diff --git a/Core/Inc/sts_weight_scale.h b/Core/Inc/sts_weight_scale.h new file mode 100644 index 0000000..e606992 --- /dev/null +++ b/Core/Inc/sts_weight_scale.h @@ -0,0 +1,57 @@ +/* + * sts_weight_scale.h + * + * Created on: Jun 19, 2024 + * Author: lenovo + */ + +#ifndef APPLICATION_USER_CORE_STS_WEIGHT_SCALE_H_ +#define APPLICATION_USER_CORE_STS_WEIGHT_SCALE_H_ +#include "main.h" +#include "sys_app.h" + +//#define HX711_SCK PBout(0)// PB0 +//#define HX711_DOUT PBin(1)// PB1 +//#define PBout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 +//#define PBin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 + +//#define HX711_SCK(x) HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET);(0)// PB0 +//#define HX711_DOUT(x) HAL_GPIO_ReadPin(HX711_DOUT_PORT, HX711_DOUT_PIN) + + +int sts_weight_scale(void); +void HX711_Init(void); +void Init_HX711pin(void); +uint32_t HX711_Read(void); +void Get_Maopi(void); +void Get_Weight(void); +#if 0 + +#endif + +//V1.2修改说明 +//修正了中断中调用出现死循环的错误 +//防止延时不准确,采用do while结构! + +//V1.3修改说明 +//增加了对UCOSII延时的支持. +//如果使用ucosII,delay_init会自动设置SYSTICK的值,使之与ucos的TICKS_PER_SEC对应. +//delay_ms和delay_us也进行了针对ucos的改造. +//delay_us可以在ucos下使用,而且准确度很高,更重要的是没有占用额外的定时器. +//delay_ms在ucos下,可以当成OSTimeDly来用,在未启动ucos时,它采用delay_us实现,从而准确延时 +//可以用来初始化外设,在启动了ucos之后delay_ms根据延时的长短,选择OSTimeDly实现或者delay_us实现. + +//V1.4修改说明 20110929 +//修改了使用ucos,但是ucos未启动的时候,delay_ms中中断无法响应的bug. +//V1.5修改说明 20120902 +//在delay_us加入ucos上锁,防止由于ucos打断delay_us的执行,可能导致的延时不准。 +////////////////////////////////////////////////////////////////////////////////// +void delay_init(void); +void delay_ms(uint16_t nms); +void delay_us(uint32_t nus); + + + + + +#endif /* APPLICATION_USER_CORE_STS_WEIGHT_SCALE_H_ */ diff --git a/Core/Src/sts_weight_scale.c b/Core/Src/sts_weight_scale.c new file mode 100644 index 0000000..1e67b0f --- /dev/null +++ b/Core/Src/sts_weight_scale.c @@ -0,0 +1,201 @@ +#include "sts_weight_scale.h" + +uint32_t HX711_Buffer; +uint32_t Weight_Maopi; +int32_t Weight_Shiwu; +uint8_t Flag_Error; + +int sts_weight_scale(void) +{ + //Init_HX711pin(); + + //delay_init(); + HX711_Init(); + + //NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 + //uart_init(9600); //串口初始化为9600 + + Get_Maopi(); //称毛皮重量 + + HAL_Delay(2000); + + Get_Maopi(); //重新获取毛皮重量 + + + while(1) + { + Get_Weight(); + + //printf("净重量 = %d g\r\n",Weight_Shiwu); //打印 + + APP_LOG(TS_OFF, VLEVEL_M, "Net Weight = %d g \r\n", Weight_Shiwu); + + //delay_ms(1000); + HAL_Delay(2000); + + + } +} + +/************************************************************************************ + +*************************************************************************************/ + + +uint8_t Flag_Error = 0; + +//校准参数 +//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。 +//当发现测试出来的重量偏大时,增加该数值。 +//如果测试出来的重量偏小时,减小改数值。 +//该值可以为小数 +//#define GapValue 106.5 +#define GapValue 909.5 + +void HX711_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + __HAL_RCC_GPIOA_CLK_ENABLE(); + + GPIO_InitStruct.Pin = HX711_SCK_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(HX711_SCK_PORT, &GPIO_InitStruct); + + //HX711_DOUT + GPIO_InitStruct.Pin = HX711_DOUT_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(HX711_DOUT_PORT, &GPIO_InitStruct); + + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); + + + + + +} + +//**************************************************** +//读取HX711 +//**************************************************** +uint32_t HX711_Read(void) //增益128 +{ + unsigned long count; + unsigned char i; + //HX711_DOUT=1; + HAL_GPIO_WritePin(HX711_DOUT_PORT, HX711_DOUT_PIN, GPIO_PIN_SET); + + delay_us(1); + //HX711_SCK=0; + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); + + count=0; + uint32_t dout=0; + //while(HX711_DOUT); + while(HAL_GPIO_ReadPin(HX711_DOUT_PORT, HX711_DOUT_PIN)==GPIO_PIN_SET); + + for(i=0;i<24;i++) + { + //HX711_SCK=1; + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_SET); + + count=count<<1; + delay_us(1); + + //HX711_SCK=0; + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); + + //if(HX711_DOUT) + dout = HAL_GPIO_ReadPin(HX711_DOUT_PORT, HX711_DOUT_PIN); + if (dout==GPIO_PIN_SET) + count++; + delay_us(1); + } + //HX711_SCK=1; + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_SET); + count=count^0x800000;//第25个脉冲下降沿来时,转换数据 + + delay_us(1); + + //HX711_SCK=0; + HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); + + return(count); +} + +//**************************************************** +//获取毛皮重量 +//**************************************************** +void Get_Maopi(void) +{ + Weight_Maopi = HX711_Read(); + APP_LOG(TS_OFF, VLEVEL_M, "\r\n ##### Mao Pi =%d <<<<<< \r\n",Weight_Maopi); +} + +//**************************************************** +//称重 +//**************************************************** +void Get_Weight(void) +{ + HX711_Buffer = HX711_Read(); + + if(HX711_Buffer > Weight_Maopi) + { + Weight_Shiwu = HX711_Buffer; + Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。 + + Weight_Shiwu = (int32_t)((float)Weight_Shiwu/GapValue); //计算实物的实际重量 + //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。 + //当发现测试出来的重量偏大时,增加该数值。 + + APP_LOG(TS_OFF, VLEVEL_M, "\r\n ##### Weight_Shiwu =%d <<<<<< \r\n",Weight_Shiwu);//如果测试出来的重量偏小时,减小改数值。 + } +} + + +//延时nus +//nus为要延时的us数. +static uint8_t fac_us=0;//us延时倍乘数 +static uint16_t fac_ms=0;//ms延时倍乘数 + + +void delay_us(uint32_t nus) +{ + fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 + uint32_t temp; + SysTick->LOAD=nus*fac_us; //时间加载 + SysTick->VAL=0x00; //清空计数器 + SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 + do + { + temp=SysTick->CTRL; + } + while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 //bit16置一说明时间到,跳出循环 + SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 + SysTick->VAL =0X00; //清空计数器 +} +//延时nms +//注意nms的范围 +//SysTick->LOAD为24位寄存器,所以,最大延时为: +//nms<=0xffffff*8*1000/SYSCLK +//SYSCLK单位为Hz,nms单位为ms +//对72M条件下,nms<=1864 +void delay_ms(uint16_t nms) +{ + fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 + fac_ms=(uint16_t)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数 + uint32_t temp; + SysTick->LOAD=(uint32_t)nms*fac_ms;//时间加载(SysTick->LOAD为24bit) + SysTick->VAL =0x00; //清空计数器 + SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 + do + { + temp=SysTick->CTRL; + } + while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 + SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 + SysTick->VAL =0X00; //清空计数器 +}