|
電子秤的仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (23.88 KB, 下載次數(shù): 70)
下載附件
2018-4-20 02:47 上傳
0.jpg (36.77 KB, 下載次數(shù): 63)
下載附件
2018-4-20 02:48 上傳
單片機(jī)源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #define PLEN 7
- #define WLEN 4
- #define MLEN 4
- #define SUMLEN 10
- #define BEEP() P1^=(1<<0);//蜂鳴器
- #define Key_NO (P2&0x0F)
- #define delay4us() {_nop_(); _nop_(); _nop_(); _nop_();}
- #define Key_Pressed (P2&(1<<4)) //DA(P1^4)為高電平時(shí)表示有鍵按下
- //#define Key_NO (P2&0x0F) /、//解碼器輸出線(xiàn)連接在P1低四位
- sbit RS=P1^1; //寄存器選擇引腳,搞電平選擇數(shù)據(jù)寄存器,低電平選擇指令寄存器
- sbit RW=P1^2; //讀寫(xiě)操作使能引腳,高電平使能讀操作,低電平使能寫(xiě)操作
- sbit E=P1^3; //總使能引腳
- sbit FMQ=P1^0; //蜂鳴器
- sbit CS=P3^5;
- sbit CLK=P3^6;
- sbit DIO=P3^7;
- volatile int AD_Result,Pre_Result=0,Pressure_Value=0,Pressure_Value1=0,AD_Result1=0;
- code char KEY_CHAR_TABLE[]="0123456789.BCDEF"; //鍵盤(pán)字符表
- //----------------------AD轉(zhuǎn)換程序--------------//
- uchar GET_CHx_AD_Value(uchar ch)
- {
- uchar i,dat1=0,dat2=0;
- CS=0;CLK=0;
- DIO=1;
- _nop_(); _nop_();
- CLK=1;
- _nop_(); _nop_();
- CLK=0;DIO=1;
- //_nop_(); _nop_();
- _nop_(); _nop_();
- CLK=1; _nop_(); _nop_();
- CLK=0;DIO=ch;
- _nop_(); _nop_();
- CLK=1;
- _nop_(); _nop_();
- CLK=0;DIO=1;
- _nop_(); _nop_();
- for(i=0;i<8;i++)
- {
- CLK=1; _nop_(); _nop_();
- CLK=0; _nop_(); _nop_();
- dat1=(dat1<<1)|DIO;
- }
- for(i=0;i<8;i++)
- {
- dat2=dat2|((uchar)DIO<<i);
- CLK=1; _nop_(); _nop_();
- CLK=0; _nop_(); _nop_();
- }
- CS=1;
- return (dat1==dat2)?dat1:0x00;
- }
- //--------------------延時(shí)子函數(shù)--------//
- void delay(uchar x)
- {
- uchar t;while(x--) for(t=0;t<120;t++) ;
- }
- /*//-----------------------單鍵掃描子函數(shù)-------------//
- unsigned char JP()
- {
- unsigned char x=0x00;
- bit i=0;
- x=P2; //掃描Y坐標(biāo)
- FMQ=0; //響起蜂鳴器
- delay(125); //延時(shí)去抖動(dòng)
- P2=0x0f;
- delay(2);
- x+=P2; //掃描X坐標(biāo)
- switch(x)
- {
- case 0xee:x=0x30;break; //按下0
- case 0xed:x=0x31;break; //按下1
- case 0xeb:x=0x34;break; //按下4
- case 0xe7:x=0x37;break; //按下7
- case 0xde:x=0x46;break; //按下F
- case 0xdd:x=0x32;break; //按下2
- case 0xdb:x=0x35;break; //按下5
- case 0xd7:x=0x38;break; //按下8
- case 0xbe:x=0x45;break; //按下E
- case 0xbd:x=0x33;break; //按下3
- case 0xbb:x=0x36;break; //按下6
- case 0xb7:x=0x39;break; //按下9
- case 0x7e:x=0x44;break; //按下D
- case 0x7d:x=0x43;break; //按下C
- case 0x7b:x=0x42;break; //按下B
- case 0x77:x=0x41;break; //按下A
- default:x=0xff;break;
- }
- //FMQ=1; //關(guān)閉蜂鳴器
- while(i==0) //等待按鍵松開(kāi)
- {
- P2=0xf0;
- delay(150);
- if(P2==0xf0)
- {
- i=1;
- }
- else{i=0;}
- }
- return x; //返回x(ASCII碼)
- }*/
- //------------------測(cè)忙-----------------//
- bit Read_LCD_Busy_Flag()
- {
- uchar result;
- P0=0xFF;
- RS=0;RW=1;
- E=1;delay4us(); result=P0; E=0;
- return(result & 0x80)?1:0;
- }
- //------------------寫(xiě)指令-------------------------//
- void write_com(uchar com)
- {
- while(Read_LCD_Busy_Flag());
- RS=0;RW=0;
- E=0;_nop_(); _nop_(); P0=com;
- delay4us();E=1;delay4us();E=0;
- }
- //------------------寫(xiě)數(shù)據(jù)-------------------------//
- void write_dat(uchar dat)
- {
- while(Read_LCD_Busy_Flag());
- RS=1;RW=0;
- E=0;P0=dat;delay4us();
- E=1;delay4us();E=0;
- }
- //----------------------顯示-----------------------------//
- void LCD_Show_String(uchar r,uchar c,char *s )
- {
- uchar i=0;
- uchar code DDRAM[]={0x80,0xC0};
- write_com(DDRAM[r]|c);
- while(s[i]&&i<16) write_dat(s[i++]);
- }
- //---------------1602初始化-----------------//
- void initinal()
- {
- write_com(0x38);delay(1);
- write_com(0x0C);delay(1);
- write_com(0x06);delay(1);
- write_com(0x01);delay(1);
- }
- //LCD顯示輸出緩沖(單價(jià),重量,總價(jià))
- char disp_buffer_P[PLEN];
- char disp_buffer_W[WLEN];
- char disp_buffer_SUM[SUMLEN];
- uchar NumberPtr=0; //價(jià)格輸入緩沖的索引
- ////----------蜂鳴器輸出------------//
- void Sounder()
- {
- uchar i,j;
- for(i=0;i<200;i++)
- {
- BEEP();
- j=70;
- while(--j);
- }
- }
- //------------處理運(yùn)算并顯示余額 -----------//
- void Compute_and_show_sum()
- {
- float p,w;
- if(strlen(disp_buffer_P)==0)p=0;else
- p=strtod(disp_buffer_P,'\0'); //價(jià)格未輸入時(shí),將p設(shè)為0,否則轉(zhuǎn)換為float類(lèi)型
- w=strtod(disp_buffer_W,'\0'); //將重量字符串轉(zhuǎn)換成float類(lèi)型
- sprintf(disp_buffer_SUM,"%.2f",p*w); //計(jì)算金額并生成字符串
- LCD_Show_String(1,7,(char *)" " ); //清除金額,然后顯示最新金額
- LCD_Show_String(1,7,disp_buffer_SUM );
- }
- //處理鍵盤(pán)操作
- void KeyBoard_Handle()
- {
- char KeyChar;
- static uchar havedot=0; //是否已經(jīng)輸入的價(jià)格p的小數(shù)點(diǎn)
- static uchar dtnum=PLEN; //在沒(méi)有輸入小數(shù)點(diǎn)時(shí)可繼續(xù)輸入的字符的個(gè)數(shù)(dtnum初始值為7)
- if(Key_Pressed)
- {
- Sounder(); //按鍵提示音
- KeyChar=KEY_CHAR_TABLE[Key_NO]; //獲取按鍵字符
- //如果輸入的是數(shù)字字符或小數(shù)點(diǎn)并且此前沒(méi)有輸入過(guò)小數(shù)點(diǎn)
- if(isdigit(KeyChar)||(KeyChar=='.'&&!havedot))
- {
- if(strlen(disp_buffer_P)==3&&(KeyChar!='.'&&!havedot)) //限制整數(shù)部分最高為三位數(shù),及整數(shù)部分最大為999
- return;
- //將輸入的字符存入緩沖
- if(NumberPtr<dtnum)
- {
- // 如果輸入的第一個(gè)字符是‘0’或者‘.’,就相當(dāng)于直接輸入了‘0.’
- if(NumberPtr==0&&(KeyChar=='0'||KeyChar=='.'))
- {
- disp_buffer_P[NumberPtr++]='0';
- KeyChar=='.';
- disp_buffer_P[NumberPtr++]='.';
- }
- else
- {
- disp_buffer_P[NumberPtr++]=KeyChar;
- }
- disp_buffer_P[NumberPtr]='\0'; //加字符串結(jié)束標(biāo)志
- LCD_Show_String(0,3,disp_buffer_P ); //刷新顯示總價(jià)
- }
- //輸入字符為‘.’,且此前未輸入過(guò)小數(shù)點(diǎn),開(kāi)始限定可輸入的小數(shù)位數(shù)
- if(KeyChar=='.'&&!havedot)
- {
- dtnum=NumberPtr+2;havedot=1;
- }
- }
- if(KeyChar=='B') //清零操作
- {
- NumberPtr=0;
- havedot=0;
- dtnum=PLEN-2;
- disp_buffer_P[0]='\0';
- disp_buffer_SUM[0]='\0';
- LCD_Show_String(0,3,(char *)" " ); //清除單價(jià)
- LCD_Show_String(1,7,(char *)" " ); //清除總價(jià)
- }
- if(KeyChar=='C') //刪除操作(可用于單價(jià)輸入錯(cuò)誤時(shí))
- {
- write_com(0x80+NumberPtr+2); //確定刪除對(duì)象
- write_dat(' '); //顯示空格即為刪除
- disp_buffer_P[--NumberPtr]=0; //刪除后數(shù)據(jù)清零
- write_com(0x80+NumberPtr); //為下次輸入數(shù)據(jù)時(shí)寫(xiě)好位置,必須是在最后一個(gè)后面
-
- }
-
- if (Key_Pressed) Compute_and_show_sum();
- while(Key_Pressed); //等待按鍵釋放
- }
- }
- //--------------------主函數(shù)-------------//
- void main()
- {
- initinal();
- LCD_Show_String(0,0,(char*)"P: W:");
- LCD_Show_String(1,0,(char*)"SUM($):");
- while(1)
- {
- AD_Result=GET_CHx_AD_Value(0) ;
-
-
- Pressure_Value=(int)((AD_Result*5.0*2/511.0/5.1-0.04)/0.00369-3.45);
- KeyBoard_Handle();
- //M_Value=(int)(Pressure_Value*0.0101972);
- if(Pressure_Value>=230) //超重報(bào)警
- { write_com(0x01);
- LCD_Show_String(0,0,"ERROR!");
- Sounder();
- }
- sprintf(disp_buffer_W,"%-3d",Pressure_Value);
- LCD_Show_String(0,13,disp_buffer_W);
- //KeyBoard_Handle();
- //壓力變化就計(jì)算金額
- if(Pre_Result!=AD_Result)
- {
- Compute_and_show_sum();
- Pre_Result=AD_Result;
- Sounder();
- }
- delay(50);
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
最終版.zip
(102.99 KB, 下載次數(shù): 111)
2018-4-19 17:13 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|