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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4255|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

一種簡易單片機計數(shù)器程序Proteus仿真 帶詳細(xì)注釋

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:825202 發(fā)表于 2021-3-8 20:01 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
計數(shù)器仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include <reg52.h>                        // 包含頭文件
  2. #include <intrins.h>

  3. #define uchar unsigned char                // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int                // 以后unsigned int 就可以用uint 代替

  5. sfr ISP_DATA  = 0xe2;                        // 數(shù)據(jù)寄存器
  6. sfr ISP_ADDRH = 0xe3;                        // 地址寄存器高八位
  7. sfr ISP_ADDRL = 0xe4;                        // 地址寄存器低八位
  8. sfr ISP_CMD   = 0xe5;                        // 命令寄存器
  9. sfr ISP_TRIG  = 0xe6;                        // 命令觸發(fā)寄存器
  10. sfr ISP_CONTR = 0xe7;                        // 命令寄存器

  11. sbit w1      = P2^4;                         // 數(shù)碼管第1位的控制引腳
  12. sbit w2      = P2^5;                        // 數(shù)碼管第2位的控制引腳
  13. sbit w3      = P2^6;                        // 數(shù)碼管第3位的控制引腳
  14. sbit w4      = P2^7;                        // 數(shù)碼管第4位的控制引腳
  15. sbit Red     = P1^0;                        // 紅外模塊
  16. sbit Led     = P1^1;                        // LED燈
  17. sbit Buzzer  = P2^3;                        // 蜂鳴器引腳
  18. sbit KeySet  = P3^2;                        // 設(shè)置按鍵
  19. sbit KeyDown = P3^3;                        // 減按鍵
  20. sbit KeyUp   = P3^4;                        // 加按鍵


  21. /*   數(shù)碼管的顯示值:  0    1    2    3    4    5     6   7    8    9    -       */
  22. uchar code Array1[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00 };

  23. uchar Buff[4];                                        // 顯示緩沖區(qū)
  24. uchar ShowID=1;                                        // 當(dāng)前顯示的是哪一個數(shù)碼管

  25. int gAlarm;                                                        // 報警值
  26. int gCount=0;                                                // 計數(shù)值


  27. /*********************************************************/
  28. // 單片機內(nèi)部EEPROM不使能
  29. /*********************************************************/
  30. void ISP_Disable()
  31. {
  32.         ISP_CONTR = 0;
  33.         ISP_ADDRH = 0;
  34.         ISP_ADDRL = 0;
  35. }


  36. /*********************************************************/
  37. // 從單片機內(nèi)部EEPROM讀一個字節(jié),從0x2000地址開始
  38. /*********************************************************/
  39. unsigned char EEPROM_Read(unsigned int add)
  40. {
  41.         ISP_DATA  = 0x00;
  42.         ISP_CONTR = 0x83;
  43.         ISP_CMD   = 0x01;
  44.         ISP_ADDRH = (unsigned char)(add>>8);
  45.         ISP_ADDRL = (unsigned char)(add&0xff);
  46.         // 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
  47.         ISP_TRIG  = 0x46;           
  48.         ISP_TRIG  = 0xB9;
  49.         _nop_();
  50.         ISP_Disable();
  51.         return (ISP_DATA);
  52. }


  53. /*********************************************************/
  54. // 往單片機內(nèi)部EEPROM寫一個字節(jié),從0x2000地址開始
  55. /*********************************************************/
  56. void EEPROM_Write(unsigned int add,unsigned char ch)
  57. {
  58.         ISP_CONTR = 0x83;
  59.         ISP_CMD   = 0x02;
  60.         ISP_ADDRH = (unsigned char)(add>>8);
  61.         ISP_ADDRL = (unsigned char)(add&0xff);
  62.         ISP_DATA  = ch;
  63.         ISP_TRIG  = 0x46;
  64.         ISP_TRIG  = 0xB9;
  65.         _nop_();
  66.         ISP_Disable();
  67. }


  68. /*********************************************************/
  69. // 擦除單片機內(nèi)部EEPROM的一個扇區(qū)
  70. // 寫8個扇區(qū)中隨便一個的地址,便擦除該扇區(qū),寫入前要先擦除
  71. /*********************************************************/
  72. void Sector_Erase(unsigned int add)         
  73. {
  74.         ISP_CONTR = 0x83;
  75.         ISP_CMD   = 0x03;
  76.         ISP_ADDRH = (unsigned char)(add>>8);
  77.         ISP_ADDRL = (unsigned char)(add&0xff);
  78.         ISP_TRIG  = 0x46;
  79.         ISP_TRIG  = 0xB9;
  80.         _nop_();
  81.         ISP_Disable();
  82. }


  83. /*********************************************************/
  84. // 毫秒級的延時函數(shù),time是要延時的毫秒數(shù)
  85. /*********************************************************/
  86. void DelayMs(uint time)
  87. {
  88.         uint i,j;
  89.         for(i=0;i<time;i++)
  90.                 for(j=0;j<112;j++);
  91. }


  92. /*********************************************************/
  93. // 定時器初始化
  94. /*********************************************************/
  95. void TimerInit()
  96. {
  97.         TMOD = 0x01;                                        // 使用定時器0,工作方式1         
  98.         TH0  = 248;                                                // 給定時器0的TH0裝初值
  99.         TL0  = 48;                                                // 給定時器0的TL0裝初值
  100.         ET0  = 1;                                                        // 定時器0中斷使能
  101.         EA   = 1;                                                        // 打開總中斷
  102.         TR0         = 1;                                                        // 啟動定時器0
  103. }


  104. /*********************************************************/
  105. // 顯示數(shù)字
  106. /*********************************************************/
  107. void ShowNum(int dat)
  108. {
  109.         Buff[1]=Array1[dat/100];                        // 顯示百位
  110.         Buff[2]=Array1[dat%100/10];                // 顯示十位
  111.         Buff[3]=Array1[dat%10];                                // 顯示個位
  112. }


  113. /*********************************************************/
  114. // 報警判斷
  115. /*********************************************************/
  116. void AlarmJudge()
  117. {
  118.         if(gCount>gAlarm)                        // 計數(shù)值大于報警值
  119.         {
  120.                 Led=0;                                                        // 點亮LED
  121.                 Buzzer=0;                                                // 啟動蜂鳴器
  122.         }
  123.         else                                                        
  124.         {
  125.                 Led=1;                                                        // 關(guān)閉LED
  126.                 Buzzer=1;                                                // 關(guān)閉蜂鳴器
  127.         }
  128. }


  129. /*********************************************************/
  130. // 按鍵掃描
  131. /*********************************************************/
  132. void KeyScanf()
  133. {
  134.         if(KeySet==0)                                                                // 如果設(shè)置按鍵被按下
  135.         {
  136.                 Buff[0]=Array1[10];                                // 數(shù)碼管第一位顯示“-”,表示當(dāng)前顯示的是報警值
  137.                 ShowNum(gAlarm);                                        // 顯示報警值
  138.                 DelayMs(10);                                                        // 延時去抖
  139.                 while(!KeySet);                                                // 等待按鍵釋放
  140.                 DelayMs(10);                                                        // 延時去抖
  141.                
  142.                 while(1)
  143.                 {
  144.                         if(KeyDown==0)                                        // 如果“減”按鍵被按下
  145.                         {
  146.                                 if(gAlarm>1)                                        // 判斷當(dāng)前報警值是否大于1
  147.                                 {
  148.                                         gAlarm--;                                                // 報警值減1
  149.                                         ShowNum(gAlarm);                // 刷新顯示改變后的報警值
  150.                                         DelayMs(200);                                // 延時
  151.                                 }
  152.                         }
  153.                         
  154.                         if(KeyUp==0)                                                // 如果“加”按鍵被按下                                       
  155.                         {
  156.                                 if(gAlarm<999)                                // 判斷當(dāng)前報警值是否小于999
  157.                                 {
  158.                                         gAlarm++;                                                // 報警值減1
  159.                                         ShowNum(gAlarm);                // 刷新顯示改變后的報警值
  160.                                         DelayMs(200);                                // 延時
  161.                                 }
  162.                         }
  163.                         
  164.                         if(KeySet==0)                                                // 如果“設(shè)置”按鍵被按下
  165.                         {
  166.                                 break;                                                                // 退出報警值設(shè)置,回到測量界面
  167.                         }
  168.                 }
  169.                
  170.                 /* 退出設(shè)置模式 */
  171.                 Buff[0]=Array1[11];                                // 數(shù)碼管第一位顯示“ ”,表示當(dāng)前顯示的是測量值
  172.                 ShowNum(gCount);                                        // 顯示報警值
  173.                 DelayMs(10);                                                        // 延時去抖
  174.                 while(!KeySet);                                                // 等待按鍵釋放
  175.                 DelayMs(10);                                                        // 延時去抖
  176.                
  177.                 Sector_Erase(0x2000);                                                        // 保存報警距離
  178.                 EEPROM_Write(0x2000,gAlarm/100);
  179.                 EEPROM_Write(0x2001,gAlarm%100);
  180.         }
  181. }


  182. /*********************************************************/
  183. // 報警值初始化
  184. /*********************************************************/
  185. void AlarmInit()
  186. {
  187.         gAlarm=EEPROM_Read(0x2000)*100+EEPROM_Read(0x2001);                // 從EEPROM讀取報警值

  188.         if((gAlarm==0)||(gAlarm>999))                        // 如果讀取到的報警值異常(等于0或大于999則認(rèn)為異常)
  189.         {
  190.                 gAlarm=25;                                                                                        // 重新賦值報警值為25
  191.         }
  192. }


  193. /*********************************************************/
  194. // 主函數(shù)
  195. /*********************************************************/
  196. void main()
  197. {
  198.         TimerInit();                                                        // 定時器0的初始化(數(shù)碼管的動態(tài)掃描)
  199.         AlarmInit();                                                        // 報警值初始化
  200.         
  201.         Buff[0]=Array1[11];                                // 剛上電顯示" 000"
  202.         Buff[1]=Array1[0];
  203.         Buff[2]=Array1[0];
  204.         Buff[3]=Array1[0];
  205.         
  206.         while(1)
  207.         {
  208.                 if(Red==0)                                                        // 如果紅外模塊檢測到有障礙物
  209.                 {
  210.                         if(gCount<999)                                // 判斷當(dāng)前計數(shù)是否小于999
  211.                         {
  212.                                 gCount++;                                                // 計數(shù)加1
  213.                                 ShowNum(gCount);                // 刷新顯示
  214.                         }
  215.                         Buzzer=0;                                                        // 蜂鳴器嘀一聲
  216.                         DelayMs(50);
  217.                         Buzzer=1;
  218.                         while(!Red);                                        // 等待障礙物離開傳感器檢測范圍
  219.                         DelayMs(100);
  220.                 }

  221.                 AlarmJudge();                                                // 判斷是否需要報警
  222.                
  223.                 KeyScanf();                                                        // 按鍵掃描                                                        
  224.         }
  225. }


  226. /*********************************************************/
  227. // 定時器0服務(wù)程序
  228. /*********************************************************/
  229. void Timer0(void) interrupt 1
  230. {
  231.         TH0  = 248;                                // 給定時器0的TH0裝初值
  232.         TL0  = 48;                                // 給定時器0的TL0裝初值

  233.         P0=0x00;                                        // 先關(guān)閉所有顯示
  234.         w1=1;
  235.         w2=1;
  236.         w3=1;
  237.         w4=1;

  238.         if(ShowID==1)                          // 判斷是否顯示第1位數(shù)碼管
  239.         {
  240.                 w1=0;                                                   // 打開第1位數(shù)碼管的控制開關(guān)
  241.                 P0=Buff[0];                           // 第1位數(shù)碼管顯示內(nèi)容        
  242.         }
  243.         
  244.         if(ShowID==2)                          // 判斷是否顯示第2位數(shù)碼管
  245.         {
  246.                 w2=0;                                                   // 打開第2位數(shù)碼管的控制開關(guān)
  247.                 P0=Buff[1];                           // 第2位數(shù)碼管顯示內(nèi)容        
  248.         }
  249.         
  250.         if(ShowID==3)                          // 判斷是否顯示第3位數(shù)碼管
  251.         {
  252.                 w3=0;                                                   // 打開第3位數(shù)碼管的控制開關(guān)
  253.                 P0=Buff[2];                           // 第3位數(shù)碼管顯示內(nèi)容        
  254.         }
  255.         
  256.         if(ShowID==4)                          // 判斷是否顯示第4位數(shù)碼管
  257.         {
  258.                 w4=0;                                                   // 打開第4位數(shù)碼管的控制開關(guān)
  259.                 P0=Buff[3];                           // 第4位數(shù)碼管顯示內(nèi)容        
  260.         }        
  261.         
  262.         ShowID++;                                          // 切換到下一個數(shù)碼管的顯示
  263.         if(ShowID==5)
  264.                 ShowID=1;
  265. }
復(fù)制代碼

所有資料51hei提供下載:
計數(shù)器.zip (142.71 KB, 下載次數(shù): 46)


評分

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

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:197229 發(fā)表于 2021-3-31 05:29 | 只看該作者
謝謝樓主,下載了仿真例程和程序,正常運行我是做了一點兒小小的改動,在輸出輸入處,算是狗尾續(xù)貂了,覺得很有用。

調(diào)整大小 jsq.jpg (138.61 KB, 下載次數(shù): 140)

調(diào)整大小 jsq.jpg
回復(fù)

使用道具 舉報

板凳
ID:820198 發(fā)表于 2021-3-31 09:22 | 只看該作者
不錯啊,很清晰的程序
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美日韩系列 | 狠狠干网站 | 91.xxx.高清在线 | 国内自拍视频在线观看 | 日本亚洲欧美 | 2019天天操| 久草网址 | 久久久高清 | 久久一级| 国产成人高清 | 日日操夜夜操天天操 | 国产成人在线一区二区 | 日本不卡一区 | 精品一二 | 91精品国产一区二区三区 | 欧美在线视频网站 | 亚洲成a | 久久精品一 | 国产高清免费视频 | 青青草免费在线视频 | 日韩欧美网 | 日产久久 | 久草热播| 亚洲 自拍 另类 欧美 丝袜 | 午夜欧美 | 色爱av| 欧美在线国产精品 | 欧美日韩综合一区 | 九一在线观看 | 99re热精品视频国产免费 | 国产精品自产av一区二区三区 | 一区二区免费在线观看 | 一级全黄视频 | 国产精品99久久久久 | 精品免费看 | 免费中文字幕 | 全免一级毛片 | 欧美电影大全 | 免费看国产一级特黄aaaa大片 | 午夜免费网站 | 国产精品福利在线观看 |