找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5328|回复: 3
打印 上一主题 下一主题
收起左侧

51单片机中断、串口通信综合程序

[复制链接]
跳转到指定楼层
楼主
ID:382145 发表于 2019-8-19 17:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
正在初学51的中断,定时器,串口等等,遇到很多瓶颈比如串口怎么发送变量的数值啦(加一个0x30就好),分享这个程序给初学者们啦

功能:
1. 开机以后,LED0和LED1实现0.5秒间隔闪烁2次,蜂鸣器同时鸣叫2次。
2. 之后,串口等待接收到一个字符'R',开始进入主循环体。
3. 主循环体中,LED0和LED1实现1秒间隔闪烁。
4. 串口接收到字符'D',回复LED当前状态和系统当前处于运行还是暂停状态,如果运行状态,收到字符'R',如果暂停状态,收到字符'P'。
5. 串口接收到字符'T',回复主循环体开始运行的时间和系统当前处于运行还是暂停状态,时间单位为秒,最大计数值65535,以每一位的ASCII码字符发送,最后加换行符。
6. 串口接收到其他字符,回复字符'W',且蜂鸣器高频率鸣叫2次。
7. 主循环体运行每分钟,蜂鸣器低频率鸣叫1次。
8. 开启INT0中断,按下S_INT0,可以暂停目前的程序运行,再次按下,可以继续运行,之前的所有都保持继续运行的状态,计数值也继续累加。暂停状态下, 依然可以响应串口的'D'和'T'的应答回复,具体暂停还是运行状态的解释,详见第4条要求。
9. 所有定时, 用T0方式1中断实现。
10. 串行口配置为方式1,4800波特率,中断接收,查询发送。



PS:定时器的初值为了方便是用晶振12HZ算的哦,想要精确延时的朋友记得换成11.0592算一下啦
用的STC89C52REC的迷你单片机,原理图附在压缩包里啦

单片机源程序如下:
  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;//暂停和继续的切换
  41. }  

  42. //定时器中断子程序
  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++;  //记录主循环运行时间
  52.         }

  53.     if(g_i_20ms_time>50) //主程序运行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) //运行一分钟
  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)//最大计时值655353
  68.         {
  69.             g_i_1s_time = 0;
  70.         }
  71. }               

  72. //精确延时
  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. //发送一个字符
  83. void send(unsigned char byte)
  84. {
  85.         SBUF=byte;
  86.         while(!TI);
  87.         TI=0;
  88. }

  89. //不精确延时
  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. //外部中断和定时器的初始化
  99. void init()
  100. {
  101.     i=0;
  102.         g_b_R_flag=0;//判断是否是第一次发送R
  103.         g_b_enter_flag=0; //判断是否进入主循环,0为否,1为是
  104.         g_i_cnt=0;        //精确延时用
  105.         g_i_20ms_time=0;        //一个等于20ms
  106.     g_i_1s_time=0; //一个等于1s
  107.         g_i_totaltime=0;   //主程序运行总时间

  108.         EX0 = 1;//开外部中断0
  109.         IT0 = 0;//外部中断0低电平触发

  110.     ET0 = 1;//打开定时器0中断
  111.         TMOD |= 0X01; //定时器工作模式1,16位定时模式
  112.         TR0 = 1;//启动定时器0
  113.         TH0 = 0xB1;
  114.         TL0 = 0xE0; //定时20ms

  115.     ES = 1; //打开串口中断
  116.     SCON = 0x50;//配置串口为模式 1
  117.         REN = 1;//串口允许接收
  118.        
  119.         TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
  120.         TH1 = 0xFA;        //波特率4800
  121.         TL1 = 0xFA;
  122.         ET1 = 0; //禁止 T1 中断
  123.         TR1 = 1;//启动定时器1
  124.     EA = 1;        //打开总中断
  125. }   

  126. //UART中断服务函数
  127. void InterruptUART() interrupt 4 using 1
  128. {
  129.    
  130.         if(RI)//判断接收是否完成
  131.         {
  132.                 RI = 0;//手动清零接收中断标志位       

  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,开始进入主循环体
  146.                 {       
  147.                     g_b_enter_flag = 1;
  148.                         g_b_R_flag=1;
  149.             }
  150.                 else if(SBUF==0x44)//接收字母为D,发送LED状态
  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发送系统状态和运行时间
  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)//判断是否发送完成
  222.         {       
  223.             TI = 0;//清零发送完成标志位
  224.         }
  225.     }//end of if(RI)
  226. }
复制代码

所有资料51hei提供下载:
totaltask.rar (83.75 KB, 下载次数: 34)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:653636 发表于 2019-12-1 17:12 | 只看该作者
我也是初学者,感谢分享
回复

使用道具 举报

板凳
ID:682129 发表于 2020-1-6 14:49 | 只看该作者
非常不错
回复

使用道具 举报

地板
ID:583247 发表于 2020-3-2 00:32 | 只看该作者

非常不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表