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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9351|回復: 4
打印 上一主題 下一主題
收起左側

51單片機計件寫入AT24C02存儲芯片源程序與proteus仿真

[復制鏈接]
跳轉到指定樓層
樓主
51單片機計件仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>  //包含_nop_()函數定義的頭文件
  3. sbit RS=P1^0;  //寄存器選擇位,將RS位定義為P2.0引腳
  4. sbit RW=P1^1;  //寫讀選擇位,將RW位定義為P2.1引腳
  5. sbit E=P1^2;   //使能信號位,將E位定義為P2.2引腳
  6. sbit BF=P0^7;  //忙碌標志位,將BF位定義為P0.7引腳
  7. sbit S=P3^7;   //將S位定義為P3.7引腳
  8. #define OP_READ 0xa1  //器件地址以及讀寫操作,0xa1即為1010 0001B
  9. #define OP_WRITE 0xa0 //器件地址以及寫入操作,0xa1即為1010 0001B
  10. sbit SDA=P3^4;  //將串行數據總線SDA位定義在為P3.4引腳
  11. sbit SCL=P3^3;  //將串行時鐘總線SCL位定義在為P3.3引腳
  12. unsigned char code digit[]={"0123456789"};  //定義字符數組顯示數字
  13. void delay1ms()  //延時1ms
  14. {
  15.         unsigned char i,j;
  16.         for(i=0;i<10;i++)
  17.         for(j=0;j<33;j++)
  18.         ;
  19. }
  20. void delaynms(unsigned char n)  //延時若干毫秒,入口參數:n
  21. {
  22.         unsigned char i;
  23.         for(i=0;i<n;i++)
  24.         delay1ms();
  25. }
  26. unsigned char BusyTest(void)  //判斷液晶模塊的忙碌狀態,返回值result。result=1,忙碌。result=0,不忙。
  27. {
  28.         bit result;
  29.         RS=0;  //根據規定,RS為低電平,RW為高電平?可以讀狀態
  30.         RW=1;
  31.         E=1;   //E=1才允許讀寫
  32.         _nop_();
  33.         _nop_();
  34.         _nop_();
  35.         _nop_();  //空操作四個周期
  36.         result=BF;  //將忙碌標志電平賦給result
  37.         E=0;  //將E恢復低電平
  38.         return result;
  39. }
  40. void WriteInstruction(unsigned char dictate)  //將模式設置指令或顯示地址寫入液晶模塊
  41. {
  42.         while(BusyTest()==1);  //如果忙就等待
  43.         RS=0;  //根據規定,RS和RW同時為低電平時,可以寫入指令
  44.         RW=0;  //
  45.         E=0;   //E置低電平(根據表8-6,寫指令時,E為高脈沖,讓E從0到1發生正跳變,所以應先置“0”
  46.         _nop_();
  47.         _nop_();  //空操作兩個機器周期
  48.         P0=dictate;  //將數據送入P0口,即寫入指令或地址
  49.         _nop_();
  50.         _nop_();
  51.         _nop_();
  52.         _nop_();  //空操作四個機器周期
  53.         E=1;  //E置高電平
  54.         _nop_();
  55.         _nop_();
  56.         _nop_();
  57.         _nop_();  //空操作四個機器周期
  58.         E=0;  //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  59. }
  60. void WriteAddress(unsigned char x)  //指定字符顯示的實際地址,入口參數:x
  61. {
  62.         WriteInstruction(x|0x80);  //顯示位置的方法規定為“80H+地址碼x”
  63. }
  64. void WriteData(unsigned char y)  //將數據(字符的標準ASCLL碼)寫入液晶模塊,入口參數:y
  65. {
  66.         while(BusyTest()==1);
  67.         RS=1;  //RS為高電平,RW為低電平,可以寫入數據
  68.         RW=0;
  69.         E=0;   //E置低電平(根據表8-6,寫指令時,E為高脈沖,就是讓E從0到1發生正跳變,所以應先置”0“
  70.         P0=y;  //將數據送入P0口,即將數據寫入液晶模塊
  71.         _nop_();
  72.         _nop_();
  73.         _nop_();
  74.         _nop_();  //空操作四個機器周期
  75.         E=1;  //E置高電平
  76.         _nop_();
  77.         _nop_();
  78.         _nop_();
  79.         _nop_();  //空操作四個機器周期
  80.         E=0;  //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  81. }
  82. void LcdInitiate(void)  //對LCD的顯示模式進行初始化設置
  83. {
  84.         delaynms(15);  //延時15ms,首次寫指令時應給LCD一段較長的反應時間
  85.         WriteInstruction(0x38);  //顯示模式設置:16x2顯示,5x7點陣,8位數據接口
  86.         delaynms(5);  //延時5ms,給硬件一點反應時間
  87.         WriteInstruction(0x38);  //
  88.         delaynms(5);
  89.         WriteInstruction(0x38);  //連續三次,確保初始化成功
  90.         delaynms(5);
  91.         WriteInstruction(0x0c);  //顯示模式設置:顯示開,無光標,光標不閃爍
  92.         delaynms(5);
  93.         WriteInstruction(0x06);  //顯示模式設置:光標右移,字符不移
  94.         delaynms(5);
  95.         WriteInstruction(0x01);  //清屏幕指令,將以前的顯示內容清除
  96.         delaynms(5);
  97. }
  98. void Display(unsigned char x)  //顯示小時
  99. {
  100.         unsigned char i,j;
  101.         i=x/10;  //取整運算,求得十位數字
  102.         j=x%10;  //取余運算,求得個位數字
  103.         WriteAddress(0x44);  //寫顯示地址,將十位數字顯示在第2行第5列
  104.         WriteData(digit[i]);  //將十位數字的字符常量寫入LCD
  105.         WriteData(digit[j]);  //將個位數字的字符常量寫入LCD
  106. }
  107. void start()  //開始數據傳送,開始位
  108. {
  109.         SDA=1;  //SDA初始化為高電平“1”
  110.         SCL=1;  //開始數據傳送時,要求SCL為高電平“1”
  111.         _nop_();
  112.         _nop_();  //空操作兩個機器周期
  113.         SDA=0;  //SDA的下降沿被認為是開始信號
  114.         _nop_();
  115.         _nop_();
  116.         _nop_();
  117.         _nop_();  //空操作四個機器周期
  118.         SCL=0;  //SCL為低電平時,SDA上數據才允許變化(即允許以后的數據傳遞)
  119. }
  120. void stop()  //結束數據傳遞
  121. {
  122.         SDA=0;  //SDA初始化為低電平“0”
  123.         _nop_();
  124.         _nop_();  //空操作兩個機器周期
  125.         SCL=1;  //結束數據傳送時,要求SCL為高電平“1”
  126.         _nop_();
  127.         _nop_();
  128.         _nop_();
  129.         _nop_();  //空操作四個機器周期
  130.         SDA=1;  //SDA的上升沿被認為是結束信號
  131. }
  132. unsigned char ReadData()  //從AT24Cxx讀取數據,出口參數x,從AT24Cxx移入數據到MCU
  133. {
  134.         unsigned char i;
  135.         unsigned char x;  //存儲從AT24Cxx中讀出的數據
  136.         for(i=0;i<8;i++)
  137.         {
  138.                 SCL=1;  //SCL置為高電平
  139.                 x<<=1;  //將x中的各二進位向左移一位
  140.                 x|=(unsigned char)SDA;  //將SDA上的數據通過按位“或”運算存入x中
  141.                 SCL=0;  //在SCL的下降沿讀出數據
  142.         }
  143.         return(x);  //將讀取的數據返還
  144. }
  145. bit WriteCurrent(unsigned char y)  //向AT23Cxx的當前地址寫入數據,入口參數y(存儲待寫入的數據),在調用此數據寫入函數前需首先調用開始start(),所以SCL=0
  146. {
  147.         unsigned char i;
  148.         bit ack_bit;  //存儲應答位
  149.         for(i=0;i<8;i++)  //循環移入8個位
  150.         {
  151.                 SDA=(bit)(y&0x80);  //通過按位“與”運算將最高位數據送到S,因為傳送時高位在前,低位在后
  152.                 _nop_();  //空操作一個機器周期
  153.                 SCL=1;  //在SCL的上升沿將數據寫入AT24Cxx
  154.                 _nop_();
  155.                 _nop_();  //空操作兩個機器周期
  156.                 SCL=0;  //將SCL重新置為低電平,以在SCL線形成傳送數據所需的8個脈沖
  157.                 y<<=1;  //將y中的各二進位向左移一位
  158.         }
  159.         SDA=1;  //發送設備(主機)應在時鐘脈沖的高電平期間(SCL=1)釋放SDA線,以讓SDA線轉由接收設備(AT24Cxx)控制
  160.         _nop_();
  161.         _nop_();  //空操作兩個機器周期
  162.         SCL=1;  //根據上述規定,SCL應為高電平
  163.         _nop_();
  164.         _nop_();
  165.         _nop_();
  166.         _nop_();;  //空操作四個機器周期
  167.         ack_bit=SDA;  //接收設備(AT24Cxx)向SDA送低電平,表示已經接收到一個字節,若送高電平,表示沒有收到,傳送異常
  168.         SCL=0;  //SCL為低電平時,SDA上數據才允許變化(即允許以后的數據傳遞)
  169.         return  ack_bit;  //返回AT24Cxx答應位
  170. }
  171. void WriteSet(unsigned char add,unsigned char dat)  //向AT24Cxx中的指定地址寫入數據,存儲地址add,存儲待寫入數據dat
  172. //在指定地址add處寫入數據WriteCurrent
  173. {
  174.         start();  //開始數據傳遞
  175.         WriteCurrent(OP_WRITE);  //選擇要操作的AT24Cxx芯片,并告知要對其寫入數據
  176.         WriteCurrent(add);  //寫入指定地址
  177.         WriteCurrent(dat);  //向當前地址(上面指定的地址)寫入數據
  178.         stop();  //停止數據傳遞
  179.         delaynms(4);  //一字節的寫入周期為1ms,最好延時1ms以上
  180. }
  181. unsigned char ReadCurrent()  //從AT24Cxx中的當前地址讀取數據,出口參數x
  182. {
  183.         unsigned char x;
  184.         start();  //開始數據傳遞
  185.         WriteCurrent(OP_READ);  //選擇要操作的AT24Cxx芯片,并告知要讀取其數據
  186.         x=ReadData();  //將讀取的數據存入x
  187.         stop();  //停止數據傳遞
  188.         return x;  //返回讀取的數據
  189. }
  190. unsigned char ReadSet(unsigned char set_add)  //從AT24Cxx中的指定地址讀取數據,入口set_add,出口x
  191. //在指定地址讀取
  192. {
  193.         start();  //開始數據傳遞
  194.         WriteCurrent(OP_WRITE);  //選擇要操作的AT24Cxx芯片,并告知要對其寫入數據
  195.         WriteCurrent(set_add);  //寫入指定地址
  196.         return(ReadCurrent());  //從指定地址讀出數據并返回
  197. }
  198. void main(void)
  199. {
  200.         unsigned char sum;  //存儲計算值
  201.         unsigned char x;  //存儲從AT24Cxx讀出的值
  202.         LcdInitiate();  //調用LCD初始化函數
  203.         sum=0;  //將計算值初始化為0
  204.         while(1)  //無限循環
  205.         {
  206.                 if(S==0)  //如果該建被按下
  207.                 {
  208.                         delaynms(80);  //軟件消抖,延時80ms
  209.                         if(S==0)  //確實該建被按下
  210.                         sum++;  //計算值加1
  211.                         if(sum==99)  //如果計滿99
  212.                                 sum=0;  //清0,重新開始計數
  213.                 }
  214.                 WriteSet(0x01,sum);  //將計件值寫入AT24C02中的指定地址“0x01”
  215.                 x=ReadSet(0x01);  //從AT24C02中讀出計件值
  216.                 Display(x);  //將計件值用1602LCD顯示
  217.         }
  218. }
復制代碼

改了一下引腳在開發板上運行 目前仿真的液晶屏無法顯示了,大家自行修改一下吧.所有資料51hei附件下載:
ex69.zip (75.04 KB, 下載次數: 169)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

來自 2#
ID:328014 發表于 2021-7-20 04:43 | 只看該作者
我把引腳給修改好了一下,可以顯示了,大家看看還有什么問題?我覺得還需要加個手工復位開關吧,這樣手動讓單片機重啟,而at24c02的數據會保持

51hei.png (10.73 KB, 下載次數: 34)

51hei.png

我修改后的.7z

33.1 KB, 下載次數: 25, 下載積分: 黑幣 -5

回復

使用道具 舉報

板凳
ID:184706 發表于 2019-1-19 08:42 | 只看該作者
哥們 這個液晶屏 毫無反應啊
回復

使用道具 舉報

地板
ID:529488 發表于 2019-7-29 23:49 | 只看該作者
mtk1625 發表于 2019-1-19 08:42
哥們 這個液晶屏 毫無反應啊

他程序里面的引腳與接線圖沒對應上你仔細看下
回復

使用道具 舉報

5#
ID:945970 發表于 2021-6-28 12:42 | 只看該作者
mtk1625 發表于 2019-1-19 08:42
哥們 這個液晶屏 毫無反應啊

我的也沒有反應
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 黄a在线观看 | h小视频| 日韩91在线 | 国产高清不卡 | 国产欧美精品一区二区 | 亚洲成人午夜在线 | 天天草夜夜骑 | jlzzjlzz欧美大全 | 中文字幕免费 | www.日韩免费 | 国产午夜av片 | 午夜精品一区二区三区免费视频 | 岛国在线免费观看 | 欧美另类视频 | 毛片a级| 亚洲一区二区高清 | 亚洲视频免费在线看 | 天堂在线中文字幕 | 国产精品久久久久久久久久久久久久 | 91久久精品一区二区二区 | 欧美不卡 | 国产精品视频一 | 日韩午夜一区二区三区 | www日日日 | 亚洲播放一区 | 黑人粗黑大躁护士 | 欧美一级在线观看 | 一区二区在线免费观看视频 | 亚洲成人精品久久 | 国产精品99久久久久久动医院 | 精品在线播放 | 91看片视频 | 在线中文字幕日韩 | 精品视频99 | 欧美一级免费看 | 精品国产欧美一区二区 | 精品久久不卡 | 久久精品网 | 国产精品特级片 | 亚洲一区二区三区免费在线观看 | 超级黄色一级片 |