单片机模拟串口实验

发布者:DazzlingSmile最新更新时间:2016-12-28 来源: eefocus关键字:单片机  模拟串口 手机看文章 扫描二维码
随时随地手机看文章

传统的8051系列单片机一般都配备一个串口,而STC89C52RC增强型单片机也不例外,只有一个串口可供使用,这样就出问题了,假如当前单片机系统要求二个串口或多个串口进行同时通信,8051系列单片机只有一个串口可供通信就显得十分尴尬,但是在实际的应用中,有两种方法可以选择。

方法1:使用能够支持多串口通信的单片机,不过通过更换其他单片机来代替8051系列单片机,这样就会直接导致成本的增加,优点就是编程简单,而且通信稳定可靠。

方法2:在IO资源比较充足的情况下,可以通过IO来模拟串口的通信,虽然这样会增加编程的难度,模拟串口的波特率会比真正的串口通信低一个层次,但是唯一优点就是成本上得到控制,而且通过不同的IO组合可以实现更加之多的模拟串口,在实际应用中往往会采用模拟串口的方法来实现多串口通信。

普遍使用串口通信的数据流都是1位起始位、8位数据位、1位停止位的格式的,如表1。

表1

起始位

8位数据位

停止位

0

Bit0

Bit1

Bit2

Bit3

Bit4

Bit5

Bit6

Bit7

1











 

要注意的是,起始位作为识别是否有数据到来,停止位标志数据已经发送完毕。起始位固定值为0,停止位固定值为1,那么为什么起始位要是0,停止位要是1呢?这个很好理解,假设停止位固定值为1,为了更加易识别数据的到来,电平的跳变最为简单也最容易识别,那么当有数据来的时候,只要在规定的时间内检测到发送过来的第一位的电平是否0值,就可以确定是否有数据到来;另外停止位为1的作用就是当没有收发数据之后引脚置为高电平起到抗干扰的作用。

在平时使用红外无线收发数据时,一般都采用模拟串口来实现的,但是有个问题要注意,波特率越高,传输距离越近;波特率越低,传输距离越远。对于这些通过模拟串口进行数据传输,波特率适宜为1200b/s来进行数据传输。

   例子:在使用单片机的串口接收数据实验当中,使用串口调试助手发送16字节数据,单片机采用模拟串口的方法将接收到的数据返发到PC机。

模拟串口实验代码:

  1 #include "stc.h"
  2 
  3  #define RXD P3_0              //宏定义:接收数据的引脚
  4  #define TXD P3_1              //宏定义:发送数据的引脚
  5  #define RECEIVE_MAX_BYTES 16//宏定义:最大接收字节数
  6 
  7  #define TIMER_ENABLE()  {TL0=TH0;TR0=1;fTimeouts=0;}//使能T/C
  8  #define TIMER_DISABLE() {TR0=0;fTimeouts=0;}//禁止T/C
  9  #define TIMER_WAIT()    {while(!fTimeouts);fTimeouts=0;}//等待T/C超时
 10 
 11 
 12 unsigned char fTimeouts=0;//T/C超时溢出标志位
 13  unsigned char RecvBuf[16];//接收数据缓冲区
 14  unsigned char RecvCount=0;//接收数据计数器
 15  
 16 
 17  /****************************************
 18 *函数名称:SendByte
 19 *输    入:byte 要发送的字节
 20 *输    出:无
 21 *功    能:串口发送单个字节
 22 ******************************************/
 23  void SendByte(unsigned char b)
 24 {
 25      unsigned char i=8;
 26      
 27      TXD=0;
 28 
 29      TIMER_ENABLE();
 30      TIMER_WAIT();
 31      
 32 
 33  while(i--)
 34      {
 35  if(b&1)TXD=1;
 36  else    TXD=0;
 37 
 38         TIMER_WAIT();
 39         
 40         b>>=1;
 41 
 42      }
 43 
 44      
 45      TXD=1;
 46 
 47      TIMER_WAIT();
 48      TIMER_DISABLE();
 49 }
 50  /****************************************
 51 *函数名称:RecvByte
 52 *输    入:无
 53 *输    出:单个字节
 54 *功    能:串口 接收单个字节
 55 ******************************************/
 56 unsigned char RecvByte(void)
 57 {
 58      unsigned char i;
 59      unsigned char b=0;
 60      
 61      TIMER_ENABLE();
 62      TIMER_WAIT();
 63 
 64  for(i=0;i<8;i++)
 65      {
 66  if(RXD)b|=(1<=RECEIVE_MAX_BYTES)
137            {
138               RecvCount=0;
139 
140  for(i=0;i

代码分析

在模拟串口实验代码中,宏的使用占用了相当的一部分。

#define RXD P3_0          //宏定义:接收数据的引脚

#define TXD P3_1          //宏定义:发送数据的引脚

#define TIMER_ENABLE()  {TL0=TH0;TR0=1;fTimeouts=0;}//使能T/C

#define TIMER_DISABLE() {TR0=0;fTimeouts=0;}//禁止T/C

#define TIMER_WAIT()    {while(!fTimeouts);fTimeouts=0;}//等待T/C超时

   

模拟串口接收引脚为P3.0,发送引脚为P3.1。为了达到精确的定时,减少模拟串口时收发数据的累积误差,有必要通过对T/C进行频繁的使能和禁止等操作。例如宏TIMER_ENABLE为使能T/C,宏TIMER_DISABLE禁止T/C,宏TIMER_WAIT等待T/C超时。

模拟串口的工作波特率为9600b/s,在串口收发的数据流当中,每一位的时间为1/9600≈104us,

若单片机工作在12MHz频率下,使用T/C0工作在方式2,那么为了达到104us的定时时间,TH0、TL0的初值为256-104=152,在实际的模拟串口中,往往出现收发数据不正确的现象。原因就在于TH0、TL0的初值,或许很多人会疑惑,按道理来说,计算T/C0的初值是没有错的。对,是没有错,但是在SendByte和Recv的函数当中,执行每一行代码都要消耗一定的时间,这就是所谓的“累积误差”导致收发数据出现问题,因此我们必须通过实际测试得到TH0、TL0的初值,最佳值256-99=157。那么在T/C初始化TimerInit函数中,TH0、TL0的初值不能够按照常规来计算得到,实际初值在正常初值附近,可以通过实际测试得到。

模拟串口主要复杂在模拟串口发送与接收,具体实现函数在SendByte和RecvByte函数,这两个函数必须要遵循“1位起始位、8位数据位、1位停止位”的数据流。

SendByte函数用于模拟串口发送数据,以起始位“0”作为移位传输的起始标志,然后将要发送的自己从低字节到高字节移位传输,最后以停止位“1”作为移位传输的结束标志。

RecvByte函数用于模拟串口接收数据,一旦检测到起始位“0”,就立刻将接收到的每一位移位存储,最后以判断停止位“1”结束当前数据的接收。

main函数完成T/C的初始化,在while(1)死循环以检测起始位“0”为目的,当接收到的数据达到宏RECEIVE_MAX_BYTES的个数时,将接收到的数据返发到外设。


关键字:单片机  模拟串口 引用地址:单片机模拟串口实验

上一篇:C8051振荡器相关事项解答
下一篇:单片机波特率的研究

推荐阅读最新更新时间:2024-03-16 15:27

单片机中C语言延时函数
单片机C语言延时程序计算2009-11-02 22:15单片机C语言延时程序用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时很不好控制,我们常常很难知道一段延时程序它的精确延时到底是多少,这和汇编延时程序没法比。但有时后写程序又不得不要用到比较精确的延时,虽然说可以用混合编程的方式解决,但这种方式不是每个人都能掌握,且写起来也麻烦。所以,通过测试我给大家提供一个延时子程序模块,并以此给一个出我们经常用到的延时的数据表格。(注意:表格中的数据只适合我的延时模块,对其他的延时程序不适用,切忌!!!!!!!!别到时候延时不对来骂我) 延时模块:其中问号代
[单片机]
基于SPCE061A单片机的图形液晶模块的驱动设计
内置T6963C控制器的Y240128A液晶模块由双电源(VDD/V0)供电。工作时需要提供一个负电压 (即液晶驱动电压V0/VEE),用以调节对比度,接至液晶模块的V0引脚。基于液晶材料的物理特性,液晶的对比度会随着温度的变化相应变化,因此,所提供的负电压必须随温度变化作相应的调整,大致变换关系是温度变化10℃,电压变化1V左右。此外,液晶模块在正常工作前必须提供驱动电源。由于选用的Y240128A液晶模块中已具备提供负电压的功能,只需接一个可调电位器(阻值20kΩ)就可方便地为液晶提供驱动电源。具体如图1所示。     引脚1、2:接地;引脚3:接+5V电压为LCD逻辑电源;引脚5~8:液晶控制信号;引脚10~17
[家用电子]
基于SPCE061A<font color='red'>单片机</font>的图形液晶模块的驱动设计
51内核单片机中断优先级的理解
由于项目的需要,这两天正好在研究应用层协议的格式与规范,参考了吴老师给的ZLG的RS-485_Guide。 RS-485标准是基于PC的UART芯片上的处理方式(8-N-1格式),只涉及到电气特性规定,而没有对上层协议作出规定,因此,需要用户自己设计网络应用层协议。大部分用户都自行定义自己的应用层协议,或者直接取自部分ModBus协议。国内根据不同的设备类型也颁布了各类通讯协议,如CDT、SC-1801、u4F、DNP3.0 规约和1995年的IEC60870-5-101 传输规约、1997 年的国际101 规约的国内版本DL/T634-1997规约;在电表应用中,国内大多数地区的厂商采用多功能电能表通讯规约(DL/
[单片机]
CISC 和 RISC 微控制器
微控制器是将微型计算机的主要部分集成在一个芯片上的单芯片微型计算机。微控制器诞生于20世纪70年代中期,经过20多年的发展,其成本越来越低,而性能越来越强大,这使其应用已经无处不在,遍及各个领域。例如电机控制、条码阅读器/扫描器、消费类电子、游戏设备、电话、HVAC、楼宇安全与门禁控制、工业控制与自动化和白色家电(洗衣机、微波炉)等。 微控制器可从不同方面进行分类:根据数据总线宽度可分为8位、16位和32位机;根据存储器结构可分为Harvard结构和Von Neumann结构;根据内嵌程序存储器的类别可分为OTP、掩膜、EPROM/EEPROM和闪存Flash;根据指令结构又可分为CISC(Complex Instruction
[嵌入式]
AVR单片机—(五)、ATMEGA16的USART与PC机串行通信—03
五、ATMEGA16的USART与PC机串行通信 五—(03)、PC机发送控制指令控制单片机工作~(这个控制还是比较简单的~~ ,不过个人认为还是有水平的~) 还是先上图片~~,然后程序,程序师模块化的,我尽量贴全点~~ 然后就是程序了 IAR5_2.c //------------------------------------------------------------------------------ //控制指令的定义(个人感觉这个才是真正应用呢~~给力~) //上位机界面中,用户需要输入控制下位机的指令 //由于传送的数据比较简单,因此控制指令也可定义的相对简单一些((*^__^*) 嘻嘻……,那本书上
[单片机]
AVR<font color='red'>单片机</font>—(五)、ATMEGA16的USART与PC机串行通信—03
SAM4E单片机之旅——12、USART
清楚了UART的用法之后,现在来研究一下USART的用法。和上一次差不多,这次也通过USART的串口来实现和PC的通信。和上一次不同的是,USART本身就有接收超时的功能,所以这次就不用TC了。 USART和UART相比,功能多了许多,可以配置的选项也更多。虽然最主要的差别是USART可以实现同步通信,但PC的串口没有这个功能,所以我们就先不拿这个功能开刀了。 一、 思路 实现思路和上一次使用UART的PDC差不多,区别只是这次直接使用USART的接收超时功能,而不用TC。 二、 电路图 使用的USART口为USART1,这个串口在上次使用的DBGU口的旁边。 有个使能引脚连在PA23上。使用时需要将PA23拉为低电平才
[单片机]
SAM4E<font color='red'>单片机</font>之旅——12、USART
单片机学习记录——蜂鸣器
硬件连接 从图中可知,蜂鸣器只有一个接口与外部相连接。我们通过跳线把J8接口与单片机的P0.0接口相连接。 蜂鸣器发声原理 有源蜂鸣器,也称压电式压蜂鸣器,主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。 其中最重要的就是它的压电蜂鸣片,通常这是一种压电陶瓷,能进行电能与机械能的转换。 发声过程为:外部提供恒定直流电压,提供能量给多谐振荡器,多揩振荡器起振,并提供变化的电压和频率给压电陶瓷,压电陶瓷将电能转化为机械能,也就发出了声音。 无源蜂鸣器,也称电磁式蜂鸣器,主要由永磁体,线圈,振荡片构成。 发声过程为:外部按一定频率提供驱动一个振荡信号(一定占空比的方波,该信号作用于线圈,产生的磁声与永
[单片机]
<font color='red'>单片机</font>学习记录——蜂鸣器
使用高集成度MCU实现网络支持的技术
  在过去 20 年中,许多工业和自动化系统的趋势是向单个节点添加越来越多的数字智能,以提高它们的响应速度。通过使用分布式智能将系统整合到系统系统(也称为“物联网”)中,系统可以变得更加灵活。通过网络控制,可以提供对设备的远程控制,让它们更智能地工作,以节省能源并提供状态和错误反馈。   使用从远程节点收集的数据,云中的服务器可以在警报开始出现时主动安排维护。这些服务器还可以通过使用增强的控制算法使设备协同工作,以获得更节能或更具成本效益的解决方案,这些算法不仅对来自一个设备的数据作出反应,而且还执行传感器融合以使用来自多个设备的输入。   自 1970 年代推出以来,以及随后在 1980 年代更新为使用低成本双绞线电缆,
[单片机]
使用高集成度<font color='red'>MCU</font>实现网络支持的技术
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved