历史上的今天
返回首页

历史上的今天

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

正在发生

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

2019-11-18 来源:51hei

工程硬件平台:    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();//每一次称重,都要更新一下用于低功耗的数据

推荐阅读

史海拾趣

永丰盈(CST)公司的发展小趣事

作为一家有社会责任感的企业,CST始终关注环境保护和社会公益事业。公司严格执行环保法规,积极推广绿色生产理念,努力减少生产过程中的污染排放。此外,CST还积极参与社会公益活动,为当地的教育、文化等事业做出了积极贡献。这些举措进一步提升了CST的企业形象和社会声誉。

Degson Electronics Co Ltd公司的发展小趣事

Degson Electronics Co., Ltd.成立于1990年,当时主要专注于电子连接器的研发和生产。在初创阶段,公司面临了诸多挑战,包括资金短缺、市场竞争激烈以及技术壁垒等。然而,Degson凭借其创始团队对电子行业的深入理解和坚定信念,成功研发出了一系列高质量、性能稳定的电子连接器产品,并逐渐在市场上赢得了客户的认可。

EVER-WAY公司的发展小趣事

随着公司规模的扩大和产品质量的提升,EVER-WAY公司开始积极拓展国内外市场。公司制定了详细的市场拓展计划,通过参加国际展会、开展国际贸易合作等方式,逐步打开了国际市场的大门。同时,公司还加强了与国内客户的合作,通过提供定制化服务、优化供应链管理等方式,赢得了客户的信任和支持。这些市场拓展的跨越不仅为公司带来了更多的商业机会,也进一步提升了公司的品牌价值和市场地位。

Harris公司的发展小趣事

进入21世纪后,Hammond进行了内部重组,将变压器事业部分拆为独立的Hammond Power Solutions, Inc.(HPSI)。这一举措使得两家公司能够更加专注于各自的核心业务,实现更加高效和专业化的发展。Hammond Manufacturing则继续专注于电气和电子外壳、机架、机柜以及电子变压器的生产,而HPSI则专注于定制和分类变压器的制造。这种专业化的分工不仅增强了各自的市场竞争力,还为客户提供了更加全面和专业的服务。

通过这些故事,我们可以看到Hammond公司在电子行业中的发展历程充满了挑战与机遇。从初创时期的艰难起步,到成为行业先驱和全球领先企业,Hammond始终保持着对市场的敏锐洞察和持续创新的精神。

Anaren Ceramics公司的发展小趣事

Anaren Ceramics公司在电子行业中崭露头角,首先得益于其在陶瓷材料技术方面的重大突破。公司研发了一种新型的陶瓷材料,具有优异的绝缘性能和高温稳定性,这为当时的电子行业提供了前所未有的解决方案。随着这种新型陶瓷材料在市场上的广泛应用,Anaren Ceramics公司的知名度逐渐提升,逐渐成为了行业内的佼佼者。

ALD [Advanced Linear Devices]公司的发展小趣事

Anaren Ceramics公司深知技术创新是企业发展的核心动力,因此一直致力于打造一支强大的研发团队。公司投入大量资金用于研发人才的引进和培养,同时积极与高校和科研机构建立合作关系,共同开展技术研发项目。这些举措使得公司的研发团队不断壮大,为公司的发展提供了源源不断的创新动力。

问答坊 | AI 解惑

ADSL宽带接入技术在韩国通信的应用1

一、概况 韩国通信开展ADSL业务的主要原因是由于激烈的市场竞争。由于电信业务完全放开,除韩国通信之外,还有不少宽带业务提供商也在提供电信业务。当韩国通信还在推广ISDN业务时,一些CATV公司已利用CableModem占去了不少宽带Internet接入市场。 ...…

查看全部问答>

DVD扫盲知识

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 来论坛这么久,一直是下载一些东西,感谢所有分享好东西的兄弟姐妹们! 今天我也发一点DVD扫盲知识来给大家分享一下,看完了这个绝对能让你对DVD有一个比较全面的了解,扫盲用的!呵呵 另外 ...…

查看全部问答>

如何关闭窗口

我用WINCE开发了一个MFC窗口函数,在关闭窗口时程序还在执行,如果想退出的程序的话,要重载哪个函数? 谢谢。。。…

查看全部问答>

PCI总线原理及编程指南

PCI总线原理及编程指南: 最近想研究一下PCI插槽上的控制器是如何工作的,谁那有详细的说明? 该从哪些方面找,有这方面的代码吗?谁有?给一份,谢谢了。…

查看全部问答>

MFC requires WINVER to be #defined to 0x0400 or greater

项目建立的时候是wm5.0,后来选择别的模拟器,编译的时候出现“MFC requires WINVER to be #defined to 0x0400 or greater”,应该如何解决?…

查看全部问答>

猎头职位——条码手持终端开发工程师

条码手持终端开发工程师 1.        2名,大专以上学历; 2.        了解制造业物流业务和条码/RFID技术,有仓库和生产线条码/RFID手持终端开发经验。 3.        熟悉C#语言编程 ...…

查看全部问答>

led冷光源与热光源的区别

热光源:利用热能激发的光源,如白炽灯在3,000-4,000K温度时热辐射发光。白炽灯有80-90%的能量转换能热能,10%左右的能量转换为光能。因此发光效率较低。我们不是根据灯具外壳的温度来定义为冷光源,还是热光源。灯具週边的温度高低,只能评判 ...…

查看全部问答>

高精度数控恒流源

各位大侠,目前手头有个设计任务,征集个方案主要情况是这个样子:板卡由BGA核心板(现有模块)+DA模拟输出部分+恒流源运放电路+AD采集模块几部分主要技术难点就在于高精度正负恒流源的设计和实现,技术要求如下: 1提供八路独立正负恒流源恒流源量 ...…

查看全部问答>

linux中inittab文件详解

转贴自:http://www.2cto.com/os/201108/98426.html   init的进程号是1(ps -aux | less),从这一点就能看出,init进程是系统所有进程的起点,Linux在完成核内引导以后,就开始运行init程序。 init程序需要读取配置文件/etc/ini ...…

查看全部问答>

这可怎么办

有两个电源16V和12V,平时使用12V,当12V被去掉后,要求PCB上实现能够自动切换到16V;这个怎么办?还请高手赐教。…

查看全部问答>