历史上的今天

今天是:2024年11月18日(星期一)

2019年11月18日 | 带详细注释的51单片机CS1237电子秤源程序

发布者:美好回忆 来源: 51hei关键字:51单片机  CS1237  电子秤 手机看文章 扫描二维码
随时随地手机看文章

工程硬件平台:    1,51Core-V1.0(51单片机最小系统板)
                2,差分ADC模块-CS1237
                3,称重传感器模块
                4,OLED显示器0.96寸,4PIN

工程程序版本:51单片机厨房(药房)秤方案 V1.0.0.0
(本例程仅提供一种实现思路,学会后完全可以使用其他品牌的单片机替代)
---------------------------------------------------
------------------------------------------------------------------------------------------------------.

硬件:

1,单片机内部时钟设置为 5.5296MHZ

2,“差分ADC模块-CS1237”的电源正确连接到“51单片机最小系统板“的5V电源上。同时数字接口如下连接:
    OUT = P3^7;//数据对应IO口
    CLK = P3^5;//时钟对应IO口

3,”称重传感器模块“和”差分ADC模块-CS1237“连接好。接线定义如下:
    CS1237模块的E+ 连接 红色
    CS1237模块的E- 连接 黑色
    CS1237模块的S+ 连接 绿色
    CS1237模块的S- 连接 白色
(本例程的软件上有处理,S+和S-不用区别正负极,因为CS1237的模拟输入通道是差分输入)

4,OLED显示器0.96寸4PIN ,直接查到51最小系统板的P17排母上即可

5,锂电池供电下的运行功耗:19mA    待机功耗:<2mA

------------------------------------------------------------------------------------------------------



---------------------------------------------------

程序功能:
1,第一个点校准功能。需要保证系统供电是一个精确的5V,第一次烧写完程序后会进行第一个点的自动校准。
    此功能也可以通过按 KEY1 按键随时进入。
    第一个点校准后,不能直接称重,还需要第二个点校准。
    
2,第二个点的校准功能。需要在秤盘上放一个500克的砝码,等待几秒,按下 KEY2 按键即可。

3,去皮功能。经过两个点的校准后便可以正常使用。使用过程中随时可以去皮重。按下 KEY3 按键即可。

4,电池供电使用。接上一节普通锂电池即可使用(也可以是两节或三节普通干电池串联),接到5V供电的位置即可。
    OLED显示屏会显示电池的电压,单位是mV。
    
5,程序正常执行显示的是实时重量。

6,当程序检测到超过30S重量没有变化,则自动进入低功耗模式,关闭OLED以达到省电的目的。若想再次使用必须按下 KEY3 按键。
    (此时的KEY3按键相当于产品上面的“开机”按键。当然你也可以做一个电源开关,直接关闭系统)

7,开机去皮。由于每次开机时候,传感器受力情况会发生微妙变化(比如移动位置,秤盘被压过,底座没放平等),所以程序在每次开机时
    会进行去皮,软件上消除此误差。

8,按键KEY1和KEY2只在校准时候使用,若厂家做产品,只需要在出场时候校准使用即可。留给用户的接口只有KEY3按键,兼容去皮和开机唤醒。

---------------------------------------------------
单片机源程序如下:


//内部时钟 5.5296MHZ

//电池供电可用,实时显示重量,单位g

//KEY1 校准时第一步空称 ;  KEY2 砝码校准500G砝码 ;KEY3 常规去皮功能

#include "STC15W.h"

#include "intrins.h"

#include "Uart_1.h"

#include "OLED_IIC.h"

#include "CS1237.h"

#include "T4_Key.h"

#include "ADC.h"

#include "IAP_EEPROM.h"



#define  Tare         EEROM_20Long[0]  //校准用,皮重

#define  BGA_EEPROM   EEROM_20Long[1]  //在5V供电下,校准的内部BGA参数

#define  First_ON     EEROM_20Long[2]  //第一次开机标志位 如果不是88则表示第一次开机,用于批量生产

#define  Weight_500g  EEROM_20Long[3]  //500G标定时候的ADC数值



extern bit Key_1,Key_2,Key_3;//三个按键的状态,全局变量 1表示按下 ,每次用过之后需要手动置零

extern unsigned int Battery_Now;//计算出来的当前电池电压

long EEROM_20Long[20];//用于掉电保存的数值,每次烧写过后可能会归零

unsigned char Work_Count=0;//放在定时器里面,每50ms进行一次显示,称重。

unsigned int Low_Power = 0;//放到定时器里面,进行关机检测,30S重量没有变化后进入低功耗模式

static float Weight_Coe=0.00000;//全局变量,称重时参考的重量系数

static float Tare_Coe=0.00000;//全局变量,皮重的重量,放大1000倍之后的数值

static unsigned int Weight_30S_1,Weight_30S_2;//30S读取一次重量,然后比较,如果两次相同则进入低功耗

static unsigned char Power_Down_F=0;//单片机掉电标志位,用于掉电重启后初始化所有设备


//获取电池电压,50次平均值

unsigned int Get_Bat(void);

//读取CS1237,去皮后的重量,精确到g

unsigned int  Get_Weight(void);

//根据校准的数值,计算出称重系数

void Get_Weight_Coe(void);


void main(void)

{

        unsigned int Main_Loop=0;//在主函数里面用的,循环时候控制循环次数的变量

        

        P0M1=0;P0M0=0;P1M1=0;P1M0=0;

        P2M1=0;P2M0=0;P3M1=0;P3M0=0;

        P4M1=0;P4M0=0;P5M1=0;P5M0=0;//上电初始化所有IO口为普通IO

        Init_Uart1();//初始化串口1,9600bps

        OLED_Init();  //OLED初始化

        Init_T4();//初始化T4,用于按键检测

        Init_CS1237();//初始化CS1237

        Init_ADC();//初始化ADC

        EA = 1;//打开单片机全局中断

        Re_20_Long(0XD3B8,EEROM_20Long);//读取所有的掉电保存数据到内存里

        Delay1ms(10);

        if(First_ON != 88)//如果检测到第一次开机情况,表示需要校准,用于批量生产时候

        {

                LED2 = 0;//灯亮

                First_ON = 88;

                Main_Loop = 10;

                while(Main_Loop--)

                        Tare = Read_18Bit_AD();//读取出CS1237的数据,5V情况下

                Main_Loop = 10;

                while(Main_Loop--)

                        BGA_EEPROM = Get_BGA();//在5V供电情况下,保存BGA参数

                Wr_20_Long(0XD3B8,EEROM_20Long);//保存数据到EEPROM

                LED2 = 1;//灯灭

        }

        else

                Get_Weight_Coe();//依据EEPROM内容,计算称重系数

        Send_Data1(Read_CON());//发送CS1237配置信息到串口

        

        //---------------------------------------------------------------//

        LED2 = 0;//灯亮

        Main_Loop = 10;//开机自动读取一次当前皮重。

        while(Main_Loop--)//连续读取10次,是因为CS1237读取程序里有软件滤波器,这样做更接近真实值

                Tare_Coe = Read_18Bit_AD();//读取出皮重的ADC数据

        Tare_Coe *= Weight_Coe;

        LED2 = 1;//关灯

        //--------------------------------------------------------------//               

        while(1)

        {

                if(Key_1)//去皮后的值保存到EEPROM里面,必须在5V环境下 校准专用

                {

                        Key_1 = 0;

                        LED2 = 0;//灯亮

                        Main_Loop = 10;

                        while(Main_Loop--)

                                Tare = Read_18Bit_AD();//读取出CS1237的数据,5V情况下

                        Main_Loop = 10;

                        while(Main_Loop--)

                                BGA_EEPROM = Get_BGA();//在5V供电情况下,保存BGA参数

                        Wr_20_Long(0XD3B8,EEROM_20Long);//保存数据到EEPROM

                        LED2 = 1;//关灯

                }

                

                if(Key_2)//放上一个500g砝码,用于校准误差,必须在5V供电环境下

                {

                        Key_2 = 0;

                        LED2 = 0;//灯亮

                        Main_Loop = 10;

                        while(Main_Loop--)

                                Weight_500g = Read_18Bit_AD();//读取出500G的数据

                        Weight_Coe = Weight_500g -  Tare;//除去皮重的ADC数值

                        Weight_Coe = 500000 / Weight_Coe;//放大1000倍的斜率

                        Tare_Coe = Weight_Coe * Tare;//皮重的重量,放大1000倍之后的

                        Wr_20_Long(0XD3B8,EEROM_20Long);//保存数据到EEPROM

                        LED2 = 1;

                } 

                

                if(Key_3)//正常的去皮重,不保存到EEPROM里面

                {

                        Key_3 = 0;

                        LED2 = 0;

                        Main_Loop = 10;

                        while(Main_Loop--)

                                Tare_Coe = Read_18Bit_AD();//读取出皮重的ADC数据

                        Tare_Coe *= Weight_Coe;

                        LED2 = 1;

                }

                

                //定时器控制的子程序,每150ms调用一次

                if(Work_Count == 4)

                {

                        OLED_ShowNum(7*9,2,Get_Bat(),4,16);//显示电池电压

                        Weight_30S_1 = Get_Weight();//每一次称重,都要更新一下用于低功耗的数据

[1] [2]
关键字:51单片机  CS1237  电子秤 引用地址:带详细注释的51单片机CS1237电子秤源程序

上一篇:单片机+DHT11温湿度检测程序
下一篇:51单片机中断系统详解(定时器、计数器)

推荐阅读

2018年双十一购物狂欢节尽管已经收官,但商品的配送仍然热火朝天,为了让剁手党们尽早拿到快递,快递员真的很辛苦,“双十一派件高峰,小哥熬夜抢快递柜”,“快递员三天两夜睡了不到8小时的觉”,这一类的新闻层出不穷。 最后一公里的快递配送难题如何解决,是各大物流最大痛点。人口红利消失,人力成本飙升的当下,单纯的靠招聘快递员已经不能满足配...
一般来说,单片机的使用要从基础的汇编语言开始讲起,即使使用C语言进行开发,也必须对内部的机器码实现非常熟悉,才能应付设计和调试中可能出现的各种情况。WINAVR是个免费的AVR 开发程序集,它以著名的自由软件GCC 为C/C++编译器。之所以选用WINAVR,是因为它是一组开放源代码的程序集,也是目前最好的自由软件之一。 下面是关于WINAVR的使用要点,...
印刷电路板(PCB板)制造商在提高可靠性和降低成本的同时,也面临着增加密度、缩小占位面积、减少侧面尺寸、管理热流和提高数据速率等重大压力。随着他们不断成功地消减这些压力,一个有趣的挑战出现在设计师们的面前,即在两片PCB板之间去对齐多个已配对连接器组。 我们所需要的是清晰明确的准则,以在不牺牲系统性能、密度和可靠性的情况下,懂得如何应...
广告摘要声明广告特斯拉放弃 SAP ,25个人仅用了4个月的时间开发了整套 ERP ,这到底是特斯拉牛,还是低代码牛?首先,我们先来了解一下,什么是 SAP ?什么是 ERP ?SAP:SAP 起源于 Systems Applications and Products in Data Processing 。 SAP 既是公司名称,又是一个系统的名称,即企业管理解决方案。SAP 解决方案包括标准商业...

史海拾趣

问答坊 | AI 解惑

正弦波输入电流的开关电源

正弦波输入电流的开关电源       开关电源以其效率高,功率密度高而在电源领域中占主导地位,但传统的开关电源存在一个致命的弱点:功率因数低,一般为0.45~0.75,而且其无功分量基本上为高次谐波,其中三次谐波幅度约为 ...…

查看全部问答∨

求助:图中IC是什么型号

附图中S端接的是光敏二极管,受光的强弱而改变X1端的频率.一般的实现此攻能用NE555最实用,又容易.但此图不是用的NE555,请大侠们帮忙分析一下,此图中是什么型号的IC?非常感谢…

查看全部问答∨

有关DDS输出正弦信号功放的问题

AD9852的输出为可调的不足1V的电压,输出电流为5-20mA, 有什么办法能使电压升220V,又使正弦波不失真啊。。 高手们给些建议。。…

查看全部问答∨

谁知道有IM字节的EEPROM吗?

谁知道有IM字节的EEPROM吗?…

查看全部问答∨

zibee疑问

#define SET_MAIN_CLOCK_SOURCE(source) \\   do {                                  \\      &n ...…

查看全部问答∨

在开发FM1208CPU卡遇到的问题

我用的是FM1208芯片,问题是 1. 外部认证的密钥被锁死,报6983的错误,FM1208怎么解锁? 2. 所有指令不能被正常执行,即执行任何指令报6581的错误,怎么解决? 谢谢了!…

查看全部问答∨

关于vxworks5.5下的82541网卡使用求教

找了好长时间,还是修改已有驱动没成功,deviceid等到底是改什么,查了芯片手册没发现差别啊,求教已经修改成功的同学,折腾的头大,现在被卡住在网卡这个地方了,有谁帮一把,谢谢各位!…

查看全部问答∨

如何给M25P64写官方开发板的image?

现在用EK-STM32开发板,已经搞定320x240的液晶,但该板没有M25P64,故在程序运行的开始,会“蓝屏”,提示SPI FLASH不对头。现在已经在SPI1安装上了空白的M25P64。以前偶尔好像看过一篇文档,讲的是怎么样将官方的image写到m25p64中,但 ...…

查看全部问答∨

吉时利DriverLINX的应用寄语

KPCI-3100系列板卡都有多个数字信道。KPCI-3101/2/3/4有两个8位和一个7位(分别是信道A,B和C)。KPCI-3110/16有两个8位和一个2位(分别是信道A和B,以及动态数字输出[1])。在KPCI-3101/2/3/4中,信道C既可以作为普通的数字位操作,也可以作为动态数 ...…

查看全部问答∨

busybox 不能ctrl+c 提示can't access tty.job control

板子启动后就会自动创建ttyS0之类的节点 inittab文件内容: # /etc/inittab: init(8) configuration. # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ # The default runlevel. id:5:initdefault: # Boot-time system configuration ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved