搜索
bottom↓
回复: 36

模拟多串口转发器

  [复制链接]

出0入0汤圆

发表于 2018-4-23 20:25:07 | 显示全部楼层 |阅读模式
最近一个哥们找我询问单片机任意端口模拟串口的思路,突然想起以前在学生时期做过一个多串口转发器,使用的是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_OVERFLOW1TIMER2_OVERFLOW0,其包含4种状态00,01,10,11,模拟串口接收的基本思路如下:在每一个定时器2溢出时,检测串口RXx端口的电平,起始电平是低电平,当检测到低电平后,记录下当前定时器2的状态,此时程序开始与该串口的数据帧同步。程序中设置有两个字节的接收匹配寄存器Simulated_RX_Match_State_HSimulated_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来反美的!

出0入213汤圆

发表于 2018-4-23 21:02:37 | 显示全部楼层
牛叉, MARK一下.  模拟多串口

出0入0汤圆

发表于 2018-4-23 21:32:07 | 显示全部楼层
真棒!谢谢!

出0入0汤圆

发表于 2018-4-23 21:44:00 | 显示全部楼层
厉害了。多串口用

出0入0汤圆

发表于 2018-4-23 21:44:49 | 显示全部楼层
厉害了,哥,顶

出0入0汤圆

发表于 2018-4-23 22:43:51 来自手机 | 显示全部楼层
stm8有个文档专门说这个功能的,具体叫什么名字忘了

出0入0汤圆

发表于 2018-4-23 22:44:28 来自手机 | 显示全部楼层
够省的了

出0入0汤圆

 楼主| 发表于 2018-4-23 23:02:59 | 显示全部楼层
gao_hailong 发表于 2018-4-23 22:43
stm8有个文档专门说这个功能的,具体叫什么名字忘了

还有官方的模拟方法?倒是想见识对比一下

出0入0汤圆

 楼主| 发表于 2018-4-23 23:05:34 | 显示全部楼层

之前做这个东西定位就是低成本的硬件,由于带帧包缓存处理,所以还算比较吃RAM,每个通道分配了64B,使用8个串口的话缓存区占了512B,几乎用了ATmega8A一半的RAM了

出0入0汤圆

发表于 2018-4-23 23:25:33 | 显示全部楼层
速度最高能到多少?

出0入1209汤圆

发表于 2018-4-24 02:05:04 | 显示全部楼层
记号         

出0入0汤圆

发表于 2018-4-24 09:00:27 | 显示全部楼层
好贴,先收藏,等以后用到的时候再来取经

出0入0汤圆

 楼主| 发表于 2018-4-24 19:35:41 | 显示全部楼层
rf_smart 发表于 2018-4-23 23:25
速度最高能到多少?

自己测到过576000的比特率,再往上就没测了,你有空可以自己试试

出0入0汤圆

发表于 2018-4-24 21:20:54 | 显示全部楼层
厉害,下来研究下

出0入0汤圆

发表于 2018-4-24 21:54:26 | 显示全部楼层
kingway00 发表于 2018-4-23 23:05
之前做这个东西定位就是低成本的硬件,由于带帧包缓存处理,所以还算比较吃RAM,每个通道分配了64B,使用 ...

  。。。这基本把AVR当fpga使用了把

出0入0汤圆

发表于 2018-4-25 00:06:37 | 显示全部楼层
学习了,谢谢,串口还可以这样模拟啊。

出0入0汤圆

发表于 2018-4-25 10:48:20 | 显示全部楼层
18年前用89C52搞过模拟串口。记得高于4800就不大稳定了。现在的单片机快多了,中断也多的很,波特率高些应该靠谱。

出0入0汤圆

 楼主| 发表于 2018-4-25 20:19:51 | 显示全部楼层
zlutian 发表于 2018-4-25 00:06
学习了,谢谢,串口还可以这样模拟啊。

你目前所知的所有通信方式都能模拟,只是速度问题

出0入0汤圆

 楼主| 发表于 2018-4-25 21:01:42 | 显示全部楼层
censtar 发表于 2018-4-25 10:48
18年前用89C52搞过模拟串口。记得高于4800就不大稳定了。现在的单片机快多了,中断也多的很,波特率高些应 ...

是的,按照9600波特率来算,一个比特位的时间大概为0.104 ms,用我的方法,需要4倍的采样率,那么一次中断的处理时间为26 us。按照STC 12T的单片机,12MHz的晶振,这段时间内只能执行26个指令,完全达不到实现多个串口的指令处理量,但是AVR的单片这段时间可以执行26*16 = 416 个指令,我的处理方法针对每一个串口,极限工况下需要约100条指令,按这样计算可以达到四路串口满负荷同时接收。实际上这个程序还有带有负载均衡功能的代码,可以在一个比特位中的四个时间片中分担不同的代码工作,以避免在26 us中出现多路串口同时需要大量时间处理的情况,充分利用一个比特位的104 us时间,这样可以执行416*4 = 1664条指令,同时处理8路毫无压力。同样,对于一路串口,一路发送需要执行的代码极限情况下需要70条指令,如果要处理8路则需要执行70*8 = 560条指令。那么在8路串口满负荷的情况下,需要执行560+800 = 1360条指令。可以看到还有1664-1360 = 304条指令的余量(对于1个比特位的时间),而这些指令余量正好用作数据帧检验及转发控制。实际上这种8路串口同时出现满负荷的工况是非常罕见的,所以ATmega8模拟这种多路串口还算无压力。

出0入0汤圆

发表于 2018-4-25 21:32:01 | 显示全部楼层
  还用AVR的就算了,不过可以看看思路,,,

出0入0汤圆

发表于 2018-4-25 22:44:10 来自手机 | 显示全部楼层
收藏  正好在研究这块

出0入0汤圆

发表于 2018-4-25 23:02:39 | 显示全部楼层
下载下来研究一下,刚好有个串口HUB类似的项目,谢谢楼主分享。

出0入0汤圆

发表于 2018-4-25 23:15:44 | 显示全部楼层
借鉴借鉴

出0入0汤圆

发表于 2018-4-25 23:20:27 | 显示全部楼层
学习了

出0入0汤圆

发表于 2018-4-29 09:25:52 | 显示全部楼层
谢谢楼主分享

出0入0汤圆

发表于 2018-4-29 09:30:03 | 显示全部楼层
看起来确实感觉很NB!

出0入0汤圆

发表于 2018-4-29 10:07:59 | 显示全部楼层
在这硬件资源横流的时代,还有这个必要吗

出0入0汤圆

 楼主| 发表于 2018-4-29 23:29:24 | 显示全部楼层
xieweibiao 发表于 2018-4-29 10:07
在这硬件资源横流的时代,还有这个必要吗

这个是看需求的。如果要求多路串口,找对应的多路串口单片机不好找,价格什么的没准也不能接受。所以这种做法有使用价值就行

出0入0汤圆

发表于 2018-5-1 13:37:25 | 显示全部楼层
思路还是值得学习的

出0入0汤圆

发表于 2018-5-1 17:50:31 来自手机 | 显示全部楼层
xieweibiao 发表于 2018-4-29 10:07
在这硬件资源横流的时代,还有这个必要吗

8串口的mcu应该不多,这个方案有实际意义。
退一步说,即使不用,方法和思路也是很不错的。
关键点是楼主的无私分享,谢谢楼主。

出0入0汤圆

发表于 2018-5-1 21:29:45 | 显示全部楼层
mark!这个好! 顶!

出0入42汤圆

发表于 2018-5-9 12:29:35 | 显示全部楼层
谢谢楼主无私分享,提供一个很好的思路

出0入0汤圆

发表于 2018-5-9 13:25:59 | 显示全部楼层
想法不错,攒个~

出0入0汤圆

发表于 2018-5-9 13:45:55 | 显示全部楼层
记一下,慢慢看。

出0入0汤圆

发表于 2018-5-24 15:42:57 | 显示全部楼层
一个很好的思路

出0入10汤圆

发表于 2018-5-24 16:31:05 | 显示全部楼层
设计巧妙!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 09:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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