久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1602|回復: 0
收起左側

簡易單片機計算器程序設計 LCD1602顯示

[復制鏈接]
ID:979771 發表于 2023-11-28 10:27 | 顯示全部樓層 |閱讀模式
基于51單片機的簡易計算器設計  單片機型號選擇STC89C52RC,讀取16*16矩陣式鍵盤對應的鍵值,可以進行五位數的加、減、乘、除運算,計算結果通過LCD1602顯示,并可通過AT24C02存儲模塊對計算結果進行存儲與調用。

實物演示

實物演示

單片機源程序如下:
  1. #include <reg52.h>
  2. #define        uchar unsigned char        
  3. #define        uint  unsigned int
  4. sbit rs=P2^5;        //指令or數據
  5. sbit wela=P2^6;      //讀or寫
  6. sbit lcden=P2^7;         //使能信號
  7. sbit K1 = P2^3;
  8. sbit K2 = P2^2;
  9. sbit I2C_SCL = P2^1;
  10. sbit I2C_SDA = P2^0;
  11. uchar code table[]= "                ";
  12. //uchar code XUEHAO[]= "190302051";
  13. long  int data_a,data_b;         //第一個數和第二個數
  14. long  int data_c;                        //計算結果
  15. uchar dispaly[10];         //顯示緩沖
  16. //--聲明全局變量--//
  17. void I2C_Delay10us();
  18. void I2C_Start();           //起始信號:在I2C_SCL時鐘信號在高電平期間I2C_SDA信號產生一個下降沿
  19. void I2C_Stop();            //終止信號:在I2C_SCL時鐘信號高電平期間I2C_SDA信號產生一個上升沿
  20. uchar I2C_SendByte(uchar dat, uchar ack);//使用I2c讀取一個字節
  21. uchar I2C_ReadByte();       //通過I2C發送一個字節。在I2C_SCL時鐘信號高電平期間,保持發送信號I2C_SDA保持穩定
  22. void I2C_Delay10us()
  23. {
  24.         uchar a, b;
  25.         for(b=1; b>0; b--)
  26.         {
  27.                 for(a=2; a>0; a--);
  28.         }
  29. }
  30. void I2C_Start()
  31. {
  32.         I2C_SDA = 1;
  33.         I2C_Delay10us();
  34.         I2C_SCL = 1;
  35.         I2C_Delay10us();//建立時間是I2C_SDA保持時間>4.7us
  36.         I2C_SDA = 0;
  37.         I2C_Delay10us();//保持時間是>4us
  38.         I2C_SCL = 0;                        
  39.         I2C_Delay10us();               
  40. }
  41. void I2C_Stop()
  42. {
  43.         I2C_SDA = 0;
  44.         I2C_Delay10us();
  45.         I2C_SCL = 1;
  46.         I2C_Delay10us();//建立時間大于4.7us
  47.         I2C_SDA = 1;
  48.         I2C_Delay10us();               
  49. }
  50. uchar I2C_SendByte(uchar dat, uchar ack)
  51. {
  52.         uchar a = 0,b = 0;//最大255,一個機器周期為1us,最大延時255us。                        
  53.         for(a=0; a<8; a++)//要發送8位,從最高位開始
  54.         {
  55.                 I2C_SDA = dat >> 7;         
  56.                 dat = dat << 1;
  57.                 I2C_Delay10us();
  58.                 I2C_SCL = 1;
  59.                 I2C_Delay10us();
  60.                 I2C_SCL = 0;
  61.                 I2C_Delay10us();        
  62.         }
  63.         I2C_SDA = 1;
  64.         I2C_Delay10us();
  65.         I2C_SCL = 1;
  66.         while(I2C_SDA && (ack == 1))
  67.         {
  68.                 b++;
  69.                 if(b > 200)         
  70.                 {
  71.                         I2C_SCL = 0;
  72.                         I2C_Delay10us();
  73.                         return 0;
  74.                 }
  75.         }
  76.         I2C_SCL = 0;
  77.         I2C_Delay10us();
  78.          return 1;               
  79. }

  80. uchar I2C_ReadByte()
  81. {
  82.         uchar a = 0,dat = 0;
  83.         I2C_SDA = 1;                        //起始和發送一個字節之后I2C_SCL都是0
  84.         I2C_Delay10us();
  85.         for(a=0; a<8; a++)//接收8個字節
  86.         {
  87.                 I2C_SCL = 1;
  88.                 I2C_Delay10us();
  89.                 dat <<= 1;
  90.                 dat |= I2C_SDA;
  91.                 I2C_Delay10us();
  92.                 I2C_SCL = 0;
  93.                 I2C_Delay10us();
  94.         }
  95.         return dat;               
  96. }
  97. void AT24C02Write(unsigned char addr,unsigned char dat)
  98. {
  99.         I2C_Start();
  100.         I2C_SendByte(0xa0, 1);//發送寫器件地址
  101.         I2C_SendByte(addr, 1);//發送要寫入內存地址
  102.         I2C_SendByte(dat, 0);        //發送數據
  103.         I2C_Stop();
  104. }
  105. unsigned char AT24C02Read(unsigned char addr)
  106. {
  107.         unsigned char num;
  108.         I2C_Start();
  109.         I2C_SendByte(0xa0, 1); //發送寫器件地址
  110.         I2C_SendByte(addr, 1); //發送要讀取的地址
  111.         I2C_Start();
  112.         I2C_SendByte(0xa1, 1); //發送讀器件地址
  113.         num=I2C_ReadByte(); //讀取數據
  114.         I2C_Stop();
  115.         return num;        
  116. }
  117. void LCD_Delay_us(unsigned int t)
  118. {
  119.         while(t--);           //t=0,退出
  120. }
  121. void LCD_Delay_ms(unsigned int t)
  122. {
  123.         unsigned int i,j;
  124.         for(i=0;i<t;i++)                       //執行t次循環
  125.         for(j=0;j<113;j++)                     //執行113次循環
  126.         ;
  127. }
  128. void write_com(uchar com)            //1602液晶寫指令
  129. {
  130.         rs=0;                       //寫指令
  131.         lcden=0;                    //使能1602
  132.         P0=com;                     //寫入指令com
  133.         LCD_Delay_ms(1);            //延時1ms
  134.         lcden=1;                    //使能1602
  135.         LCD_Delay_ms(2);            //延時2ms  
  136.         lcden=0;                        //使能1602
  137. }
  138. void write_date(uchar date) //1602液晶寫數據
  139. {
  140.         rs=1;                        //寫數據
  141.         lcden=0;                     //使能1602
  142.         P0=date;                     //寫入數據date
  143.         LCD_Delay_ms(1);             //延時1ms
  144.         lcden=1;                     //使能1602
  145.         LCD_Delay_ms(2);             //延時2ms
  146.         lcden=0;                         //使能1602
  147. }
  148. void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
  149. {     
  150.          if (y == 0){write_com(0x80 + x);}   //第一行  
  151.          else{write_com(0xc0 + x);}          //第二行
  152.          write_date( Data);                  //寫入數據
  153. }
  154. //指定x,y寫入字符串函數
  155. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  156. {     
  157. if (y == 0){write_com(0x80 + x);}                 //第一行
  158. else{write_com(0xC0 + x);}                        //第二行
  159. while (*s)                                        //
  160.          {write_date( *s); s++;}                      //寫入數據
  161. }

  162. void init_lcd(void)            //初始化液晶,及畫面初始化
  163. {
  164.         wela=0;                      //寫液晶
  165.         lcden=0;                     //使能1602
  166.         write_com(0x38);             //8 位總線,雙行顯示,5X7 的點陣字符
  167.         LCD_Delay_us(100);           //延時100us
  168.         write_com(0x0c);             //開顯示,無光標,光標不閃爍
  169.         write_com(0x06);             //光標右移動
  170.         write_com(0x01);             //清屏
  171.         write_com(0x80);             //DDRAM 地址歸0
  172. }
  173. short keycheckdown()                                /* 反轉法鍵盤掃描 */
  174. {

  175.         short temp1,temp2,temp,a=0xff;
  176.         P1=0xf0;                                                /* 輸入行值(或列值) */
  177.         LCD_Delay_ms(20);                                /* 延時 */
  178.         temp1=P1;                                                /* 讀列值(或行值) */
  179.         P1=0xff;
  180.         LCD_Delay_ms(20);                                /* 延時 */
  181.         P1=0x0f;                                                /* 輸入列值(或行值) */
  182.         LCD_Delay_ms(20);                                /* 延時 */        
  183.         temp2=P1;                                                /* 讀行值(或列值) */
  184.         P1=0xff;
  185.         temp=(temp1&0xf0)|(temp2&0xf);        /* 將兩次讀入數據組合 */
  186.         switch(temp)                                        /* 通過讀入數據組合判斷按鍵位置 */
  187.         {


  188.                 case 0x77 :a=0x0d;break;//  按鍵/   
  189.                 case 0x7b :a=0x0e; break;// 按鍵=        
  190.                 case 0x7d :a=0;           break;// 按鍵0
  191.                 case 0x7e :a=0x0f; break;// 按鍵CE

  192.                 case 0xb7 :a=0x0c;break;//         按鍵*
  193.                 case 0xbb :a=0x9;break; //  按鍵9
  194.                 case 0xbd :a=0x8;break; //  按鍵8
  195.                 case 0xbe :a=0x7;break; //         按鍵7

  196.                 case 0xd7 :a=0x0b;break;//  按鍵-
  197.                 case 0xdb :a=0x6;break; //         按鍵6
  198.                 case 0xdd :a=0x5;break; //         按鍵5
  199.                 case 0xde :a=0x4;break; //         按鍵4

  200.                 case 0xe7 :a=0x0a; break;// 按鍵+
  201.                 case 0xeb :a=3;break;        //  按鍵3
  202.                 case 0xed :a=2;break;        //  按鍵2
  203.                 case 0xee :a=1;break;        //  按鍵1

  204.                 default :a=0xff;
  205.         }
  206.         return a;                                                /* 返回按鍵值 */
  207. }
  208. void display_a() //顯示數據a
  209. {
  210.         dispaly[4]=data_a%100000/10000;
  211.         dispaly[3]=data_a%10000/1000;    //千
  212.         dispaly[2]=data_a%1000/100;      //百
  213.         dispaly[1]=data_a%100/10;        //十
  214.         dispaly[0]=data_a%10;            //個

  215.         write_com(0x80+0);               //顯示數據a
  216.         if(data_a>9999){        write_date('0'+dispaly[4]); }
  217.         if(data_a>999){        write_date('0'+dispaly[3]);}      //顯示千位
  218.         if(data_a>99){        write_date('0'+dispaly[2]);}                 //顯示百位
  219.         if(data_a>9){        write_date('0'+dispaly[1]);}     //顯示十位
  220.                               write_date('0'+dispaly[0]);      //顯示個位
  221. }

  222. void display_b() //顯示數據b
  223. {
  224.         write_com(0x80+7); //第一行
  225.         dispaly[4]=data_b%100000/10000;
  226.         dispaly[3]=data_b%10000/1000;    //千
  227.         dispaly[2]=data_b%1000/100;      //百
  228.         dispaly[1]=data_b%100/10;        //十
  229.         dispaly[0]=data_b%10;            //個
  230. if(data_b>9999){        write_date('0'+dispaly[4]); }
  231. if(data_b>999){        write_date('0'+dispaly[3]); }     //顯示千位   
  232. if(data_b>99) {        write_date('0'+dispaly[2]); }    //顯示百位  
  233. if(data_b>9)  {        write_date('0'+dispaly[1]); }     //顯示十位
  234.                               write_date('0'+dispaly[0]);      //顯示個位
  235. }
  236. void display_c(x)
  237. {

  238.         if(data_c<100000000&&data_c>-1)//溢出時顯示錯誤
  239.         {        

  240.                 dispaly[8]=data_c%1000000000/100000000;            //萬萬
  241.                 dispaly[7]=data_c%100000000/10000000;            //千萬
  242.                 dispaly[6]=data_c%10000000/1000000;                    //百萬
  243.                 dispaly[5]=data_c%1000000/100000;                    //十萬
  244.                 dispaly[4]=data_c%100000/10000;                            //萬
  245.                 dispaly[3]=data_c%10000/1000;                            //千
  246.                 dispaly[2]=data_c%1000/100;                              //百
  247.                 dispaly[1]=data_c%100/10;                                //十
  248.                 dispaly[0]=data_c%10;                                    //個
  249.                 write_com(0x80+6+0x40); //第一行
  250.                 if(x==4)
  251.                 {   
  252.                 if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  253.                 if(data_c>9999999)        {        write_date('0'+dispaly[7]);}   //千萬
  254.                 if(data_c>999999)        {        write_date('0'+dispaly[6]);}    //百萬
  255.                 if(data_c>99999)        {        write_date('0'+dispaly[5]);}    //十萬
  256.                                                                 write_date('0'+dispaly[4]);    //萬
  257.                                                                 write_date('.');
  258.                                                                 write_date('0'+dispaly[3]);    //千
  259.                                                                 write_date('0'+dispaly[2]);    //百
  260.                                                                 write_date('0'+dispaly[1]);    //十
  261.                                                                 write_date('0'+dispaly[0]);    //個
  262.                 }
  263.         else{
  264.                 if(data_c>99999999)        {        write_date('0'+dispaly[8]);}    //顯示萬萬
  265.                 if(data_c>9999999)        {        write_date('0'+dispaly[7]);}    //千萬
  266.                 if(data_c>999999)                {        write_date('0'+dispaly[6]);}    //百萬
  267.                 if(data_c>99999)                {        write_date('0'+dispaly[5]);}    //十萬
  268.                 if(data_c>9999)                        {        write_date('0'+dispaly[4]);}    //萬
  269.                 if(data_c>999)                        {        write_date('0'+dispaly[3]);}    //千
  270.                 if(data_c>99)                                {        write_date('0'+dispaly[2]);}    //百
  271.                 if(data_c>9)                                {        write_date('0'+dispaly[1]);}    //十
  272.                                                                                                         write_date('0'+dispaly[0]);    //個
  273.                 }
  274.         }
  275.         else  //溢出時顯示錯誤
  276.         {
  277.                 write_com(0x80+11+0x40); //第一行
  278.                 write_date('E');         //顯示 E
  279.                 write_date('r');         //顯示R
  280.                 write_date('r');                 //顯示R
  281.                 write_date('o');                 //顯示O
  282.                 write_date('r');                 //顯示E
  283.         }
  284. }

復制代碼

原理圖: 無
仿真: 無
代碼: 程序代碼.7z (34.48 KB, 下載次數: 11)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费在线黄 | 成年人免费在线视频 | 免费人成在线观看网站 | 成人一级黄色毛片 | 国产欧美精品一区二区色综合朱莉 | 欧美成年人视频在线观看 | 鸡毛片 | www.国产一区 | 欧美成人免费在线视频 | 国产伦精品一区二区三区精品视频 | 成人精品啪啪欧美成 | 国产成人免费视频 | 韩日三级| 狠狠久久久 | 天堂一区在线观看 | 日韩av中文 | 中文字幕亚洲区一区二 | 久久一级免费视频 | 国产精品久久影院 | 欧美αv | 国产高清视频 | 日日操夜夜操天天操 | 国产免费看 | 午夜一区| 国产一区二区三区四区区 | 国产精品一区二区久久 | 亚洲巨乳自拍在线视频 | 北条麻妃视频在线观看 | 在线观看免费av片 | 国产999精品久久久 精品三级在线观看 | 欧美精品一区二区三区蜜桃视频 | 在线观看视频亚洲 | 国产精品国产成人国产三级 | 羞羞色在线观看 | 免费h视频 | 拍真实国产伦偷精品 | 午夜小视频在线播放 | 激情网站在线观看 | 午夜精品一区二区三区免费视频 | 国产欧美视频一区二区 | 日韩国产欧美在线观看 |