找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6636|回復: 7
打印 上一主題 下一主題
收起左側(cè)

基于51單片機的紅外無線計算器設(shè)計

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:272887 發(fā)表于 2018-1-7 20:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本設(shè)計利用紅外線作為傳輸介質(zhì),利用紅外遙控其實現(xiàn)數(shù)據(jù)的輸入。其次用單片機處理數(shù)據(jù),計算結(jié)果采用1602液晶顯示器顯示,可支持負數(shù)的輸出。系統(tǒng)基本實現(xiàn)了計算器的加減乘除功能。



1系統(tǒng)方案
1.1 紅外部分的論證與選擇
1.2 顯示部分的論證與選擇
1.3 控制系統(tǒng)的論證與選擇
2系統(tǒng)理論分析與計算
3電路與程序設(shè)計
3.1電路的設(shè)計
3.1.1系統(tǒng)總體框圖
3.1.2控制部分子系統(tǒng)框圖與電路原理圖
3.1.3 紅外部分子系統(tǒng)框圖與電路原理圖
3.1.4 1602顯示子系統(tǒng)框圖與電路原理圖
3.1.5電源
3.2程序的設(shè)計
3.2.1程序功能描述與設(shè)計思路
3.2.2程序流程圖
4測試方案與測試結(jié)果
4.1測試方案
4.2 測試結(jié)果及分析
附錄1:源程序

基于STC89C516RD+的紅外計算器
技術(shù)部
1系統(tǒng)方案
本系統(tǒng)主要由紅外部分、控制系統(tǒng)部分、顯示部分組成,電源直接使用5V直流電。下面分別論證這幾個模塊的選擇。
1.1    紅外部分的論證與選擇
由于采用矩陣鍵盤的輸入方式會浪費單片機過多的IO口,且鍵盤掃描函數(shù)過于冗長。所以本系統(tǒng)摒棄了矩陣鍵盤的輸入,采用紅外遙控輸入。紅外輸入用紅外遙控器,接收用一體化紅外接收頭。整個紅外接收只用了3個IO口,使系統(tǒng)的電路設(shè)計個更為簡便。
1.2    顯示部分的論證與選擇
系統(tǒng)顯示部分采用市場出售的基于HD44780液晶芯片的1602液晶顯示器。此類顯示器可顯示數(shù)字和常用的字符。適合用于計算器的設(shè)計。
1.3    控制部分的論證與選擇
控制部分采用單片機STC90C516RD+實現(xiàn)。由于該計算器程序所用的ROM和RAM較小,沒有必要用增強型的1T單片機例如STC12C5A60S2。所以用普通的51單片機即可。系統(tǒng)采用了12M的晶振。實現(xiàn)了對數(shù)據(jù)的有效處理。
2系統(tǒng)理論分析與計算
              開啟系統(tǒng)之后,單片機就一直檢測有無紅外數(shù)據(jù)的輸入,若有則在單片機中實現(xiàn)數(shù)據(jù)的處理,后將數(shù)據(jù)傳輸?shù)?602顯示屏顯示出來。
3電路與程序設(shè)計3.1電路的設(shè)計3.1.1系統(tǒng)總體框圖

由于本系統(tǒng)在普中開發(fā)板上實現(xiàn),沒有另外焊接電路,故系統(tǒng)電路圖省略。

3.1.2 控制部分子系統(tǒng)框圖與電路原理圖
1、控制部分子系統(tǒng)框圖

圖1   控制部分子系統(tǒng)框圖
3.1.3 紅外子系統(tǒng)框圖與電路原理圖
1、紅外子系統(tǒng)框圖

圖3   紅外子系統(tǒng)框圖
3.1.4LCD1602顯示子系統(tǒng)框圖與電路原理圖

圖3   LCD1602顯示子系統(tǒng)框圖

3.1.5電源

電源直接使用(普中單片機開發(fā)板上的)直流5V供電,確保電路的正常穩(wěn)定工作。這部分電路比較簡單,故不作詳述。

3.2程序的設(shè)計3.2.1程序功能描述與設(shè)計思路

1、程序功能描述

根據(jù)題目要求軟件部分主要實現(xiàn)紅外解碼,計算函數(shù)和顯示函數(shù)。

1)紅外解碼及將鍵值顯示為指定字符。

2)計算器核心計算部分。

3)顯示輸入的算式及結(jié)果。

2、程序設(shè)計思路

3.2.2程序流程圖

1、主程序流程圖

4測試方案與測試結(jié)果4.1測試方案

1、硬件測試

              基于普中單片機開發(fā)測試儀測試


4.2 測試結(jié)果及分析
此設(shè)計符合原先設(shè)想,一切正常。

綜上所述,本設(shè)計達到設(shè)計要求。


參考文獻
《新概念51單片機c語言教程》 , 《C程序設(shè)計》


附錄1:源程序

單片機源程序如下:
  1. /****************************************************************************/
  2. /*                                                                                    紅外線計算器                                                                                                                                            */
  3. /*功能:可實現(xiàn)整數(shù)的加減乘除(由紅外遙控輸入,1602顯示)                                                                      */                                                                                                
  4. /*                            可實現(xiàn)負數(shù)的結(jié)果輸出                                                                                                                                                                        */
  5. /*                                                                                                                                                                                                                                                                */
  6. /*作者:                                                                                                                                                                                                                                */
  7. /****************************************************************************/


  8. /****************************頭文件*******************************************/
  9. #include<reg52.h>
  10. /*****************************宏定義******************************************/
  11. #define uchar unsigned char
  12. #define uint unsigned int
  13. #define lin P0                             //宏定義數(shù)據(jù)口

  14. /******************************位定義*****************************************/
  15. sbit BEEP = P1^5;                         //定義蜂鳴器端口
  16. sbit IRIN=P3^2;                                       //定義紅外使用的中斷
  17. sbit lcd1602e=P2^7;                         //1602使能端
  18. sbit lcd1602rw=P2^5;                     // 1602讀寫選擇端
  19. sbit lcd1602rs=P2^6;                     // 1602數(shù)據(jù)命令選擇端

  20. /******************************函數(shù)聲明***************************************/
  21. void delay(uint c);            //延時函數(shù)
  22. void writeorder(uchar order);  //寫命令函數(shù)
  23. void writedata(uchar dat);                 //寫數(shù)據(jù)函數(shù)
  24. void initialize();                                             //1602初始化函數(shù)
  25. void beep();                                                           //蜂鳴器發(fā)聲函數(shù)
  26. void IrInit();                                                           //紅外初始化函數(shù)
  27. void outwork(int a);                               //結(jié)果顯示函數(shù)
  28. void IRdelay(unsigned char x); //紅外解碼延時函數(shù)  


  29. /******************************定義全局變量或數(shù)組*****************************/
  30. unsigned char IRCOM[6];                     //定義紅外解碼所用數(shù)組

  31. /*******************************主函數(shù)****************************************/

  32. void main(void)                                       //主函數(shù)
  33. {            
  34.               uchar codedata[]="   welcome you ";                            //定義初始顯示界面
  35.                  uchar codedata1[]=" lin chuang wei ";

  36.               uint flag=0,lin0,lin1,k=0;                                              //定義局部變量
  37.               uchar flagfu,fuhao=0,beeplin=0,i,j;
  38.               int a=0,b=0,c=0;

  39.               initialize();                                                                                                  //1602初始化

  40.               for(j=100;j>0;j--)
  41.   {            
  42.                             writeorder(0x80);                   //設(shè)置數(shù)據(jù)指針起點,顯示在第一行
  43.                             for(i=0;i<16;i++)
  44.                             writedata(codedata1[i]);
  45.                             writeorder(0x80+0x40);              //設(shè)置數(shù)據(jù)指針起點,顯示在第二行
  46.                             for(i=0;i<14;i++)
  47.                                           {
  48.                                           writedata(codedata[i]);            
  49.                                           }
  50.    }
  51.             
  52.             
  53.               IrInit();                                                                                                                //紅外初始化
  54.               initialize();                                                                                                  //1602初始化
  55.               writeorder(0x80);                                   //設(shè)置顯示位置


  56. while(1)
  57.               {                                                                                                                                              //紅外解碼
  58.                             writeorder(0x06);                                                                      //設(shè)置指針加1
  59.                            
  60.                   IRCOM[5]=IRCOM[2]>>4;                                               //高位
  61.                             IRCOM[6]=IRCOM[2]&0x0f;                                     //低位            
  62.                             if(IRCOM[5]>9)
  63.                             {
  64.                                           lin0=0x37+IRCOM[5];              //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  65.                             }
  66.                             else
  67.                             {
  68.                                 lin0=IRCOM[5]+0x30;              //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  69.                             }            
  70.                             if(IRCOM[6]>9)
  71.                             {                           
  72.                                 lin1=IRCOM[6]+0x37;                           //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  73.                             }
  74.                             else
  75.                             {                           
  76.                                 lin1=IRCOM[6]+0x30;                           //將數(shù)值轉(zhuǎn)換為該顯示的ASCII碼
  77.                             }               
  78.                             if((lin0==49)&&(lin1==54))writedata(flagfu='0'); //顯示0
  79.               else if((lin0==48)&&(lin1==67))writedata(flagfu='1'); //顯示1
  80.               else if((lin0==49)&&(lin1==56))writedata(flagfu='2'); //顯示2
  81.               else if((lin0==53)&&(lin1==69))writedata(flagfu='3'); //顯示3
  82.               else if((lin0==48)&&(lin1==56))writedata(flagfu='4'); //顯示4
  83.               else if((lin0==49)&&(lin1==67))writedata(flagfu='5'); //顯示5
  84.               else if((lin0==53)&&(lin1==65))writedata(flagfu='6'); //顯示6
  85.               else if((lin0==52)&&(lin1==50))writedata(flagfu='7'); //顯示7
  86.               else if((lin0==53)&&(lin1==50))writedata(flagfu='8'); //顯示8
  87.               else if((lin0==52)&&(lin1==65))writedata(flagfu='9'); //顯示9
  88.               else if((lin0==52)&&(lin1==53))                                                                                      //刪除所有顯示
  89.                             {
  90.                                           writeorder(0x01);                                                                                                    //清屏
  91.                                           writeorder(0x80);                                                                                                    //設(shè)置數(shù)據(jù)指針起點
  92.                                           a=0;b=0;                                                                                                                                //初始化a,b,避免計算出錯
  93.                             }                                
  94.   //else if((lin0==52)&&(lin1==54))                       //剩下1個空按鍵
  95.               else if((lin0==52)&&(lin1==55))beeplin=1;             // 關(guān)聲音
  96.               else if((lin0==52)&&(lin1==52))writedata(flagfu='='); //顯示=
  97.               else if((lin0==52)&&(lin1==48))writeorder(0x10);      //光標左移1位
  98.               else if((lin0==52)&&(lin1==51))writeorder(0x14);      //光標右移1位
  99.               else if((lin0==48)&&(lin1==55))                                                                                      //刪除一位數(shù)
  100.               {
  101.                             writeorder(0x10);
  102.                             writedata(' ');
  103.                             writeorder(0x10);
  104.               }
  105.               else if((lin0==49)&&(lin1==53))writedata(flagfu='-');  //顯示-
  106.               else if((lin0==48)&&(lin1==57))writedata(flagfu='+');  //顯示+
  107.               else if((lin0==49)&&(lin1==57))writedata(flagfu='*');  //顯示*
  108.               else if((lin0==48)&&(lin1==68))writedata(flagfu='/');  //顯示/
  109.             
  110.               if(beeplin==0)                                                                                                                                               //如果beeplin=0則蜂鳴器發(fā)聲
  111.                             beep();

  112.                 switch(flagfu)                                                                                                                                  //計算函數(shù)                                                                        
  113.                 {                                                      
  114.               case '=': switch(fuhao)
  115.                                     {              case'+':a=b+a;outwork(a);break;                                                      
  116.                                                                                                     case'-':a=b-a;outwork(a);break;
  117.                                                                                                      case'*':a=a*b;outwork(a);break;                                                                     
  118.                                                                                         case'/':a=b/a;outwork(a);break;            
  119.                                                                                                   default:break;                                                                                                                                               
  120.                                                                                     }            
  121.                                                                                     break;            
  122.                  case '+':fuhao='+';b=a;k=0;break;                                                      
  123.                  case '-':fuhao='-';b=a;k=0;break;                                                                                                                                                                                                                                                   
  124.                  case '*':fuhao='*';b=a;k=0;break;                                         
  125.                  case '/':fuhao='/';b=a;k=0;break;                                                                                                                                                                                                            
  126.                  case '0':
  127.                  case '1':
  128.                  case '2':
  129.                  case '3':
  130.                  case '4':
  131.                  case '5':                    
  132.                  case '6':                                                                                                     
  133.                  case '7':
  134.                  case '8':
  135.                  case '9':a=(flagfu-'0')+a*k*10;k=1;;  break;                             //可實現(xiàn)多位數(shù)的輸入
  136.                                                                                                                                                 
  137.                             }

  138.                
  139.                
  140.                 while(IRIN);                                                                                                                                                          //如果沒有發(fā)生中斷則一直停在這里,避免while(1)重復執(zhí)行
  141.               }                                                                                                                                                                                                                                                                                
  142. }                                                                                                                             

  143. /******************************延時函數(shù)*****************************************/
  144. void delay(uint c)
  145.   { uchar a,b;
  146.   for(a=c;a>0;a--)
  147.     for(b=110;b>0;b--);
  148. }

  149. /*******************************發(fā)聲函數(shù)****************************************/
  150. void beep()
  151. {
  152.   unsigned char i;
  153.   for (i=0;i<20;i++)
  154.    {
  155.    delay(5);
  156.    BEEP=!BEEP;                 //BEEP取反
  157.    }
  158.   BEEP=1;                      //關(guān)閉蜂鳴器
  159. }

  160. /*******************************紅外初始化函數(shù)**********************************/
  161. void IrInit()
  162. {
  163.               IT0=1;//下降沿觸發(fā)
  164.               EX0=1;//打開中斷0允許
  165.               EA=1;              //打開總中斷

  166.               IRIN=1;//初始化端口
  167. }

  168. /********************************紅外延時函數(shù)************************************/
  169. void IRdelay(unsigned char x)    //x*0.14MS
  170. {
  171. unsigned char i;
  172.   while(x--)
  173. {
  174.   for (i = 0; i<13; i++) {}
  175. }
  176. }

  177. /********************************1602寫命令函數(shù)***********************************/
  178. void writeorder(uchar order)                //寫入命令
  179. {

  180.               lcd1602rs = 0;                 //選擇發(fā)送命令
  181.     lcd1602rw = 0;                 //選擇寫入
  182.             
  183.     lin=order;    //放入命令
  184.               delay(1);                            //等待數(shù)據(jù)穩(wěn)定

  185.     lcd1602e = 1;                        //寫入時序
  186.     delay(5);                //保持時間
  187.     lcd1602e=0;
  188. }   

  189. /********************************1602寫數(shù)據(jù)函數(shù)************************************/
  190. void writedata(uchar dat)                                          //寫入數(shù)據(jù)
  191. {

  192.               lcd1602rs = 1;              //選擇輸入數(shù)據(jù)
  193.               lcd1602rw = 0;              //選擇寫入

  194.               lin = dat; //寫入數(shù)據(jù)
  195.       delay(1);

  196.               lcd1602e= 1;   //寫入時序
  197.               delay(5);   //保持時間
  198.               lcd1602e=0;
  199. }

  200. /**********************************1602初始化函數(shù)************************************/
  201. void initialize()                                                                                      //LCD初始化子程序
  202. {              lcd1602e = 0;     //使能
  203.               writeorder(0x38);  //開顯示
  204.               writeorder(0x0f);  //開顯示不顯示光標
  205.               writeorder(0x06);  //寫一個指針加1
  206.               writeorder(0x01);  //清屏
  207. }

  208. /***********************************顯示函數(shù)******************************************/
  209. void outwork(int a)
  210. {                                          
  211.               uchar i,shu[6];
  212.               uint k=0;
  213.               if(a<0)                                                                                       //若是負數(shù),顯示負號
  214.                             {writeorder(0x80+0x49);
  215.                             writedata('-');            
  216.                             a=-a;            
  217.                             }            
  218.                                                                                                                         //分離結(jié)果
  219.             shu[0]='0'+a/100000;                  //十萬
  220.                                           shu[1]='0'+a/10000%10;                            //萬
  221.                                           shu[2]='0'+a/1000%10;                  //千
  222.                                           shu[3]='0'+a/100%10;                            //百
  223.                                           shu[4]='0'+a/10%10;                      //十
  224.                                           shu[5]='0'+a%10;                      //個

  225.                             writeorder(0x80+0x4a);
  226.                             for(i=0;i<5;i++)                          //如果前面幾位為0就顯示空格
  227.                                if(shu[i]=='0')
  228.                                   shu[i]=' ';
  229.                                else
  230.                                                 break;
  231.                             for(i=0;i<6;i++)
  232.                                writedata(shu[i]);
  233. }
  234. /*              while(c!=0)
  235. {                                                                                                      //另一種思路的顯示函數(shù)
  236. write_date(0x30+c%10);
  237. c=c/10;
  238. }
  239. */



  240. /*******************************紅外中斷函數(shù)****************************************/
  241. void IR_IN(void) interrupt 0      //  進入中斷,開始處理紅外信號
  242. {
  243.                 unsigned char j,k,N=0;
  244.                 EX0 = 0;                    //進入中斷后先關(guān)掉中斷
  245.                               
  246.                 IRdelay(5);
  247.                 if (IRIN==1)                //  這里是避免干擾信號影響,如出現(xiàn)干擾信號,將會屏蔽掉
  248.                 {
  249.                                  EX0 =1;
  250.                                return;
  251.                 }
  252.                                             //確認IR信號出現(xiàn)
  253.                 while (!IRIN)               //等IR變?yōu)楦唠娖,跳過9ms的前導低電平信號。
  254.                 {
  255.                               IRdelay(1);
  256.                 }
  257. ……………………

  258. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

完整的Word格式文檔51黑下載地址:
基于單片機-的紅外簡易計算器設(shè)計1.doc (252 KB, 下載次數(shù): 67)



評分

參與人數(shù) 1黑幣 +5 收起 理由
zqy181818 + 5 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發(fā)
ID:342288 發(fā)表于 2018-6-3 18:51 | 只看該作者
你好,請問有程序和仿真圖的下載嗎?
回復

使用道具 舉報

板凳
ID:310558 發(fā)表于 2018-6-3 23:16 來自手機 | 只看該作者
試一試,謝謝分享
回復

使用道具 舉報

地板
ID:359778 發(fā)表于 2018-6-27 08:57 | 只看該作者
請問一下,有電路完整的圖嗎。
回復

使用道具 舉報

5#
ID:399282 發(fā)表于 2018-9-20 00:02 | 只看該作者
你好,我在嘗試你的程序發(fā)現(xiàn)了幾種運算均出現(xiàn)了問題
回復

使用道具 舉報

6#
ID:422073 發(fā)表于 2018-11-6 22:54 | 只看該作者
simon小白 發(fā)表于 2018-9-20 00:02
你好,我在嘗試你的程序發(fā)現(xiàn)了幾種運算均出現(xiàn)了問題

你好,你解決了嗎
回復

使用道具 舉報

7#
ID:538338 發(fā)表于 2019-5-14 21:02 | 只看該作者
哇,大神啊,學單片機正好有用呢
回復

使用道具 舉報

8#
ID:538517 發(fā)表于 2019-5-15 02:55 來自手機 | 只看該作者
我只有摩拜的份了。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表