51单片机IO口模拟串口通讯2-计数法

本文介绍了一种基于STC89C52单片机的串口通信方法,利用计数法模拟波特率实现数据的发送与接收。通过实例验证了该方法的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




硬件环境:STC89C52

软件环境:IDE Keil uVision V4.10

                    编译器 C51 V9.0

代码如下:

 

[cpp]  view plain copy
  1. /********************************************** 
  2. 方法2:计数法 
  3. 硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1 
  4. 波特率:9600 
  5. 描述:所谓计数法是指根据模拟出的波特率,每1位持续的时间的长短是通过定时器计数 
  6.       溢出来置标志位,查询该标志位来实现的。 
  7.  
  8. 测试1:上电发送1个0x02的字符 
  9. 测试2:上电先发送1个0x02的字符,然后等待接收,将收到的字符再发送出去(分别一个一个发送0x01,0x02,0x03,0x04,0x05)  
  10.  
  11. 结果: 
  12. 测试1:正确!接收到1个0x02的字符 
  13. 测试2-1:正确!上电接收到1个0x02的字符,分别一个一个发送0x01,0x02,0x03,0x04,0x05,均正常接收 
  14. 测试2-2:错误!   一起发送0x01,0x02,0x03,0x04,0x05,丢包,只能接收0x01,0x03,0x05 
  15.  
  16. 注意:由于本方法在上电时,TF0初始状态即为0,故不存在后边中断法出现的上电后必须手动将标志位清0的情况 
  17.  
  18. 时间:2012.07.25 于单位 
  19. **********************************************/  
  20. #include "reg52.h"  
  21. #define uchar unsigned char  
  22.   
  23. sbit P1_0 = 0x90;  
  24. sbit P1_1 = 0x91;  
  25. sbit P1_2 = 0x92;  
  26.   
  27. #define RXD P1_0  
  28. #define TXD P1_1  
  29. #define WRDYN 44                    //写延时  
  30. #define RDDYN 43                    //读延时  
  31.   
  32. #define TM0_FLAG P1_2 //设传输标志  
  33.   
  34. void Delay2cp(unsigned char i);  
  35. void WaitTF0( void );  
  36.   
  37. //计数器初始化  
  38. void S2INI(void)  
  39. {  
  40.     TMOD |=0x02;                 //计数器0,方式2  
  41.     TH0=0xA0;                    //预值为256-96=160,十六进制A0  
  42.     TL0=TH0;          
  43.     TR0=1;                       //开始计数  
  44.     TF0=0;  
  45. }  
  46.   
  47. //发送一个字符  
  48. void WByte(uchar input)  
  49. {  
  50.      //发送启始位  
  51.      uchar i=8;  
  52.      TR0=1;  
  53.      TXD=(bit)0;  
  54.      WaitTF0();  
  55.   
  56.      //发送8位数据位  
  57.      while(i--)  
  58.      {  
  59.          TXD=(bit)(input&0x01);   //先传低位  
  60.          WaitTF0();  
  61.          input=input>>1;  
  62.      }  
  63.   
  64.      //发送校验位(无)  
  65.   
  66.      //发送结束位  
  67.      TXD=(bit)1;  
  68.      WaitTF0();  
  69.      TR0=0;  
  70. }  
  71.   
  72. //接收一个字符  
  73. uchar RByte()  
  74. {  
  75.     uchar Output=0;  
  76.     uchar i=8;  
  77.     TR0=1;                          //启动Timer0  
  78.     TL0=TH0;  
  79.     WaitTF0();                      //等过起始位  
  80.   
  81.     //发送8位数据位  
  82.     while(i--)  
  83.     {  
  84.         Output >>=1;  
  85.         if(RXD)  
  86.             Output   |=0x80;        //先收低位  
  87.         WaitTF0();                  //位间延时  
  88.     }  
  89.     while(!TM0_FLAG) if(RXD) break;  
  90.   
  91.     TR0=0;                          //停止Timer0  
  92.   
  93.     return Output;  
  94. }  
  95.       
  96. //查询计数器溢出标志位  
  97. void WaitTF0( void )  
  98. {  
  99.      while(!TF0);  
  100.      TF0=0;  
  101. }  
  102.   
  103. void main()  
  104. {  
  105.     uchar ccc;  
  106.     S2INI();  
  107.   
  108.     //测试1  
  109.     //WByte(0x02);  
  110.     //while(1){;}  
  111.   
  112.     //测试2  
  113.     WByte(0x02);  
  114.     while(1)  
  115.     {  
  116.         if(RXD==0)  
  117.         {  
  118.             ccc=RByte();  
  119.             WByte(ccc);  
  120.         }  
  121.     }  
  122. }  


 

附几张抓到的波形:

测试1:十六进制字符0x02的波形

测试1:接收到的字符

 

结论:发送和接收字符均正常,没加缓冲,大数据量未测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值