标题:
差动桥智能电子秤的单片机源程序与原理图 1602矩阵键盘+ADC0832
[打印本页]
作者:
shuaifriend
时间:
2018-7-5 18:05
标题:
差动桥智能电子秤的单片机源程序与原理图 1602矩阵键盘+ADC0832
一个关于电子秤的毕业设计程序 1602矩阵键盘+ADC0832。大家可以参考
附件里面有原理图
单片机源程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define BUSY 0x80 //常量定义
#define DATAPORT P0
#define ADCOFFSET 12
#define GAIN 17.857
//ADC0832的引脚
sbit ADCS =P2^4; //ADC0832 chip seclect
sbit ADDI =P2^0; //ADC0832 k in
sbit ADDO =P2^1; //ADC0832 k out
sbit ADCLK =P2^2; //ADC0832 clock signal
sbit LCM_RS=P2^7;
sbit LCM_RW=P2^6;
sbit LCM_EN=P2^5;
sbit KEY_IN_1 = P1^7;
sbit KEY_IN_2 = P1^6;
sbit KEY_IN_3 = P1^5;
sbit KEY_IN_4 = P1^4;
sbit KEY_OUT_1 = P1^0;
sbit KEY_OUT_2 = P1^1;
sbit KEY_OUT_3 = P1^2;
sbit KEY_OUT_4 = P1^3;
char TestModeFlag = 0; //实验模式选项,单臂 半桥 全桥 0 1 2
char WeigherModeflag = 0;
char TestOrWeigher = 0;
char IsExistPoint = 0;
char IsInput = 0;
char InputIndex = 0;
char ShowWigherFlag = 0;
unsigned char PriceArray[5] = {'0','0','0','0','0'};
float voltage = 0;
float weight = 123.4;
float UnitPrice = 0;
float TotalPrice = 0;
float Shelling = 0;
float K_D = 0.1764;
float K_B = 0.3805;
float K_Q = 0.7541;
float B_D = 0.3636;
float B_B = -0.4091;
float B_Q = -0.1364;
long ad_data;
unsigned long AD_Sum = 0;
unsigned long TimerCnt =0;
sbit Beep =P3^2; //超过重量表量程最大值红色led报警定义
unsigned char AlarmFlag = 0;
//adc采样值存储单元
unsigned char KeySta[4][4] = {
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
{ 0x01, 0x02, 0x03, 'U' }, //数字键1、数字键2、数字键3、向上键
{ 0x04, 0x05, 0x06, 'D' }, //数字键4、数字键5、数字键6、向下键
{ 0x07, 0x08, 0x09, 'E' }, //数字键7、数字键8、数字键9、向下键
{ 0x00, '.', 'L', 'R' } //数字键0、ESC键、 回车键、 向右键
};
void KeyDriver();
void Showfolat_1(uchar X,uchar Y,float num);
void Showfolat_2(uchar X,uchar Y,float num);
void delay(uint);
void lcd_wait(void);
void delay_LCM(uint); //LCD延时子程序
void initLCM( void); //LCD初始化子程序
void lcd_wait(void); //LCD检测忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC); //写指令到ICM子函数
void WriteDataLCM(uchar WDLCM); //写数据到LCM子函数
void DisplayOneChar(uchar X,uchar Y,uchar DData); //显示指定坐标的一个字符子函数
void DisplayListChar(uchar X,uchar Y,uchar code *DData); //显示指定坐标的一串字符子函数
void WeigherModeDisplay();
void TestModeDisplay();
//系统显示子函数
uchar Adc0832(unsigned char channel);
void alarm(void);
/**********main funcation************/
void main(void)
{
int i = 0;
Beep = 0;
EA = 1; //使能总中断
TMOD = 0x11; //设置T0为模式1
TH0 = 0xF8; //为T0赋初值0xFC67,定时2ms
TL0 = 0x2F;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
TH1 = 0x27; //为T1赋初值0xFC67,定时50ms
TL1 = 0x10;
ET1 = 1; //使能T1中断
TR1 = 1; //启动T1
Beep = 0;
delay(500); //系统延时500ms启动
ad_data=0; //采样值存储单元初始化为0
initLCM( );
Beep = 0;
WriteCommandLCM(0x01,1); //清显示屏
//DisplayListChar(0,0,str0);
WriteCommandLCM(0x01,0);
//DisplayListChar(0,1,str2);
Beep = 0;
while(1)
{
ad_data = 0;
for(i=0;i<400;i++)
ad_data += Adc0832(0); //采样值存储单元初始化为0
ad_data/=400;
voltage = ad_data;
//voltage = 1000*ad_data*5.0/255.0/GAIN;
//voltage = (ad_data*5.0/255.0)*1000.0/GAIN;
if(TestOrWeigher==0)
{
TestModeDisplay();
delay(1);
Beep = 0;
DisplayOneChar(14,1,' ');
DisplayOneChar(15,1,' ');
}else if(TestOrWeigher==1)
{
WeigherModeDisplay();
alarm();
delay(1);
}
//KeyDriver();
// DisplayOneChar(0,0,ad_data/100+'0');
// DisplayOneChar(1,0,ad_data/10%10+'0');
// DisplayOneChar(2,0,ad_data%10+'0');
// delay(500);
}
}
/*********延时K*1ms,12.000Mhz**********/
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
for(j=0;j<60;j++);
}
/**********写指令到ICM子函数************/
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)
lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; // 选中指令寄存器
LCM_RW=0; // 写模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/**********写数据到LCM子函数************/
void WriteDataLCM(uchar WDLCM)
{
lcd_wait( ); //检测忙信号
DATAPORT=WDLCM;
LCM_RS=1; // 选中数据寄存器
LCM_RW=0; // 写模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/***********lcm内部等待函数*************/
void lcd_wait(void)
{
DATAPORT=0xff; //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
_nop_();
_nop_();
while(DATAPORT&BUSY)
{ LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}
/**********LCM初始化子函数***********/
void initLCM( )
{
DATAPORT=0;
delay(15);
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
delay(5);
WriteCommandLCM(0x38,0);
delay(5);
WriteCommandLCM(0x38,0);
delay(5);
WriteCommandLCM(0x38,1); //8bit数据传送,2行显示,5*7字型,检测忙信号
WriteCommandLCM(0x08,1); //关闭显示,检测忙信号
WriteCommandLCM(0x01,1); //清屏,检测忙信号
WriteCommandLCM(0x06,1); //显示光标右移设置,检测忙信号
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
}
/****显示指定坐标的一个字符子函数****/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=0x01;
X&=0x0f;
if(Y)X|=0x40; //若y为1(显示第二行),地址码+0X40
X|=0x80; //指令码为地址码+0X80
WriteCommandLCM(X,1);
WriteDataLCM(DData);
}
void Showfolat_1(uchar X,uchar Y,float num)
{
int i = 0;
unsigned char temp[5]={0};
int number;
number = (int)(num*10);
//int number = 12345;
temp[4] = number%10;
temp[3] = '.';
temp[2] = number/10%10;
temp[1] = number/100%10;
temp[0] = number/1000%10;
DisplayOneChar(X+4,Y,temp[4]+'0');
DisplayOneChar(X+3,Y,temp[3]);
DisplayOneChar(X+2,Y,temp[2]+'0');
DisplayOneChar(X+1,Y,temp[1]+'0');
DisplayOneChar(X+0,Y,temp[0]+'0');
if(temp[i]==0)
{
for(i = 0;i<2;i++)
{
if(temp[i]!=0)break;
if(temp[i]==0)DisplayOneChar(X+i,Y,' ');
}
}
}
void Showfolat_2(uchar X,uchar Y,float num)
{
int i = 0;
int j = 1;
int temp[7]={0};
long number;
number = (long)(num*100);
//int number = 12345;
temp[6] = number%10;
temp[5] = number/10%10;
temp[4] = '.';
temp[3] = number/100%10;
temp[2] = number/1000%10;
temp[1] = number/10000%10;
temp[0] = number/100000%10;
DisplayOneChar(X+6,Y,temp[6]+'0');
DisplayOneChar(X+5,Y,temp[5]+'0');
DisplayOneChar(X+4,Y,temp[4]);
DisplayOneChar(X+3,Y,temp[3]+'0');
DisplayOneChar(X+2,Y,temp[2]+'0');
DisplayOneChar(X+1,Y,temp[1]+'0');
DisplayOneChar(X+0,Y,temp[0]+'0');
if(temp[i]==0)
{
for(i = 0;i<3;i++)
{
if(temp[i]!=0)break;
if(temp[i]==0)DisplayOneChar(X+i,Y,' ');
}
}
// for(i = 0;i<7;i++)
// if(temp[i]==0)DisplayOneChar(X+i,Y,0);
}
void Showfolat_3(uchar X,uchar Y,float num)
{
int i = 0;
int j = 1;
int temp[7]={0};
long number;
number = (long)(num*1000);
//int number = 12345;
temp[6] = number%10;
temp[5] = number/10%10;
temp[4] = number/100%10;
temp[3] = '.';
temp[2] = number/1000%10;
temp[1] = number/10000%10;
temp[0] = number/100000%10;
DisplayOneChar(X+6,Y,temp[6]+'0');
DisplayOneChar(X+5,Y,temp[5]+'0');
DisplayOneChar(X+3,Y,temp[3]);
DisplayOneChar(X+4,Y,temp[4]+'0');
DisplayOneChar(X+2,Y,temp[2]+'0');
DisplayOneChar(X+1,Y,temp[1]+'0');
DisplayOneChar(X+0,Y,temp[0]+'0');
if(temp[i]==0)
{
for(i = 0;i<2;i++)
{
if(temp[i]!=0)break;
if(temp[i]==0)DisplayOneChar(X+i,Y,' ');
}
}
}
void TestModeDisplay()
{
//
// float voltage = 0;
// float weight = 0;
// float sensitivity = 0;
DisplayOneChar(2,0,'U');
DisplayOneChar(3,0,':');
if(ShowWigherFlag==1)
DisplayOneChar(9,0,'W');
else DisplayOneChar(9,0,' ');
if(ShowWigherFlag==1)
DisplayOneChar(10,0,':');
else DisplayOneChar(10,0,' ');
if(ShowWigherFlag==1)
DisplayOneChar(0,1,'S');
else DisplayOneChar(0,1,' ');
if(ShowWigherFlag==1)
DisplayOneChar(1,1,':');
else DisplayOneChar(1,1,' ');
if(TestModeFlag==0)
{
DisplayOneChar(0,0,'D');
if(ShowWigherFlag==1)
Showfolat_3(2,1,K_D);
else{
DisplayOneChar(2,1,' ');
DisplayOneChar(3,1,' ');
DisplayOneChar(4,1,' ');
DisplayOneChar(5,1,' ');
DisplayOneChar(6,1,' ');
DisplayOneChar(7,1,' ');
DisplayOneChar(8,1,' ');
DisplayOneChar(9,1,' ');
DisplayOneChar(10,1,' ');
}
weight = (voltage - B_D)/K_D;
if(voltage==0)weight = 0;
}else if(TestModeFlag==1)
{
DisplayOneChar(0,0,'B');
if(ShowWigherFlag==1)
Showfolat_3(2,1,K_B);
else{
DisplayOneChar(2,1,' ');
DisplayOneChar(3,1,' ');
DisplayOneChar(4,1,' ');
DisplayOneChar(5,1,' ');
DisplayOneChar(6,1,' ');
DisplayOneChar(7,1,' ');
DisplayOneChar(8,1,' ');
DisplayOneChar(9,1,' ');
DisplayOneChar(10,1,' ');
}
weight = (voltage - B_B)/K_B;
if(voltage==0)weight = 0;
}else if(TestModeFlag==2)
{
DisplayOneChar(0,0,'Q');
if(ShowWigherFlag==1)
Showfolat_3(2,1,K_Q);
else{
DisplayOneChar(2,1,' ');
DisplayOneChar(3,1,' ');
DisplayOneChar(4,1,' ');
DisplayOneChar(5,1,' ');
DisplayOneChar(6,1,' ');
DisplayOneChar(7,1,' ');
DisplayOneChar(8,1,' ');
DisplayOneChar(9,1,' ');
DisplayOneChar(10,1,' ');
}
weight = (voltage - B_Q)/K_Q;
if(voltage==0)weight = 0;
}
Showfolat_1(4,0,voltage);
if(ShowWigherFlag==1)
{
Showfolat_1(11,0,weight);
}
else
{
DisplayOneChar(15,0,' ');
DisplayOneChar(14,0,' ');
DisplayOneChar(13,0,' ');
DisplayOneChar(12,0,' ');
DisplayOneChar(11,0,' ');
}
}
void WeigherModeDisplay()
{
DisplayOneChar(0,0,'W');
DisplayOneChar(1,0,':');
if(IsInput == 0)
{
DisplayOneChar(8,0,'U');
DisplayOneChar(9,0,'P');
}
DisplayOneChar(10,0,':');
DisplayOneChar(0,1,'T');
DisplayOneChar(1,1,'P');
DisplayOneChar(2,1,':');
weight = (voltage-Shelling)*2.0;
TotalPrice = UnitPrice*weight;
Showfolat_1(2,0,weight);
Showfolat_2(3,1,TotalPrice);
}
void KeyAction(unsigned char keycode)
{
int i = 0;
int j = 1;
float k = 0.1;
//IsExistPoint
if(TestOrWeigher==0)//试验模式
{
if((keycode >= 0x00) &&(keycode <= 0x09))
{
}else if(keycode == '.')
{
}else if(keycode == 'E')
{
TestOrWeigher = 1;
//Showfolat_2(11,0,12.34);
}else if(keycode == 'U')
{
TestModeFlag--;
} else if(keycode == 'D')
{
TestModeFlag++;
}else if(keycode == 'L')
{
ShowWigherFlag = 0;
WriteCommandLCM(0x01,1); //清显示屏
WriteCommandLCM(0x01,0); //清显示屏
}else if(keycode == 'R')
{
ShowWigherFlag = 1;
WriteCommandLCM(0x01,1); //清显示屏
WriteCommandLCM(0x01,0); //清显示屏
}
if(TestModeFlag<=0)TestModeFlag = 0;
if(TestModeFlag>=2)TestModeFlag = 2;
}else if(TestOrWeigher==1)
{
if((keycode >= 0x00) &&(keycode <= 0x09))
{
if(IsInput)
{
//DisplayOneChar(13,1,InputIndex+'0');
switch(InputIndex)
{
case 0:
PriceArray[4] = keycode+'0';
break;
case 1:
PriceArray[3] = PriceArray[4];
PriceArray[4] = keycode+'0';
break;
case 2:
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = keycode+'0';
break;
case 3:
PriceArray[1] = PriceArray[2];
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = keycode+'0';
break;
case 4:
PriceArray[0] = PriceArray[1];
PriceArray[1] = PriceArray[2];
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = keycode+'0';
break;
default:break;
}
}
InputIndex++;
if(InputIndex>4)InputIndex=5;
//DisplayOneChar(0,1,keycode+'0');
}else if(keycode == '.')
{
if(IsInput)
{
switch(InputIndex)
{
case 0:
PriceArray[4] = '.';
break;
case 1:
PriceArray[3] = PriceArray[4];
PriceArray[4] = '.';
break;
case 2:
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = '.';
break;
case 3:
PriceArray[1] = PriceArray[2];
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = '.';
break;
case 4:
PriceArray[0] = PriceArray[1];
PriceArray[1] = PriceArray[2];
PriceArray[2] = PriceArray[3];
PriceArray[3] = PriceArray[4];
PriceArray[4] = '.';
break;
default:break;
}
}
IsExistPoint = InputIndex;
InputIndex++;
}else if(keycode == 'E')
{
TestOrWeigher = 0;
}else if(keycode == 'U')
{
IsInput = 1;
InputIndex = 0;
for(i = 0;i<5;i++)
PriceArray[i] = 0+'0';
UnitPrice = 0;
} else if(keycode == 'D')
{
IsExistPoint = 5;
for(i = 0;i<5;i++)
{
if(PriceArray[i]=='.')
{
IsExistPoint = i;
break;
}
}
for(i=IsExistPoint-1;i>=0;i--)
{
UnitPrice += j*(PriceArray[i]-'0');
j*=10;
}
for(i=IsExistPoint+1;i<5;i++)
{
UnitPrice += k*(PriceArray[i]-'0');
k*=0.1;
}
//Showfolat_2(3,1,UnitPrice);
IsInput = 0;
}else if(keycode == 'L')
{
//DisplayOneChar(0,1,keycode);
Shelling = voltage;
}else if(keycode == 'R')
{
//DisplayOneChar(0,1,keycode);
Shelling = 0;
}
}
for(i = 0;i<5;i++)
{
// if(PriceArray[i]=='0')
// DisplayOneChar(11+i,0,0);
// else
DisplayOneChar(11+i,0,PriceArray[i]);
}
// if(PriceArray[0]==0)
// {
// for(i = 0;i<3;i++)
// {
// if(PriceArray[i]!=0)break;
// if(PriceArray[i]==0)DisplayOneChar(11+i,0,' ');
// }
// }
}
void KeyDriver()
{
unsigned char i, j;
static unsigned char backup [4][4] = {
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(backup[i][j] != KeySta[i][j])
{
if(backup[i][j] == 0)
{
KeyAction(KeyCodeMap[i][j]);
}
backup[i][j] = KeySta[i][j];
}
}
}
}
/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
void KeyScan()
{
unsigned char i;
static unsigned char keyout = 0; //矩阵按键扫描输出索引
static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
};
//将一行的4个按键值移入缓冲区
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
//消抖后更新按键状态
for (i=0; i<4; i++) //每行4个按键,所以循环4次
{
if ((keybuf[keyout][i] & 0x0F) == 0x00)
{ //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[keyout][i] = 0;
}
else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
{ //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[keyout][i] = 1;
}
}
//执行下一次的扫描输出
keyout++; //输出索引递增
keyout = keyout & 0x03; //索引值加到4即归零
switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚
{
case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
default: break;
}
}
/************
读ADC0832函数
************/
//采集并返回
uchar Adc0832(unsigned char channel) //AD转换,返回结果
{
uchar i=0;
uchar j;
uint dat=0;
uchar ndat=0;
if(channel==0)channel=2;
if(channel==1)channel=3;
ADDI=1;
_nop_();
_nop_();
ADCS=0;//拉低CS端
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=channel&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}
for(i=0;i<8;i++)
{
j=0;
j=j|ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
j=j<<7;
ndat=ndat|j;
if(i<7)ndat>>=1;
}
ADCS=1;//拉低CS端
ADCLK=0;//拉低CLK端
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
差动桥智能电子秤毕设.zip
(125.6 KB, 下载次数: 38)
2018-7-5 18:03 上传
点击文件名下载附件
1602+矩阵键盘+ADC0832
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1