具体看附件了,注释写的很细。
有个小BUG,重新上电LCD只开背光无显示。对调试无大影响,不影响称重部分。估计是由于delay头文件的问题,不建议折腾。
STM32单片机源程序如下:
- //传感器用的是8Kg 2.0mV/V的如果其它规格,更改转换公式即可。
- //检测参数通过串口发送的电脑。
- //可以做程序在电脑上直接显示。
- //串口选用USART1
- //PB11接HX711数据口浮空输入
- //PB12接HX711CLK
- //PA11为测试程序时用过的。可删除
- //HX711输入电子称电压调称为22K 10K 调压为4V输出
- //输出结果最后一位为0.1g
- //我们的传感器50kg,灵敏度1mv/v
- //HX711模块R1=20k欧,R2=8.2k欧,所以HX711给传感器供电电压为(20+8.2)/8.2*1.25=4.3V,注意万用表测得会比这个值低,模块为了降低功耗只在采样时会用到4.3输出电压
- /*Include---------------------------*/
- #include //包含所有的头文件
- #include
- #include "sys.h"
- #include "usart.h"
- #include "lcd.h"
- //#include "adc.h"
- //#include "led.h"
- //#include "delay.h"
- //----------------函数声明--------------------
- void Delay_MS(u16 dly);
- void delay_us(u16 dly1);
- void RCC_Configuration(void);
- void GPIO_Configuration(void);
- unsigned long Read_HX711(void);
- void USART_Configuration(void);
- int fputc(int ch,FILE *f);
- int GetKey (void);
- long double filter(void);
- USART_InitTypeDef USART_InitStructure;
- ErrorStatus HSEStartUpStatus;
- //void u32tostr(unsigned long dat,char *str) ;
- /*******************************************************************************
- * Function Name : main
- * Description : Main program.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- int main(void)
- {
- u32 adcx;
- float weight;
- #ifdef DEBUG
- debug();
- #endif //执行主函数之前的调试函数,不影响最终的release版
- //------------初始化------------下面三个初始化
- delay_init();
- LCD_Init();
- RCC_Configuration();//RCC指时钟控制预分频器
- GPIO_Configuration();//初始化GPIO口状态
- USART_Configuration( ); //初始化串口配置
- //uart_init(9600); //串口初始化为9600
- POINT_COLOR=RED;//设置字体为红色
- LCD_ShowString(60,50,200,16,16,"Mini STM32");
- LCD_ShowString(60,70,200,16,16,"WEIGHT SCALE");
- LCD_ShowString(60,90,200,16,16,"ZHILV@EIGER");
- LCD_ShowString(60,110,200,16,16,"2017/11/25");
- POINT_COLOR=BLUE;//设置字体为蓝色
- LCD_ShowString(60,130,200,16,16,"ADC_CH1_VAL:");
- LCD_ShowString(60,150,200,16,16,"ADC_CH1_WEI:000.000kg");
- while(1) //恒运行下面的程序
- {
- Delay_MS(1000);//延时1s,可能是为了等读数稳定(这个延时是为了稳定,也可以留时间滤波)
- adcx=filter();//adcx值由这个子函数读出,这个数需要由下面两句转kg值
- adcx=8388608-adcx;
- LCD_ShowxNum(156,130,adcx,8,16,0);//显示ADC转换后的24位二进制数转十进制数值
- adcx=adcx/100;//为节省运算量,将AD值固定缩小100倍
- weight=(float)adcx/429.496+0.005; //实际用的时候需要调试,429.496由于传感器差异这个系数一般在400到500之间,加0.005是为了四舍五入
- adcx=weight;
- LCD_ShowxNum(156,150,adcx,3,16,0);//显示重量值整数部分
- weight-=adcx;
- weight*=1000;
- LCD_ShowxNum(188,150,weight,3,16,0X80);//显示重量值小数部分
- //GPIO_SetBits(GPIOA,GPIO_Pin_11); //没看懂,大概是对PA11进行设置,但不清楚作什么设置 从后面推敲应该set置1,reset置0
- //printf("%dn",weight); //打印weight值,串口调试用的
- }
- }
- /*******************************************************************************
- * Function Name : Delay_Ms
- * Description : delay 1 ms.
- * Input : dly (ms)
- * Output : None
- * Return : None
- *******************************************************************************/
- void Delay_MS(u16 dly)
- {
- u16 i,j;
- for(i=0;i for(j=1000;j>0;j--);
- }
- void delay_us(u16 dly1) //重复定义!!!!问题已解决,在delay.c中注释掉该定义
- {
- u16 i;
- for(i=dly1;i>0;i--); //这个延时函数的作用是延时dly1个微秒,但这个延时器用来干嘛不清楚
- }
- /*******************************************************************************
- * Function Name : Read_HX711
- * Description : Read weigh
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- unsigned long Read_HX711(void) //读HX711芯片输出的数据。
- {
- unsigned long val = 0; //long型32位
- unsigned char i = 0;
- //DOUT指串行数据输出,SCK指的是PD_SCK串行时钟输入
- GPIO_SetBits(GPIOB,GPIO_Pin_11); //DOUT=1 ,PB11接HX711数据口浮空输入,还是不懂什么叫浮空输入,但是连线的话把HX711的数据线口接STM的PB11口
- GPIO_ResetBits(GPIOB,GPIO_Pin_12); //SCK=0 ,PB12接HX711CLK
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)); //等待DOUT=0
- delay_us(1); //等1us执行下面
- for(i=0;i<24;i++)
- {
- GPIO_SetBits(GPIOB,GPIO_Pin_12); //SCK=1
- val=val<<1; //左移1位,右补0
- delay_us(1);
- GPIO_ResetBits(GPIOB,GPIO_Pin_12); //SCK=0
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)) //DOUT=1
- val++;
- delay_us(1);
- }
- GPIO_SetBits(GPIOB,GPIO_Pin_12);
- val=val^0x800000;//异或。
- delay_us(1);
- GPIO_ResetBits(GPIOB,GPIO_Pin_12);
- delay_us(1);
- return val;
- }
- /*******************************************************************************
- * Function Name : FILTER
- * Description : 限幅中位均值滤波
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- //下面这个滤波函数是一个去最大最小后取平均的函数,要使用它,需要将前面的延时1us改为5us,增大采样时间。
- long double filter(void) //?????ù?????¨·¨????????
- {
- unsigned long max=0,min=0,SUM,BUF[12],Average;
- int i=0;
- for(i=0;i<12;i++)
- {
- BUF=Read_HX711();
- //printf("%ldrn",BUF);
- if(i==0)
- {
- max=BUF[0];
- min=BUF[0];
- }
- if(i>0)
- {
- if(BUF>max) max=BUF;
- if(BUF;
- }
- }
- for(i=0;i<12;i++)
- {
- if(!(BUF==max||BUF==min))
- {
- SUM=SUM+BUF;
- }
- }
- Average=SUM/(12-2);
- return Average;
- }
- /*******************************************************************************
- * Function Name : RCC_Configuration
- * Description : Configures the different system clocks.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void RCC_Configuration(void)
- {
- //----------使用外部RC晶振-----------
- RCC_DeInit(); //初始化为缺省值
- RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟
- while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪
- FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
- FLASH_SetLatency(FLASH_Latency_2);
- RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK
- RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK
- RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ
- RCC_PLLCmd(ENABLE); //Enable PLLCLK
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock
- while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source
- //---------打开相应外设时钟--------------------
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); //使能APB2外设的GPIOA的时钟
- //开启串口时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- }
- /*******************************************************************************
- * Function Name : GPIO_Configuration
- * Description : 初始化GPIO外设
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void GPIO_Configuration(void)
- {
- //CLK:PB5 CLR:PE11 Data:PE10
- GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //选择PC.10(TXD) 和 PC.11
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //输出模式为推挽输出
- GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB5
- //配置USART1_Tx为复合推挽输出
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //配置 USART1_Rx 为浮空输入
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //选择PC.10(TXD) 和 PC.11
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
- GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB5
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB5
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //选择PC.10(TXD) 和 PC.11
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PB5
- }
- /*******************************************************************************
- * Function Name : USART_Configuration
- * Description : 设置串口USART1
- * Input : ch,*f
- * Output : None
- * Return : None
- *******************************************************************************/
- void USART_Configuration(void)
- {
- //串口配置: 波特率 115200 数据位 8 停止位 1 奇偶位 NONE
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No ;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- //初始化串口
- USART_Init(USART1, &USART_InitStructure);
- //启动串口
- USART_Cmd(USART1, ENABLE);
- }
- /*******************************************************************************
- * Function Name : fputc
- * Description : 重定向这个C库(stdio)printf函数 文件流——》串口USART1
- * Input : ch,*f
- * Output : None
- * Return : None
- *******************************************************************************/
- int fputc(int ch, FILE *f) //fputc重复定义!!!!已解决
- {
- USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等
- while (!(USART1->SR & USART_FLAG_TXE)); //->指针,传递值的一种方式;!逻辑非;&逻辑与
- return (ch);
- }
- // 接收数据
- int GetKey (void) {
- while (!(USART1->SR & USART_FLAG_RXNE));
- return ((int)(USART1->DR & 0x1FF));
- }
所有资料51hei提供下载:
传感器称重及LCD显.rar
|