带详细注释的51单片机CS1237电子秤源程序

发布者:美好回忆最新更新时间:2019-11-18 来源: 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单片机中断系统详解(定时器、计数器)

推荐阅读最新更新时间:2024-11-07 00:19

从零开始51单片机教程 —— 25 动态扫描显示接口电路及程序
动态扫描显示接口电路及程序 在单片机系统中动态扫描显示接口是单片机中应用最为广泛的一种显示方式之一。其接口电路是把所有显示器的8个笔划段a-h同名端连在一起,而每一个显示器的公共极COM是各自独立地受I/O线控制。CPU向字段输出口送出字形码时,所有显示器接收到相同的字形码,但究竟是那个显示器亮,则取决于COM端,而这一端是由I/O控制的,所以我们就能自行决定何时显示哪一位了。而所谓动态扫描就是指我们采用分时的办法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。 在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,
[单片机]
从零开始<font color='red'>51单片机</font>教程 —— 25 动态扫描显示接口电路及程序
51单片机C51精确延时
如下程序能实现ms级的比较精确的延时: void Delayms(unsigned int n) { unsigned int i,j; for(j=n;j 0;j--) for(i=112;i 0;i--); } 用keil可以看出这个延时的时间,我们先延时1ms(Delayms(1))。 进入Delayms前,sec=0.00042209s 延时后,sec=0.00142253s 可以知道Delayms(1)实际延时0.00142253s 0.00042209s=0.00100044s 1ms 同样如果想延时15ms的话,用Delayms(15),实际延时0.01480903s 15ms
[单片机]
<font color='red'>51单片机</font>C51精确延时
AT89S51单片机的硬件组成
AT89S51单片机的片内硬件组成结构如图2-1所示。它把那些作为控制应用所必需的基本功能部件都集成在一个尺寸有限的集成电路芯片上,具有如下功能部件和特性:      (1)8位微处理器(CPU)。      (2)数据存储器(128B RAM)。      (3)程序存储器(4KB FLASH ROM)。      (4)4个8位可编程并行I/O口(PO口、Pl口、P2口和P3口)。      (5)1个全双工的异步串行口。      (6)2个可编程的16位定时器/计数器。      (7)1个看门狗定时器。      (8)中断系统具有5个中断源、5个中断向量。      (9)特殊功能寄存器(SFR) 26个。  
[单片机]
AT89S<font color='red'>51单片机</font>的硬件组成
基于51单片机的多路呼叫系统设计
随着信息技术的发展与医疗卫生事业的深化改革,国家金卫工程的实施使医院管理信息化的进程大大加快,越来约多的医院认识到,只有通过信息化建设,逐步建立信息化医院和医疗企业,才能支持医院的可持续发展,从而大力提高医院综合效益和运行效益。因此,设计一个支持医院病床呼叫,具有一条线缆传输多路呼叫信息的功能的系统,是非常必要的。 1 多路呼叫系统整体设计方案 该系统利用单片机的双机通信功能,设计出的具有呼叫、显示、应答等功能的多路呼叫系统,就是为满足中小型医院中,医护人员与病人之间能及时准确地进行半双工通信,达到既方便病人又方便医护人员,更利于提高医院护理水平的目的而设计的。该系统适用于新老病房及门诊,且能随时扩充床位及迁移。针对目前整体化护理
[单片机]
基于<font color='red'>51单片机</font>的多路呼叫系统设计
51单片机C语言学习 2
第二课 初步认识51芯片   上一课我们的第一个项目完成了,可能有懂C语言的朋友会说, 这和PC机上的C语言没有多大的区别呀 。的确没有太大的区别,C语言只是一种程序语言的统称,针对不同的处理器相关的C语言都会有一些细节的改变。编写PC机的C程序时,如要对硬件编程你就必须对硬件要有一定的认识,51单片机编程就更是如此,因它的开发应用是不可与硬件脱节的,所以我们先要来初步认识一下51苾片的结构和引脚功能。MSC51架构的芯片种类很多,具体特点和功能不尽相同(在以后编写的附录中会加入常用的一些51芯片的资料列表),在此后的教程中就以Atmel公司的AT89C51和AT89C2051为中心对象来进行学习
[单片机]
基于51单片机的IEEE-488接口设计
1 概 述   智能仪器程控接口电路的设计,首先是根据仪器的功能确定该仪器的接口功能。文中所涉及的仪器是以MCS-51系列单片机作为内部控制器的高速数据采集装置,由于A/D转换器既要向计算机输送采集结果,又要接受计算机对其工作条件的控制,因此,在程控接口电路设计时,设置了六种接口功能:源挂钩功能(选用SH1功能子集)、受者挂钩功能(选用AH1功能子集)、讲功能(选用T5功能子集)、听功能(选用L4功能子集)、远地/本地功能(选用RL功能子集)和器件触发功能(选用DT1功能子集)。 600)this.style.width='600px';" border=0> 2 接 口 功 能 (IF) 设 计   如
[单片机]
基于<font color='red'>51单片机</font>的IEEE-488接口设计
51单片机P2口介绍
P2.0 P2.7为P2口的8位双向口线,第一功能为基本输入/输出;第二功能是在系统扩展时作为高8位地址总线使用。 P2口内部结构及其功能描述 如图是P2口内部1位的电路结构。注意与P0结构的不同之处。 P2端口是一个准双向端口; 第一功能: 当P2端口作为通用I/O使用时,单片机控制二选一复用器倒向P2.x锁存器的Q端,此时P2端口的功能和使用方法都类似于P1端口;系统复位时,端口锁存器自动置1,输出的下拉驱动器截止,P2端口可直接作为输入口使用。 第二功能: P2端口在系统扩展外围总线时输出高8位地址,此时P2不可作为通用I/O端口使用; P2端口输出高8位地址时,硬
[单片机]
基于89C51单片机的编码译码显示实验电路设计
摘 要:当前手工拨盘方式编码译码显示实验电路存在输入信号不稳定、控制性较差等缺点, 为了克服上述缺点, 电路设计采用89C51 单片机为核心器件作为编码信号发生器和自动控制系统。通过Pro teus 平台仿真和实验调试, 电路能产生高质量输入信号和实现自动控制, 较好地解决了手工拨盘方式编码译码显示实验电路存在的缺陷。 0 引 言 在日常数字逻辑电路实验中编码译码显示实验电路是编码、译码、显示三个电路的综合运用, 在数字逻辑实验电路中具有重要的地位, 在实验的过程中, 时常会出现显示结果的抖动, 经研究出现这种现象主要原因是:编码电路的编码信号输入采用手工拨盘方式, 产生的编码输入信号往往不稳定; 另外, 电路控制性能较差,不能达
[单片机]
基于89C<font color='red'>51单片机</font>的编码译码显示实验电路设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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