电子人体秤的芯片采用的是CSU18M88芯片,是一颗soc集成芯片。
CSU18M88芯片是一个8位RISC架构的高性能单片机,集成了24Bit高精度ADC和LCD显示模块。内部集成8k*16Bits的MTP程序存储器。
高性能的RISC CPU
8位单片机MCU
内置8K×16位MTP可编程存储器(烧录次数1000次)
896字节数据存储器(SRAM)
只有43条单字指令
8级存储堆栈
模拟特性
24位分辨率
内部集成的可编程增益放大器
ADC的输出速率10Hz~5KHz
内带电荷泵
内带稳压器供传感器和调制器
专用微控制器的特性
上电复位(POR)
上电复位延迟定时器(39ms)
内带低电压复位(LVR)
Timer
8位可编程预分频的8位的定时计数器
扩展型看门狗定时器(WDT)
可编程的时间范围
外设特性
37位双向I/O口
内置10位SAR ADC
4×20/6x18的LCD驱动
可选择两种不同的LCD驱动波形
可选择不同的偏置电压产生方式
2个外部中断
内置8路单端输入的10位ADC,PT1.0、PT1.1、PT2.0~PT2.3、PT2.6、PT2.7
具有RTC功能,可以显示年、月、日、星期、小时、分、秒
两路Uart
1路I2C、1路SPI
下面介绍main.c主程序编写,其他程序略。
(1) 头文件和一些宏定义
#include 《reg52.h》
#include 《intrins.h》
#include 《string.h》
#include “lcd.h”
#include “hx711.h”
#include “keyboard.h”
//定义量程系数
#define RATIO 2114/1623
(2) 管脚、常量、变量定义
//定义标识
volaTIle bit FlagTest = 0;
//定时测试标志,每0.5秒置位,测完清0
volaTIle bit FlagKeyPress = 0; //有键按下标志,处理完毕清0
volaTIle bit FlagSetPrice = 0; //价格设置状态标志,设置好为1
//管脚定义 sbit LedA = P2^2;
sbit beep = P1^0;
sbit alert = P1^1;
//显示用变量 int Counter;
uchar idata str1[6] = “000000”;
int i, iTemp; //称重用变量
unsigned long idata FullScale; //满量程AD值/1000
unsigned long AdVal; //AD采样值
unsigned long weight; //重量值,单位g
unsigned long idata price; //单价,长整型值,单位为分
unsigned long idata money; //总价,长整型值,单位为分
//键盘处理变量
uchar keycode; uchar DotPos;
//小数点标志及位置
(4) 各子程序
//整型转字符串的函数,转换范围0--65536 void int2str(int x, char* str)
{
int i=1;
int tmp=10;
while(x/tmp!=0)
{
i++;
tmp*=10;
}
tmp=x;
str[i]=‘\0’;
while(i》1)
{
str[--i]=‘0’+(tmp%10);
tmp/=10;
}
str[0]=tmp+‘0’;
}
//重新找回零点,每次测量前调用
void To_Zero() {
FullScale=ReadCount()/1000;
price=0;
}
//显示单价,单位为元,四位整数,两位小数
void Display_Price()
{
unsigned int i,j;
display_GB2312_string(5,44,“ ”);
i = price/100; //得到整数部分
j = price - i*100;//得到小数部分
int2str(i,str1); //显示整数部分
if (i》=1000)
{
display_GB2312_string(5,44,str1);
}
else if (i》=100)
{
display_GB2312_string(5,52,str1);
}
else if (i》=10)
{
display_GB2312_string(5,60,str1);
}
else
{
display_GB2312_string(5,68,str1);
}
//显示小数点
display_GB2312_string(5,76,“。”);
//显示小数部分
int2str(j,str1);
if (j《10)
{
display_GB2312_string(5,84,“0”);
display_GB2312_string(5,92,str1);
}
else
{
display_GB2312_string(5,84,str1);
}
}
//显示重量,单位kg,两位整数,三位小数
void Display_Weight()
{
unsigned int i,j;
display_GB2312_string(3,60,“ ”); //weight单位是g
i = weight/1000; //得到整数部分
j = weight - i*1000;//得到小数部分
int2str(i,str1);
if (i》=10)
{
display_GB2312_string(3,60,str1);
}
else
{
display_GB2312_string(3,68,str1);
}
display_GB2312_string(3,76,“。”);
int2str(j,str1);
if (j《10) else if (j《100)
{
display_GB2312_string(3,84,“0”);
display_GB2312_string(3,92,str1);
}
else
{
display_GB2312_string(3,84,str1);
}
}
//显示总价,单位为元,四位整数,两位小数
void Display_Money()
{
unsigned int i,j;
display_GB2312_string(7,44,“ ”);
if (money》999999) //超出显示量程
{
display_GB2312_string(7,44,“-------”);
return;
}
display_GB2312_string(7,44,str1);
}
else if (i》=100)
{
display_GB2312_string(7,52,str1);
}
else if (i》=10)
{
display_GB2312_string(7,60,str1);
}
else
{
display_GB2312_string(7,68,str1);
}
//显示小数点
display_GB2312_string(7,76,“。”); //显示小数部分
int2str(j,str1);
if (j《10)
{
display_GB2312_string(7,84,“0”);
display_GB2312_string(7,92,str1);
}
else
{
display_GB2312_string(7,84,str1);
}
}
//数据初始化
void Data_Init()
{
price = 0;
DotPos = 0;
beep = 1;
alert = 1;
}
//管脚配置 void Port_Init()
{
}
//定时器0初始化
void Timer0_Init()
{
ET0 = 1; //允许定时器0中断 TMOD = 1;
//定时器工作方式选择 TL0 = 0x06;
TH0 = 0xf8; //定时器赋予初值
TR0 = 1; //启动定时器
}
//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0
{
TL0 = 0x06;
TH0 = 0xf8; //定时器赋予初值
//每0.5秒钟刷新重量
Counter ++;
if (Counter 》= 200)
{
FlagTest = 1;
Counter = 0;
}
}
//===============main program===================//
void main(void)
{
Rom_CS=1;
initial_lcd();
EA = 0;
Data_Init();
Port_Init();
Timer0_Init(); //初始化完成,开中断
EA = 1; //背光
LedA = 1;
clear_screen(); //clear all dots
display_GB2312_string(1,1,“电子秤初始化。。。。”);
To_Zero();
display_GB2312_string(1,1,“电子秤初始化成功”);
display_GB2312_string(3,1,“重量: kg”);
display_GB2312_string(5,1,“单价: 元”);
display_GB2312_string(7,1,“金额: 元”);
Display_Price();
while(1)
{
//每0.5秒称重一次
if (FlagTest==1)
{
//称重,得到重量值weight,单位为g
AdVal=ReadCount();
weight=FullScale-AdVal/1000;
if (weight》0x8000) weight=0;
weight=10000*weight/FullScale;
weight=weight*RATIO; //如果超量程,则报警
if (weight 》= 10000)
{
beep = 0;
alert = 0;
display_GB2312_string(3,60,“------”);
display_GB2312_string(7,44,“--------”);
}
//如果不超量程
else
{
beep = 1;
alert = 1; //显示重量值
Display_Weight();
//如果单价设定好了,则计算价格
if (FlagSetPrice == 1)
{
money = weight*price/1000; //money单位为分
//显示总金额
Display_Money();
}
else
{
display_GB2312_string(7,44,“ ”);
}
//清测试标志
FlagTest = 0;
}
}
//获取按键
keycode = Getkeyboard(); //有效键值0-15
if ((keycode《16)&&(FlagKeyPress==0))
{
FlagKeyPress = 1;
KeyPress(keycode);
FlagKeyPress = 0;
}
delay(20);
}
}