找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC15F系列8051单片机模拟串口57600bps@24MHz

[复制链接]
跳转到指定楼层
楼主
ID:71407 发表于 2014-12-31 00:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

  1. //为何不把程序写得通俗易懂点?超级代码来了!
  2. //参考了STC官网手册中的程序,但源程序遇到RX脚一直为低电平也会收到数据0x00,这里已经修正
  3. //柳州市第一职业技术学校 电气自动化专业部 中国欧软 China O Soft! 2012年8月3日
  4. #include <reg52.h>                                //使用8052内核单片机
  5. sbit TX_IO=P3^1;                                  //模拟串口发送IO
  6. sbit RX_IO=P3^0;                                  //模拟串口接收IO
  7. sfr AUXR=0x8e;                        //STC15F系列单片机特殊寄存器,控制定时器时钟来源频率
  8. bit sending,receing,received;                      //发送中,接收中,接收完毕标志
  9. unsigned char rece_bit_count;                      //接收位计数变量
  10. unsigned char rece_pls_count;                      //接收脉冲计数变量
  11. unsigned char send_bit_count;                      //发送位计数变量
  12. unsigned char send_pls_count;                      //发送脉冲计数变量
  13. unsigned char receing_data;                        //正在接收着的临时数据
  14. unsigned char byte_need_to_send;                  //要发送出去的字节
  15. unsigned char byte_received;                      //已收到的字节

  16. void send_byte(unsigned char byte_will_send)      //发送一个字节
  17. {                                                  //函数开始
  18. byte_need_to_send=byte_will_send;                  //传递要发送的数据
  19. send_pls_count=3;                                  //采样倍率3
  20. send_bit_count=8;                                  //8位数据一位停止
  21. TX_IO=0;                                          //发送起始位
  22. sending=1;                                        //置标志位,中断程序开始发送该字节
  23. while(sending);                                    //等待数据发送完成
  24. }                                                  //函数结束

  25. void timer0(void) interrupt 1                      //中断服务程序
  26. {                                                  //函数开始
  27. if(receing)                                        //接收中?
  28.   {                                                //接收中开始
  29.   if(--rece_pls_count==0)                          //三次脉冲计数够了吗?
  30.     {                                              //接收一位二进制位开始
  31.     rece_pls_count=3;                              //脉冲计数辅助变量复位
  32.     if(rece_bit_count)                            //是在接收数据位还是停止位
  33.       {                                            //接收数据位开始
  34.       receing_data=receing_data>>1;                //向右移一位,准备拼入一位二进制数据
  35.       if(RX_IO==1){receing_data=receing_data|0x80;}//如果收到的是二进制位"1",则拼入最高位中
  36.       rece_bit_count=rece_bit_count-1;            //已接收一位,接收位计数变量计数
  37.       }                                            //接收数据位结束
  38.     else                                          //如果已经收完8位数据
  39.       {                                            //就开始接收停止位
  40.       receing=0;                                  //本字节已接收完毕
  41.       if(RX_IO==1)                                //停止位是"1"吗
  42.         {                                          //是“1”
  43.         byte_received=receing_data;                //将数据输出
  44.         received=1;                                //摇旗示意数据正确接收完毕
  45.         }                                          //数据输出处理完毕
  46.       }                                            //停止位处理完毕
  47.     }                                              //接收一位二进制位结束
  48.   }                                                //接收中处理结束
  49. else                                              //还没收到停止位,不是正在接收状态
  50.   {                                                //等待接收开始
  51.     if(RX_IO==0)                                  //是一个起始位到来吗
  52.     {                                              //是.......
  53.     receing=1;                                    //开始接收
  54.     rece_pls_count=3;                              //置接收起始位脉冲数
  55.     rece_bit_count=8;                              //置接收二进制位数
  56.     }                                              //起始位处理完毕
  57.   }                                                //等待接收完毕
  58. //----------------------------------------------------------------------------------------
  59. if(sending)                                        //是正在发送状态吗
  60.   {                                                //是……
  61.   if(--send_pls_count==0)                          //脉冲计数够了吗
  62.     {                                              //够了……
  63.     send_pls_count=3;                              //脉冲计数复位
  64.     if(send_bit_count)                            //是在发送数据还是要发送停止位
  65.       {                                            //发送数据开始
  66.       TX_IO=byte_need_to_send&0x01;                //从最低位开始发送数据
  67.       byte_need_to_send=byte_need_to_send>>1;      //移动数据准备下一次发送
  68.       send_bit_count=send_bit_count-1;            //已经发送了一位二进制数要记下来
  69.       }                                            //发送数据结束
  70.     else                                          //数据已经发送完成
  71.       {                                            //发送停止位开始
  72.       TX_IO=1;                                    //发送停止位
  73.       sending=0;                                  //放下旗帜表示数据已经发送完成
  74.       }                                            //停止位发送完成
  75.     }                                              //一位二进制位处理完成
  76.   }                                                //发送状态处理完成
  77. }                                                  //中断函数结束
  78. void main(void)                                    //主程序
  79. {                                                  //开始
  80. AUXR=0x80;                                        //T0计时脉冲不分频,比传统8051快12倍
  81. TMOD=0X00;                //16位自动重载模式,当TR0=0时向TH0,TL0写入数据将同时写入重载寄存器
  82. TH0=(65536-(24000000/57600/3))/256;                //重载值=65536-(定时器脉冲频率÷波特率÷3)
  83. TL0=(65536-(24000000/57600/3))%256;                //溢出率=定时器脉冲频率÷(65536-重载值)
  84. TR0=1;                                            //启动定时器,模拟串口开始工作
  85. EA=1;                                              //打开总中断
  86. ET0=1;                                            //打开定时器0中断
  87. PX0=1;                                            //优先保证定时器0中断,确保模拟串口的可靠性
  88. while(1)                                          //主循环
  89.   {                                                //主循环体开始
  90.   if(received==1)                                  //收到一个字节的数据啦?
  91.     {                                              //是……
  92.     received=0;                                    //知道了……
  93.     send_byte(byte_received);                      //原封不动打回原籍
  94.     }                                              //收到字节处理完毕
  95.   }                                                //主循环体结束
  96. }                                                  //主程序结束
复制代码


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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