STM32-HX711驱动(基于uCOSii)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_35675731/article/details/90168832

开始之前

昨天接触到一块新的传感器—HX711。把玩了一下,最后在网上随便找了个驱动改了下,做了个简易电子秤,这里分享一下。

上代码

  • 我使用的是正点原子家的mini版,所以有需要的小伙伴自己改一下芯片管脚就好了。

  • 看代码

  • hx711.h

    #ifndef _HX711_H_
    #define _HX711_H_
    #include "sys.h"
    
    void Init_Hx711(void);                       //初始化
    uint32_t Hx_Read(void);						 //读取值
    int32_t Get_Weight(void);					 //取重量
    void Get_Maopi(void);						 //去皮
    void numtostr(int16_t num, uint8_t str[]);   //数字-字符串转换
    
    #endif
    
  • hx711.c

    #include "delay.h"
    #include "hx711.h"
    
    int32_t HX711_Buffer = 0;  //HX711读取的数据值
    int32_t Weight_Maopi;      //全局变量,初始读取的重量,即毛皮
    int32_t Weight_Shiwu = 0;  //实际物品重量
    //uint8_t numto3str[4];      //三位小数转换成字符串存放数组
    
    #define GapValue 430	   //数值转换参数
    #define HIGH 1
    #define LOW  0
    #define HX711_GROUP GPIOC
    
    /**
    * @brief 置位或者复位管脚
    * @param GPIOx:GPIOA-G
    * @param pin:pin0-15
    * @param value:0(LOW) or 1(HIGH) 0为复位1为置位
    * @return none
    * @details 对指定管脚进行置位或者复位,digitalWrite(GPIOC, pin0, 1) 为置位PC0管脚
    */
    void digitalWrite(GPIO_TypeDef * GPIOx, uint16_t pin, uint16_t value)
    {
        if(value==HIGH)//set 1
        {
            GPIO_SetBits(GPIOx,pin);
        }
        if(value==LOW)//reset 0
        {
            GPIO_ResetBits(GPIOx,pin);
        }
    }
    
    
    /**
    * @brief 读取某个管脚数据
    * @param GPIOx:GPIOA-G
    * @param pin:pin0-15
    * @return 读取的数据位
    * @details 读取指定管脚的数据位,digitalRead(GPIOC, pin0)
    */
    int16_t digitalRead(GPIO_TypeDef * GPIOx,uint16_t pin)
    {
        return GPIO_ReadInputDataBit(GPIOx,pin);
    }
    
    
    /**
    * @brief 初始化HX711
    * @param None
    * @return None
    * @details 初始化HX711的DT,SCK引脚DT<----->PC0 ,SCK<----->PC13
    */
    void Init_Hx711()
    {
        GPIO_InitTypeDef GPIO_InitStructure;
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    	
    	//DT  <----->  PC0
    	//SCK <----->  PC13
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //DT设置为浮空输入
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置输出
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    }
    
    
    /**
    * @brief HX711读数据
    * @param None
    * @return HX711一次读取到的数据
    * @details val为24位数据,程序循环读取24次DT引脚电平数据,通过移位操
    *          作写入val,注意!返回的并不是实际重量,只是一个采样电平值
    */
    uint32_t Hx_Read(void)	//增益128
    {
        uint32_t val = 0;
        uint8_t i = 0;
    
    	GPIO_SetBits(GPIOC, GPIO_Pin_0); //初始状态DT引脚为高电平
    	GPIO_ResetBits(GPIOC, GPIO_Pin_13); //初始状态SCK引脚为低电平
        //判断模块是否准备好
        while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0));
        delay_us(1);
        //sck 拉低
        //GPIO_ResetBits(GPIOB,GPIO_Pin_6);
        //再次判断是否准备好
        while(!GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0));
    
        for(i=0; i<24; i++)
        {
            delay_us(100);
            GPIO_SetBits(GPIOC,GPIO_Pin_13);
            val=val<<1;
            delay_us(1);
            GPIO_ResetBits(GPIOC,GPIO_Pin_13);
            if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0))
                val++;
            delay_us(1);
        }
        GPIO_SetBits(GPIOC,GPIO_Pin_13);
        val = val^0x800000;
        delay_us(1);
        GPIO_ResetBits(GPIOC,GPIO_Pin_13);
        delay_us(1);
        return val;
    }
    
    /**
    * @brief 获取毛皮重量
    * @param None
    * @return None
    
    * @details 调用一次Hx_Read(),获取毛皮重量,并将采样值赋值给全局变量Weight_Maopi
    * @see Hx_Read();
    */
    void Get_Maopi()
    {
        Weight_Maopi = Hx_Read();
    }
    
    /**
    * @brief 获取实物重量
    * @param None
    * @return Weight_Shiwu:实物重量转换值
    
    * @details 通过再一次获取重量,减去毛皮重量,剩下的就是实物重量,再通过传感器的约定取参,
    *          即可得到实物的实际重量。
    * @see a reference to another function
    */
    int32_t Get_Weight()
    {
        HX711_Buffer = Hx_Read();
        Weight_Shiwu = HX711_Buffer;
        Weight_Shiwu = Weight_Shiwu - Weight_Maopi;				//获取实物的AD采样数值。
        Weight_Shiwu = (int32_t)((float)Weight_Shiwu/GapValue);
        return Weight_Shiwu;
    }
    
    
    /**
    * @brief 简单的三位数字转字符串
    * @param num:要转换的参数
    * @return None
    
    * @details 我们需要将x转换成00x,xx转换成0xx,xxx转换成xxx,库函数没有
    *          对应功能,所以需要自己实现
    */
    void numtostr(int16_t num, uint8_t str[])
    {
    	int8_t i=2;
        while(i >= 0)
        {
            if(num != 0)
            {
                str[i] = (uint8_t)('0'+num%10);
                num /=10;
            }
            else
            {
                str[i] = (uint8_t)'0';
            }
            --i;
        }
    	str[3] = '\0';
    }
    
    
  • main.c

    #include "led.h"
    #include "delay.h"
    #include "sys.h"
    #include "usart.h"
    #include "key.h"
    #include "lcd.h"
    #include "string.h"
    #include "hx711.h"
    #include "includes.h"
    
    
    //START 任务
    //设置任务优先级
    #define START_TASK_PRIO			10  ///开始任务的优先级为最低
    //设置任务堆栈大小
    #define START_STK_SIZE			128
    //任务任务堆栈
    OS_STK START_TASK_STK[START_STK_SIZE];
    //任务函数
    void start_task(void *pdata);
    
    
    //LED1任务 防止程序跑飞
    //设置任务优先级
    #define LED1_TASK_PRIO			6
    //设置任务堆栈大小
    #define LED1_STK_SIZE			64
    //任务堆栈
    OS_STK LED1_TASK_STK[LED1_STK_SIZE];
    //任务函数
    void led1_task(void *pdata);
    
    
    //去皮称重任务
    #define GETWEIGHT_TASK_PRIO		8
    //设置任务堆栈大小
    #define GETWEIGHT_STK_SIZE			128
    //任务堆栈
    OS_STK GETWEIGHT_TASK_STK[GETWEIGHT_STK_SIZE]; 
    //任务函数
    void getweight_task(void *pdata);
    
    
    int main(void)
    {
    	delay_init();       //延时初始化
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
    	uart_init(115200);  //串口波特率设置
    	LED_Init();  		//LED初始化
    	KEY_Init();			//按键初始化
    	LCD_Init();			//LCD初始化
    	Init_Hx711();		//HX711初始化
    	POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(30,50,200,16,16,(u8 *)"Simple Electronic Scales");
        //显示提示信息
        POINT_COLOR=BLUE;//设置字体为蓝色
    	//显示提示
        LCD_ShowString(30,110,200,16,16,(u8 *)"NOTE:");
        LCD_ShowString(30,130,200,16,16,(u8 *)"Press Key1 to Peeled");
        LCD_ShowString(30,150,200,16,16,(u8 *)"Press Key0 to get weight");
    	LCD_ShowString(30,170,200,16,16,(u8 *)"Press WK_UP to Zeroing");
    	LCD_ShowString(30,250,200,16,16,(u8 *)"Items's weight:       kg");
    	OSInit();  		//UCOS初始化
    	OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); //创建开始任务
    	OSStart(); 	//开始任务
    }
    
    //开始任务
    void start_task(void *pdata)
    {
    	OS_CPU_SR cpu_sr=0;
    	pdata=pdata;
    	OSStatInit();  //开启统计任务
    	
    	OS_ENTER_CRITICAL();  //进入临界区(关闭中断)
    	//创建LED1任务
    	OSTaskCreate(led1_task,(void*)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
    	//创建称重任务
    	OSTaskCreate(getweight_task,(void*)0,(OS_STK*)&GETWEIGHT_TASK_STK[GETWEIGHT_STK_SIZE-1],GETWEIGHT_TASK_PRIO);
    	OSTaskSuspend(START_TASK_PRIO);//挂起开始任务
    	OS_EXIT_CRITICAL();  //退出临界区(开中断)
    }
     
    
    //LED1任务,防止系统跑飞
    void led1_task(void *pdata)
    {
    	while(1)
    	{
    		LED1=0;
    		delay_ms(300);
    		LED1=1;
    		delay_ms(300);
    	}
    }
    
    
    void getweight_task(void *pdata)
    {
    	int8_t keyval;      		//扫描按键值
    	float Weight = 0;   		//HX711读取的重量
    	INT16U iweight = 0; 		//重量整数部分
    	INT16U fweight = 0; 		//重量小数部分
    	uint8_t numto3str[4] = {0}; //小数部分抓换存放数组
    	while(1)
        {
            keyval = KEY_Scan(0);   //案件扫描
    		if(keyval == WKUP_PRES)
            {
    			keyval = -1;
    			//LCD清零
    			LCD_ShowNum(150,250,00,2,16);
    			LCD_ShowString(168,250,200,16,16,(u8 *)".");
    			LCD_ShowString(176,250,200,16,16,(u8 *)"000");
            }
            if(keyval == KEY1_PRES)
            {			
    			keyval = -1;
    			POINT_COLOR=RED;//设置字体为红色
    			OSTimeDlyHMSM (0,0,1,0);
    			Get_Maopi();
    			//printf("ok\n"); //调试用
    			LCD_ShowString(30,200,200,16,16,(u8 *)"Peeled successfully");
    			LCD_ShowString(30,220,200,16,16,(u8 *)"start your weighing");
    			OSTimeDlyHMSM (0,0,2,0);
    			//第一个参数是左边X坐标,第二个参数是上边Y坐标
    			//第三个参数是右边X坐标,第四个参数是下边Y坐标
    			LCD_Fill(30,200,2000,230,WHITE); 
    			OSTimeDlyHMSM (0,0,0,100);
            }
    		if(keyval == KEY0_PRES)
            {
    			keyval = -1;
            	Weight = Get_Weight();
    			Weight = (float)Weight/1000.0f;
    			iweight = (INT16U)Weight;
    			fweight = (Weight-iweight)*1000;
    			//iweight = 22; //调试用
    			//fweight = 40; //调试用
    			numtostr(fweight, numto3str); //把数字转换成带0字符串
    			//显示重量
    			LCD_ShowNum(150,250,iweight,2,16);
    			LCD_ShowString(168,250,200,16,16,(u8 *)".");
    			LCD_ShowString(176,250,200,16,16,(u8 *)numto3str);
    			//调试用
    			//printf("%0.3fkg  %dkg %skg\n",Weight, fweight, (u8 *)numto3str);
    			//变量清零
    			Weight = 0;
    			iweight = 0;
    			fweight = 0;
    			OSTimeDlyHMSM (0,0,1,0);
            }
        }
    }
    

效果图

  • 启动界面
    启动界面
  • 去皮界面
    去皮界面
  • 称重界面
    称重显示
  • 清零界面
    清零

工程文件

猜你喜欢

转载自blog.csdn.net/qq_35675731/article/details/90168832