https://www.bilibili.com/video/BV1EV411S74t?p=15&spm_id_from=pageDriver

硬件设计

硬件设计思路

image.png
image.png
image.png

称重传感器原理

image.png
E+和 E-之间接上一个激励电压比如 3.7V。
当有重物压在受力端时, S+和 S-之间会产生一个电压, 这个电压会随着重物的增加而变大, 而且是一个线性的对应关系。比如 1 克对应的电压是 1mV, 10 克对应的电压是 10mV, 由此, 我们就可以计算出, 100mV 对应的就是 100克。 我们就是通过检测这个电压来计算物体的重量的
image.png
通过已知重量的物体进行标定,算出重量和压差的对应关系式。根据关系式,当我们测得压差时,可以算出此时的重量。(通过检测传感器的电压, 就可以计算出重量)

差分ADC模块介绍

家用厨房电子秤 - 图6
家用厨房电子秤 - 图7
CS1237 差分ADC模块
《24位差分ADC模块-CS1237》资料下载 https://www.jixin.pro/bbs/topic/3555
特别注意一下它能够承受的共模电压大小, CS1237 可以承受最大共模电压是芯片的
电源电压。

模块原理图
image.png
芯片的外围电路特别简单,需要注意在 VCC 和 GND 之间要并联连两个电容 C4 和 C5。
电阻 R3 和电容 C2 构成了一个 RC 滤波器作用在模拟输入的负通道,电阻 R4 和电容 C6 构成了另一个 RC 滤波器作用在模拟输入的正通道,目的是过滤信号上夹杂的杂波。

当不使用寄存器对CS1237进行设置的情况下,芯片的参考输入、输出电压(REFIN、REFOUT)等于VDD,如VDD外接5V,则REFIN、REFOUT=5V,可以用来给称重传感器供电。
image.png

程序设计思路

必须要校准,测量两个点的重量和对应电压,求出斜率。
全局变量 称重系数K
EEROM值 关键值放在ROM中,防止掉电丢失 计算斜率K所需要的两点的ADC值

校准程序

image.png
由于秤盘的自重,导致V—W曲线不过零点,确定曲线的斜率K

  • 刚上电时,什么东西也没有,重量为0,读取此时的ADC值(0,ADC_0),作为一点

image.png

  • 利用K2键作为状态判断,放置一个已知重量的砝码(如1Kg砝码),再采集此时ADC的值(1kg,ADC_1),作为第二点

image.png

  • 通过两点,计算出此时的斜率K。从而可以只知道ADC电压值,反推出此时重量。

image.png

两次校准程序

在不需要重新下载程序的情况下,进行两次校准,实现对称重系数K的更改
利用K1键作为状态判断
image.png

重量显示程序

image.png
image.png
利用work_Count来累计时间,达到150ms定时的效果。
每150ms,显示电池电压、当前重量

重量计算程序

image.png
image.png
dat2=dat,浮点型数据赋值给整型数据,小数点以后会丢失,但其数据处理过程中提前放大,在计算斜率的时候就放大了1000倍,此时数据丢失可以接受

dat2不直接除以1000,因为这样处理不能对结果四舍五入。先除以100,再对其进行四舍五入处理,在一定程度上提高精度和简化传递数据量
比如,2600(2.6g)2600/100=26 26%10=6>5 则(26/10)+1=3g
2300(2.3g) 2300/100=23 23%10=3<5 23/10=2g

去皮程序

将当前秤盘上的重量重新归零,方便计算新放置东西的重量
image.png
image.png

低功耗模式程序介绍

image.png
通过判读上一次重量Weight_2和这一次重量Weight_1是否相同,相同则开始累计时间Low_Power,时间达到规定时长进入低功耗模式
进入低功耗模式前使能INT2中断,当按下按键K3,外部中断被使能,单片机重新上电(IAP_CONTR = 0x20;)
image.png
K3键即是低功耗模式的唤醒功能,又是去皮功能,唤醒时不要在秤盘上放置物体,以免更改去皮值。

数据的一阶滤波处理

让ADC数据稳定下来,方便显示和处理
image.png

  1. //数字一阶滤波器 滤波系数A,小于1。上一次数值B,本次数值C out = b*A + C*(1-A)
  2. //下面这个程序负责读取出最终ADC数据
  3. long Read_18Bit_AD(void)
  4. {
  5. float out,c;
  6. out = AD_Res_Last; //把ADC上一次数据放到out中
  7. c = Read_CS1237(); ////把ADC当前数据放到c中
  8. if(c!=0) // 读到正确数据
  9. {
  10. out = out*Lv_Bo + c*(1-Lv_Bo);
  11. //Lv_Bo 滤波系数A,小于1 0.1 0.001 0.005
  12. //#define Lv_Bo 0.00001
  13. AD_Res_Last = out;//把这次的计算结果放到全局变量里面保护
  14. }
  15. return AD_Res_Last;
  16. }

image.png
经过一阶滤波后,得出的数据介于上一次和这一次数据之间。随着时间推移,越来越靠近真实值。

测量电池电压程序

image.png测量电池电压,累计测量50次后平均,再将平均值忽略后两位取整
image.png

  1. //定义了一个共用体,用于传送ADC数据使用
  2. union
  3. {
  4. unsigned char a[2];
  5. unsigned int Result;
  6. } ADC;

定义了一个共用体,a[2]和Result相同,给它赋值就是另一个也变化
image.png
image.png

单片机程序下载

冷启动

image.png
左下角RESET按键为常闭开关,控制单片机的VCC。
下载程序时,按下RESET键,再松开,单片机掉电再重新上电,程序被下载进去

特殊命令寄存器

image.png
SWBS、SWRST
给单片机发送0X60,单片机自动复位并从ISP监控程序区启动
image.png
在串口中断程序中设置,给串口发送0XFA,便将IAP_CONTR=0X60,开始复位下载程序
image.png

整套工作流程

image.png