欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
差動橋智能電子秤的單片機源程序與原理圖 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.raoushi.com/bbs/)
Powered by Discuz! X3.1