|
最近一个哥们找我询问单片机任意端口模拟串口的思路,突然想起以前在学生时期做过一个多串口转发器,使用的是ATmega8A,跟大家一起分享。
模拟多串口转发器实现的功能:
1. 任意单片机端口模拟串口RX和TX
2. 全双工多路串口
3. 数据帧检验和转发功能
之前设计这个转发器,目的是为了实现串口组网,将不同的控制器,通过一个串口转发器,组成一个星形网络,网络中的任意主机可以互相通信。
下面简单介绍下模拟串口TX和RX的思路
1.发送:
根据串口帧格式分析,发送一个数据只需产生对应波特率的数据帧格式波形。对每一位的时间控制可以使用定时器,这里使用ATmega8A的定时器0,来作为模拟串口发送的时序控制。
帧格式发送实现的基本思路如下:将定时器0的溢出率设置为波特率的2倍,在一个比特位的持续时间中,定时器0会溢出两次,在前一次的溢出中,将每个串口所需要发送的比特位值,处理好后存储在一个名为Simulated_TX_Bit_Buffer的字节中,该字节的每一位代表着每一个串口(串口0~7)所需要发送的比特位值,当定时器第二次溢出时,通过端口映射,将Simulated_TX_Bit_Buffer对应比特位的高低电平数据,映射到对应的串口发送端口(TX0~7),这样相当于发送了一位。虽然定时器0溢出率为波特率的两倍,但是其只在第二次溢出时才改写端口电平,相当于每一位持续时间与对应波特率相当,实现每一位的时间控制。
在实现了每一位的时间控制后,根据当前发送的字节具体数值,加上一个起始位和停止位,以及相应控制,最终实现一个字节的完整发送,下图完整说明了模拟串口发送数据帧的原理:
在程序中,设定有一个标志位寄存器Flags0,其中的bit0位为TIMER0_OVERFLOW位,每次定时器0溢出,就会将此位翻转,可以看成如图5-2所示的定时器0溢出波形。在TIMER0_OVERFLOW位为0时(下降沿),将每个串口所需发送的比特位读取到Simulated_TX_Bit_Buffer中的对应位置。而每个串口所需发送的比特位,与Simulated_UDR_TXx(串口x发送数据寄存器)以及Simulated_Shift_Counter_TXx(串口x发送移位计数器)有关。Simulated_UDR_TXx存储着串口x发送的字节信息,Simulated_Shift_Counter_TXx存储着当前字节已经发送了多少位,一个字节发送完毕后,Simulated_Shift_Counter_TXx即为0,表示一个字节发送完毕。
2.接收
串口发送关键在于根据串口的帧格式,发送对应时序的帧,实现串口模拟。接收是发送的逆向工作,其基本原理与发送类似,根据接收到帧的时序,在一定时间内读取每一位电平,先读低位再读高位,最终拼接成一个完整的字节数据。 与发送不同的是,模拟串口发送时,有自己的发送节拍,即定时器0溢出,对多个串口可以做类似的处理。而串口接收时,不同串口接收到数据相位是不同的,比如串口0正在接收字节的第2位,而串口1开始收到了起始位,由于串口数据帧每一位的持续时间有限,需要在一定时间内完成读取并进行处理,如果不能及时同步到外界发送过来的数据帧并处理,就会导致接收失败,当串口数很多时,更是如此。基于上述分析,模拟串口接收需要一个同步措施,针对不同时间到来的数据帧,能及时与接收到的串口信号同步并读取位信息,实现多串口模拟接收。
接收串口数据的实质,在于能正确读取外界发送的串口信号。根据采样定理,要使采样得到的波形不失真,采样频率必须大于波形最大频率的2倍。为了更好地进行采样,这里将采样频率设为波特率的4倍,使用定时器2溢出生成采样节拍。类似于模拟串口发送,其在Flags0中的状态位TIMER0_OVERFLOW包含0,1两种状态,定时器2由于其溢出频率为波特率4倍,那么在Flags0中状态位设置为两个,分别是TIMER2_OVERFLOW1,TIMER2_OVERFLOW0,其包含4种状态00,01,10,11,模拟串口接收的基本思路如下:在每一个定时器2溢出时,检测串口RXx端口的电平,起始电平是低电平,当检测到低电平后,记录下当前定时器2的状态,此时程序开始与该串口的数据帧同步。程序中设置有两个字节的接收匹配寄存器Simulated_RX_Match_State_H,Simulated_RX_Match_State_L,每个串口占用两个比特位,用于记录其接收匹配信息。当RXx检测到低电平时,将匹配信息设置为当前定时器2状态的下一个,如当前检测到低电平的时候定时器2状态位01,那么设置该串口的匹配信息为10。当下一次定时器2溢出时,其匹配状态变为10,正好与该串口匹配,说明该串口可以读取当前接收端口的数据位。由于在检测到低电平时设置了匹配信息,这个信息正是用来作为串口数据接收同步信号,以后每次要等到定时器2状态与匹配信息一致时,才进行位读取,显然,由于定时器2溢出频率为波特率的4倍,而定时器2要经过4次变化才能变为原来的状态,所以每次采样的点与帧格式保持同步,当读取完所有的位后,即可组装成一个字节,实现一个完整字节的接收。 下图完整地说明了模拟串口接收的实现原理
可以看出,在检测到匹配后,在对应匹配值的下一个状态即进行位读取,每一个串口匹配信息可能不一样,因此读取时间也不一致,但均能保持同步,以实现正确的数据读取,类似于发送,接收到的位信息将会存储到Simulated_UDR_RXx(串口x接收数据寄存器),具体送入哪一位与Simulated_Shift_Counter_RXx(串口x接收移位计数器)有关,当一个数据帧接收完成后,Simulated_Shift_Counter_RXx将会变为0,表示一个字节接收完成。
在实现了上面的模拟串口功能后,再实现网络数据帧的转发,网络帧的格式如下
具体如何检验帧,如何转发就不详细描述了,最后看看整个软件的架构
软件是用汇编写的,总共占用的FLASH大小约为1.2K,很适合小型或低成本单片机场合下使用,附件为代码源工程(AVR Studio,以及详细的设计说明书,供大家参考,希望可以分享给大家自己之前做这个东西时的思路)
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|