zoukankan      html  css  js  c++  java
  • 51单片机GPIO口模拟串口通信

    串口中断过程:

    流程是: (主程序中)发送数据--等待中断--发送成功(发送完一帧)产生中断--进入中断清除TI,再次发送--中断返回---等待中断---发送成功产生中断--进入中断清除TI,再次发送。。。。 循环而已 

       往TXBUF输入数据,当数据传输完成之后,会有标志位产生。如果这个时候已经使能全局中断位GIE和串口发送中断位UCTXIE,就会产生一个串口发送完成中断。接收中断同理。

    随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。

            本文所说的模拟串口, 就是利用51的两个输入输出引脚P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。

            以11.0592MHz的晶振为例,通过定时计数器0产生中断信号来模拟串口电平,下面附上具体源代码。

    [cpp] view plain copy
     
    1. /* 
    2. ************************************************************************************ 
    3. Fuction:使用51单片机GPIO口模拟串口通信,通过定时计数器0来产生中断信号 
    4. Software Designer:Jason 
    5. ************************************************************************************ 
    6. */  
    7. #include <reg52.h>  
    8. sbit P1_0 = P1^0;  
    9. sbit P1_1 = P1^1;  
    10. #define RXD P1_0  
    11. #define TXD P1_1  
    12. unsigned char flag;  
    13. void init();  
    14. void send_byte(unsigned char);  
    15. unsigned char rec_byte();  
    16. void wait_int();  
    17. //将从PC机串口接收到的数据原封不动回传给PC机  
    18. void main()  
    19. {  
    20.     unsigned char temp;  
    21.     init();  
    22.     while(1)  
    23.     {  
    24.         if(RI == 1)  
    25.         {  
    26.             RI = 0;  
    27.             temp = rec_byte();  
    28.             send_byte(temp);  
    29.             while(!TI);  
    30.             TI = 0;  
    31.         }  
    32.     }  
    33. }  
    34. //端口及中断初始化  
    35. void init()  
    36. {  
    37.     TMOD = 0x02;    //定时器0,方式2  
    38.     TH0 = 0xfd;     //波特率9600  
    39.     TL0 = TH0;  
    40.     TR0 = 0;        //在发送或接收时打开  
    41.     ET0 = 1;        //允许定时器0中断  
    42.     EA =1;          //允许所有中断  
    43. }  
    44. //通过串口发送一个字节数据  
    45. void send_byte(unsigned char dat)  
    46. {  
    47.     unsigned char i=8;  
    48.     TR0 = 1;        //开启T0中断  
    49.     TXD = 0;        //发送起始位0  
    50.     wait_int();  
    51.     while(i--)      //发送8位数据  
    52.     {  
    53.         TXD = (bit)(dat & 0x01);  
    54.         wait_int();  
    55.         dat = dat>>1;  
    56.     }  
    57.     TXD = 1;    //发送停止位1  
    58.     wait_int();  
    59.     TR0 = 0;        //关闭T0中断  
    60. }  
    61. //通过串口接收一个字节数据  
    62. unsigned char rec_byte()  
    63. {  
    64.     unsigned char dat=0;  
    65.     unsigned char i=8;  
    66.     TR0 = 1;        //开启T0中断  
    67.     wait_int();     //等过起始位电平  
    68.     while(i--)      //接收8位数据  
    69.     {  
    70.         dat = dat<<1;  
    71.         if(RXD)  
    72.             dat |= 0x80;  
    73.         wait_int();  
    74.     }  
    75.     wait_int();     //等过停止位电平  
    76.     TR0 = 0;        //关闭T0中断  
    77.     return dat;  
    78. }  
    79. //等待中断到来  
    80. void wait_int()  
    81. {  
    82.     while(!flag);  
    83.     flag = 0;  
    84. }  
    85. //中断服务程序  
    86. void timer0() interrupt 1  
    87. {  
    88.     flag = 1;  
    89. }  
     


     

  • 相关阅读:
    Codeforces Round #420 (Div. 2) A-E
    Codeforces Round #419 (Div. 2) A-E
    Bzoj4423 [AMPPZ2013]Bytehattan
    51nod1471 小S的兴趣
    Bzoj2629 binomial
    51nod1056 最长等差数列 V2
    51nod1055 最长等差数列
    51nod1110 距离之和最小 V3
    20. 有效的括号
    155.最小栈
  • 原文地址:https://www.cnblogs.com/Ph-one/p/7011613.html
Copyright © 2011-2022 走看看