找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

51單片機(jī)中斷、串口通信綜合程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:382145 發(fā)表于 2019-8-19 17:02 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
正在初學(xué)51的中斷,定時(shí)器,串口等等,遇到很多瓶頸比如串口怎么發(fā)送變量的數(shù)值啦(加一個(gè)0x30就好),分享這個(gè)程序給初學(xué)者們啦

功能:
1. 開(kāi)機(jī)以后,LED0和LED1實(shí)現(xiàn)0.5秒間隔閃爍2次,蜂鳴器同時(shí)鳴叫2次。
2. 之后,串口等待接收到一個(gè)字符'R',開(kāi)始進(jìn)入主循環(huán)體。
3. 主循環(huán)體中,LED0和LED1實(shí)現(xiàn)1秒間隔閃爍。
4. 串口接收到字符'D',回復(fù)LED當(dāng)前狀態(tài)和系統(tǒng)當(dāng)前處于運(yùn)行還是暫停狀態(tài),如果運(yùn)行狀態(tài),收到字符'R',如果暫停狀態(tài),收到字符'P'。
5. 串口接收到字符'T',回復(fù)主循環(huán)體開(kāi)始運(yùn)行的時(shí)間和系統(tǒng)當(dāng)前處于運(yùn)行還是暫停狀態(tài),時(shí)間單位為秒,最大計(jì)數(shù)值65535,以每一位的ASCII碼字符發(fā)送,最后加換行符。
6. 串口接收到其他字符,回復(fù)字符'W',且蜂鳴器高頻率鳴叫2次。
7. 主循環(huán)體運(yùn)行每分鐘,蜂鳴器低頻率鳴叫1次。
8. 開(kāi)啟INT0中斷,按下S_INT0,可以暫停目前的程序運(yùn)行,再次按下,可以繼續(xù)運(yùn)行,之前的所有都保持繼續(xù)運(yùn)行的狀態(tài),計(jì)數(shù)值也繼續(xù)累加。暫停狀態(tài)下, 依然可以響應(yīng)串口的'D'和'T'的應(yīng)答回復(fù),具體暫停還是運(yùn)行狀態(tài)的解釋,詳見(jiàn)第4條要求。
9. 所有定時(shí), 用T0方式1中斷實(shí)現(xiàn)。
10. 串行口配置為方式1,4800波特率,中斷接收,查詢發(fā)送。



PS:定時(shí)器的初值為了方便是用晶振12HZ算的哦,想要精確延時(shí)的朋友記得換成11.0592算一下啦
用的STC89C52REC的迷你單片機(jī),原理圖附在壓縮包里啦

單片機(jī)源程序如下:
  1. #include <reg52.h>
  2. #include"main.h"   

  3. void main()
  4. {        
  5.     init();

  6.     for(i=0; i<2; i++)
  7.         {
  8.             LED0 = 0;
  9.             LED1 = 0;
  10.             beep = 0;
  11.             delay(25);
  12.                 LED0 = ~LED0;
  13.             LED1 = ~LED1;
  14.             beep = 1;
  15.             delay(25);
  16.         }

  17. while(1)            
  18. {       
  19.     while(g_b_enter_flag)
  20.     {       
  21.                 if(LED0 == LED1)
  22.             {
  23.                     LED0 = 0;
  24.                 LED1 = 1;
  25.                     delay(50);
  26.                 }
  27.                 LED0 = ~LED0;
  28.             LED1 = ~LED1;
  29.             delay(50);
  30.     }//end of while(g_b_enter_flag)
  31.         while(!g_b_enter_flag)
  32.         {
  33.             ;
  34.         }
  35. }//end of while(1)                 
  36. }

  37. //按鍵中斷子程序
  38. void int0() interrupt 0
  39. {
  40.         g_b_enter_flag = ~g_b_enter_flag;//暫停和繼續(xù)的切換
  41. }  

  42. //定時(shí)器中斷子程序
  43. void Timer0() interrupt 1 using 1
  44. {
  45.     TH0 = 0xB1; //重新加載初值
  46.     TL0 = 0xE0;
  47.         g_i_cnt++;
  48.        
  49.         if(g_b_enter_flag)
  50.     {
  51.                  g_i_20ms_time++;  //記錄主循環(huán)運(yùn)行時(shí)間
  52.         }

  53.     if(g_i_20ms_time>50) //主程序運(yùn)行1s  
  54.         {
  55.         g_i_1s_time++;
  56.                 g_i_totaltime++;
  57.                 g_i_20ms_time = 0;
  58.     }
  59.         if(g_i_1s_time>60) //運(yùn)行一分鐘
  60.         {          
  61.             beep = 0;
  62.                 cdelay(200);
  63.                 beep = 1;
  64.                 g_i_1s_time=0;       
  65.                                                  
  66.     }
  67.         if(g_i_1s_time>65535)//最大計(jì)時(shí)值655353
  68.         {
  69.             g_i_1s_time = 0;
  70.         }
  71. }               

  72. //精確延時(shí)
  73. void delay(unsigned int z)            
  74. {   
  75.          g_i_cnt=0;
  76.      while(g_i_cnt<z)
  77.          {
  78.                ;
  79.          }
  80.          g_i_cnt=0;         
  81. }

  82. //發(fā)送一個(gè)字符
  83. void send(unsigned char byte)
  84. {
  85.         SBUF=byte;
  86.         while(!TI);
  87.         TI=0;
  88. }

  89. //不精確延時(shí)
  90. void cdelay(unsigned int k)
  91. {         
  92.      unsigned int x,y;

  93.          for(x=0; x<k; x++)
  94.          {  
  95.              for(y=0;y<600;y++);
  96.          }
  97. }

  98. //外部中斷和定時(shí)器的初始化
  99. void init()
  100. {
  101.     i=0;
  102.         g_b_R_flag=0;//判斷是否是第一次發(fā)送R
  103.         g_b_enter_flag=0; //判斷是否進(jìn)入主循環(huán),0為否,1為是
  104.         g_i_cnt=0;        //精確延時(shí)用
  105.         g_i_20ms_time=0;        //一個(gè)等于20ms
  106.     g_i_1s_time=0; //一個(gè)等于1s
  107.         g_i_totaltime=0;   //主程序運(yùn)行總時(shí)間

  108.         EX0 = 1;//開(kāi)外部中斷0
  109.         IT0 = 0;//外部中斷0低電平觸發(fā)

  110.     ET0 = 1;//打開(kāi)定時(shí)器0中斷
  111.         TMOD |= 0X01; //定時(shí)器工作模式1,16位定時(shí)模式
  112.         TR0 = 1;//啟動(dòng)定時(shí)器0
  113.         TH0 = 0xB1;
  114.         TL0 = 0xE0; //定時(shí)20ms

  115.     ES = 1; //打開(kāi)串口中斷
  116.     SCON = 0x50;//配置串口為模式 1
  117.         REN = 1;//串口允許接收
  118.        
  119.         TMOD |= 0x20;//定時(shí)器1,工作模式2 8位自動(dòng)重裝
  120.         TH1 = 0xFA;        //波特率4800
  121.         TL1 = 0xFA;
  122.         ET1 = 0; //禁止 T1 中斷
  123.         TR1 = 1;//啟動(dòng)定時(shí)器1
  124.     EA = 1;        //打開(kāi)總中斷
  125. }   

  126. //UART中斷服務(wù)函數(shù)
  127. void InterruptUART() interrupt 4 using 1
  128. {
  129.    
  130.         if(RI)//判斷接收是否完成
  131.         {
  132.                 RI = 0;//手動(dòng)清零接收中斷標(biāo)志位       

  133.                 if((SBUF==0x52)&(g_b_R_flag==1))
  134.                 {
  135.                     send('W');
  136.                     beep=0;
  137.                         cdelay(60);
  138.                         beep=1;
  139.                         cdelay(60);
  140.                         beep=0;
  141.                         cdelay(60);
  142.                         beep=1;
  143.                         cdelay(60);
  144.                 }
  145.             if(SBUF==0x52)        //接受字母為R,開(kāi)始進(jìn)入主循環(huán)體
  146.                 {       
  147.                     g_b_enter_flag = 1;
  148.                         g_b_R_flag=1;
  149.             }
  150.                 else if(SBUF==0x44)//接收字母為D,發(fā)送LED狀態(tài)
  151.                 {
  152.                         if(g_b_enter_flag)
  153.                         {
  154.                                 send('R');
  155.                                 send('\n');
  156.                                 if(LED0==1&&LED1==0)
  157.                             {
  158.                                  send('C');
  159.                                 send('O');
  160.                                 send('\n');
  161.                             }
  162.                             else
  163.                             {
  164.                                 send('O');
  165.                                 send('C');
  166.                                 send('\n');
  167.                             }
  168.                         }
  169.                         else
  170.                         {
  171.                                 send('P');
  172.                                 send('\n');
  173.                         }
  174.                 }//end of else if(SBUF==0x44)
  175.                 else if(SBUF==0x54)//接受字母T發(fā)送系統(tǒng)狀態(tài)和運(yùn)行時(shí)間
  176.                 {       
  177.                     if(g_b_enter_flag)
  178.                         {
  179.                         send('R');
  180.                                 send('\n');
  181.                         }
  182.                         else
  183.                         {         
  184.                             send('P');
  185.                                 send('\n');
  186.                         }
  187.                         num1 = 0x30+g_i_totaltime/10000;
  188.                     SBUF = num1;
  189.             while(!TI);
  190.             TI = 0;
  191.                         num2 = 0x30+g_i_totaltime%10000/1000;
  192.                     SBUF = num2;
  193.             while(!TI);
  194.             TI = 0;
  195.                         num3 = 0x30+g_i_totaltime%1000/100;
  196.                     SBUF = num3;
  197.             while(!TI);
  198.             TI = 0;
  199.                         num4 = 0x30+g_i_totaltime%100/10;
  200.                     SBUF = num4;
  201.             while(!TI);
  202.             TI = 0;
  203.                         num5 = 0x30+g_i_totaltime%10;
  204.                     SBUF = num5;
  205.             while(!TI);
  206.             TI = 0;
  207.                         send('\n');
  208.         } //end of        else if(SBUF==0x54)
  209.                 else
  210.                 {
  211.                     send('W');
  212.                         beep=0;
  213.                         cdelay(60);
  214.                         beep=1;
  215.                         cdelay(60);
  216.                         beep=0;
  217.                         cdelay(60);
  218.                         beep=1;
  219.                         cdelay(60);
  220.             }
  221.     if(TI)//判斷是否發(fā)送完成
  222.         {       
  223.             TI = 0;//清零發(fā)送完成標(biāo)志位
  224.         }
  225.     }//end of if(RI)
  226. }
復(fù)制代碼

所有資料51hei提供下載:
totaltask.rar (83.75 KB, 下載次數(shù): 34)



評(píng)分

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

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:653636 發(fā)表于 2019-12-1 17:12 | 只看該作者
我也是初學(xué)者,感謝分享
回復(fù)

使用道具 舉報(bào)

板凳
ID:682129 發(fā)表于 2020-1-6 14:49 | 只看該作者
非常不錯(cuò)
回復(fù)

使用道具 舉報(bào)

地板
ID:583247 發(fā)表于 2020-3-2 00:32 | 只看該作者

非常不錯(cuò)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表