電子秤的仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #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)為高電平時表示有鍵按下
- //#define Key_NO (P2&0x0F) /、//解碼器輸出線連接在P1低四位
- sbit RS=P1^1; //寄存器選擇引腳,搞電平選擇數據寄存器,低電平選擇指令寄存器
- sbit RW=P1^2; //讀寫操作使能引腳,高電平使能讀操作,低電平使能寫操作
- 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"; //鍵盤字符表
- //----------------------AD轉換程序--------------//
- 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;
- }
- //--------------------延時子函數--------//
- void delay(uchar x)
- {
- uchar t;while(x--) for(t=0;t<120;t++) ;
- }
- /*//-----------------------單鍵掃描子函數-------------//
- unsigned char JP()
- {
- unsigned char x=0x00;
- bit i=0;
- x=P2; //掃描Y坐標
- FMQ=0; //響起蜂鳴器
- delay(125); //延時去抖動
- P2=0x0f;
- delay(2);
- x+=P2; //掃描X坐標
- 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; //關閉蜂鳴器
- while(i==0) //等待按鍵松開
- {
- P2=0xf0;
- delay(150);
- if(P2==0xf0)
- {
- i=1;
- }
- else{i=0;}
- }
- return x; //返回x(ASCII碼)
- }*/
- //------------------測忙-----------------//
- 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;
- }
- //------------------寫指令-------------------------//
- 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;
- }
- //------------------寫數據-------------------------//
- 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顯示輸出緩沖(單價,重量,總價)
- char disp_buffer_P[PLEN];
- char disp_buffer_W[WLEN];
- char disp_buffer_SUM[SUMLEN];
- uchar NumberPtr=0; //價格輸入緩沖的索引
- ////----------蜂鳴器輸出------------//
- void Sounder()
- {
- uchar i,j;
- for(i=0;i<200;i++)
- {
- BEEP();
- j=70;
- while(--j);
- }
- }
- //------------處理運算并顯示余額 -----------//
- void Compute_and_show_sum()
- {
- float p,w;
- if(strlen(disp_buffer_P)==0)p=0;else
- p=strtod(disp_buffer_P,'\0'); //價格未輸入時,將p設為0,否則轉換為float類型
- w=strtod(disp_buffer_W,'\0'); //將重量字符串轉換成float類型
- sprintf(disp_buffer_SUM,"%.2f",p*w); //計算金額并生成字符串
- LCD_Show_String(1,7,(char *)" " ); //清除金額,然后顯示最新金額
- LCD_Show_String(1,7,disp_buffer_SUM );
- }
- //處理鍵盤操作
- void KeyBoard_Handle()
- {
- char KeyChar;
- static uchar havedot=0; //是否已經輸入的價格p的小數點
- static uchar dtnum=PLEN; //在沒有輸入小數點時可繼續輸入的字符的個數(dtnum初始值為7)
- if(Key_Pressed)
- {
- Sounder(); //按鍵提示音
- KeyChar=KEY_CHAR_TABLE[Key_NO]; //獲取按鍵字符
- //如果輸入的是數字字符或小數點并且此前沒有輸入過小數點
- if(isdigit(KeyChar)||(KeyChar=='.'&&!havedot))
- {
- if(strlen(disp_buffer_P)==3&&(KeyChar!='.'&&!havedot)) //限制整數部分最高為三位數,及整數部分最大為999
- return;
- //將輸入的字符存入緩沖
- if(NumberPtr<dtnum)
- {
- // 如果輸入的第一個字符是‘0’或者‘.’,就相當于直接輸入了‘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'; //加字符串結束標志
- LCD_Show_String(0,3,disp_buffer_P ); //刷新顯示總價
- }
- //輸入字符為‘.’,且此前未輸入過小數點,開始限定可輸入的小數位數
- 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 *)" " ); //清除單價
- LCD_Show_String(1,7,(char *)" " ); //清除總價
- }
- if(KeyChar=='C') //刪除操作(可用于單價輸入錯誤時)
- {
- write_com(0x80+NumberPtr+2); //確定刪除對象
- write_dat(' '); //顯示空格即為刪除
- disp_buffer_P[--NumberPtr]=0; //刪除后數據清零
- write_com(0x80+NumberPtr); //為下次輸入數據時寫好位置,必須是在最后一個后面
-
- }
-
- if (Key_Pressed) Compute_and_show_sum();
- while(Key_Pressed); //等待按鍵釋放
- }
- }
- //--------------------主函數-------------//
- 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) //超重報警
- { 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();
- //壓力變化就計算金額
- if(Pre_Result!=AD_Result)
- {
- Compute_and_show_sum();
- Pre_Result=AD_Result;
- Sounder();
- }
- delay(50);
- }
- }
復制代碼
所有資料51hei提供下載:
最終版.zip
(102.99 KB, 下載次數: 111)
2018-4-19 17:13 上傳
點擊文件名下載附件
|