用于面包板上8位计算机的UART收发器

最近,我越来越喜欢用TTL芯片组装8位计算机Ben IterYouTube上的精彩视频以及Hackaday网站上的各种项目给我带来了启发。在设计和组装自己的8位计算机的过程中,我考虑了实现基于7400系列IC的UART收发器有多困难





最终电路:由7400系列IC组装的成品UART收发器



首先,让我们弄清楚UART是什么...它是一种通用的异步收发器-一种简单的协议,允许您异步发送和接收8位数据,以便处理器或计算机可以与外界通信。这本身就很有用-我的8位计算机可以与笔记本电脑通信,并可以使用串行端口监视程序(如putty)作为文本输入和输出的接口。更有趣的是,我可以为我的8位计算机编程OS引导程序,然后通过笔记本电脑的UART连接对其进行编程!由于HC-05型蓝牙模块实际上是通过UART与CPU通信的,所以我什至可以使用蓝牙模块远距离编程我的8位计算机!这将是惊人的。



一些纯粹主义者会认为用欺诈手段来对8位计算机和功能更强大的计算机进行编程是一种欺诈方法-但这是我的项目,它符合我的规则!如果您喜欢数据输入而不是编程,并且想要真实的辛勤工作体验,请使用DIP开关对手动机器进行编程。



无论采用何种编程方式,至少在开发计算机以使用简单的TTL芯片时,我都决定限制自己-不使用Arduino,Raspberry Pi,ESP8266和其他图灵完备的模块(否则,您会感兴趣吗?)。



UART协议和设计限制



之前是UART信号结构。它具有一个起始位,用信号从高到低的跳变表示,后跟一个数据字节(首先是LSB),然后是一个停止位,它将信号驱动为高电平。有时也有一个奇偶校验位,但这不是必需的,因此为简单起见,我将其省略。每个位的传输时间取决于波特率(在这种情况下,是每秒的位)。例如,9600的波特率意味着在

1/9600 = 104μs内发送一个比特。波形非常简单,因此我们可以完全在逻辑芯片上的硬件中实现它。







我必须选择一个晶体振荡器,该晶体振荡器可以使我获得标准的波特率,最好可以将其除以2的幂,以便使用二进制计数器进行操作很方便。经过一番思考,我决定使用2.4576 MHz振荡器,因为它允许以38400 bps(除以64)或9600 bps(除以256)进行传输。



UART发送器



组件清单:



  • 2.4576 MHz晶体振荡器
  • 3 x 74LS161 4位计数器
  • 74LS674 16位移位寄存器
  • 74LS06和
  • 74LS74 D触发器
  • 74LS04不是
  • 二极管1N4001
  • 470 uF(!)电容器(电源平滑)


方案



UART发送器最容易理解。基本上,它是具有串行输出的并行负载移位寄存器。它加载数据字节,跟踪起始位和结束位,并将其同步到所需的波特率。下图显示了此过程。在第(1)部分中,使用两个4位74LS161计数器将2.4576 MHz晶体振荡器减慢到38400 Hz。在第(2)部分中,使用74LS674 16位移位寄存器为UART同步数据。我使用此寄存器是因为我已经拥有了它。我知道该IC价格昂贵,可能很难找到,但可以肯定地简化了我的整个方案。







仅使用这些IC中的三个(两个4位计数器和一个移位寄存器),您就可以以38,400 bps(无奇偶校验)的速度向UART发送器发送连续的字符流!是的,它是连续的流-我没有考虑到移位寄存器会一圈更新加载缓冲区-哎呀。我不需要这种行为-我希望处理器一次发送一个字节。处理器和UART的时钟脉冲不同步,使事情变得复杂,我不想假设谁的定时器更快,哪个信号在什么时候才有意义等。由于我需要可靠地处理异步问题,因此我决定使用效果很好的以下方案:



  • (3)处理器发送与处理器和UART时钟不同步的字节传输信号。
  • «». ( AND 74LS06 D- 74LS74).
  • UART «» 4- 74LS161. UART.
  • (4) 16 , .


请注意,我将UART发送器信号移位了16位而不是10位-主要是因为使用进位来禁用发送电路很方便。我可以使用十进制计数器(例如74LS162),但是在电路板上组装电路时手头没有一个。也许在最终方案中,我会切换到它。



UART接收器



组件清单:



  • 2.4576 MHz晶体振荡器(可以使用与接收器相同的振荡器)
  • 3个74LS161 4位计数器(可以使用接收器中的IC之一)
  • 74LS74 D触发器
  • 74LS04 NOT(可以使用接收器IC)
  • 二极管1N4001
  • 470 uF(!)电容器(电源平滑)
  • 220欧姆电阻器和LED美观。


在我看来,如果上述UART发送器很容易理解,那么接收器将更加复杂。但是,数字逻辑的优点是可以将其拆分为单独的模块,然后一切似乎都不再那么复杂了!



下图左下角的波形显示了接收单个数字发送器位时要考虑的事项。我们如何知道某个字节是否正在发送给我们?容易-起始位由高到低的跳变指示,因此我们可以对其进行反转,并使用低到高的跳变来设置D触发器(74LS74)(2)。



现在我们需要通过将信号移入移位寄存器并在数据位序列的中心进行采样来开始写入信号。重要的是要理解:由于我们不知道何时开始从UART接收数据,因此此过程将不会与我们的时钟脉冲同步。因此,我们的脉冲越快,我们就越接近发射机信号的真实起源。为了方便起见,我的时钟速度是波特率(1)的16倍。这意味着每个发送的位都要经过该发生器的16个脉冲。因此,为了大约在传输数据的中间进行采样,我们必须以8计数进行采样-为此,我们生成了SAMPLING_CLK(3)信号。



然后,在这个新时钟的上升沿,我们可以将传输的信号与每个数据位中间的两个相关的8位串行并行输出移位寄存器(SIPO)进行同步。在第16个计数处,我们以一个数字位结束,因此我们增加了另一个计数器,该计数器跟踪(5)中已同步的总位数。当该计数器达到16(可能是十进制计数器)时,通过清除D触发器来禁用接收电路。 !我给出以下图表,希望您能够使用我的描述来跟踪其操作的逻辑。







不幸的是,我没有示波器,最初我的电路给出了一些神秘的结果,接受一个字节,然后以不同的方式接受另一个字节。我将2.4576 MHz振荡器更改为1秒555振荡器,以检查计数逻辑,然后发现其中一个计数器的引脚上的浮动输入存在问题(我正在使用LED进行调试)。我将两个计数器重置引脚都连接到RX_active信号,导致计数器在开启和重置之间切换,这会在每个数据采集周期结束时清除其输出。计数器现在可以按预期工作,当我将振荡器放回2.4576 MHz时,一切开始正确可靠地工作。



面包板上的最终计算机电路将具有输出寄存器,以控制输出到总线的数据。最后,我在74LS74上使用了一个额外的D触发器来实现RX_READY信号,处理器可以读取该信号来检查是否准备好读取该字节(仅当该字节已被完全接收时才为真)。



下面是已组装且正在运行的计算机的照片。UART-USB接口是右上方的加密狗。中间板包含一个晶体振荡器和生成各种时钟脉冲的4位计数器。在USB电源旁边的顶部是一个16位移位寄存器。左板包含用于控制发送一个字节(UART TX)的逻辑。您可以看到用来模拟处理器控制信号的按钮和555定时器(用作处理器时钟脉冲)。UART RX模块位于右侧板上。绿色LED指示输入处已到达一个字节,黄色LED指示已接收数据(UART RX忙信号),当该字节准备好被处理器读取时,红色LED会亮起。





寻找更漂亮的面包板和接线技巧



加成



我对电路进行了一些优化(沿途学习了有关在离散IC逻辑中处理异步事件和同步事件之间的区别的课程)。我想通过使用一个十进制计数器来减少输入芯片的数量,该计数器将对输入的位进行计数,并计数10位而不是16位。然后可以删除移位寄存器。



我首先尝试了74LS162计数器。对于一个字节,一切正常,但是我很快发现它具有同步复位机制-也就是说,需要一个时钟周期来复位信号。由于时钟在接收到最后一位后停止,因此未清除计数器。我卸下的74LS161 4位计数器进行了异步复位,因此以前一切正常。很好的是,我们找到了一个带异步复位的十进制计数器-74LS160。一切对他都很好-请查看更新的图表。







检查接收字节中的错误



为简单起见,我没有在结果字节中添加任何错误检查。您可以想象我们添加了一个奇偶校验位,并在每次接收到“ 1”时切换触发器。然后,我们将知道我们接收到的是偶数还是奇数位数,并且可以通过在不匹配时设置标志来将其与奇偶校验位进行比较。另外,这可以包括停止位等于“ 1”的验证检查。为了节省空间,我没有添加此功能,但是我想在将来添加它。项目的模块化允许您根据需要执行此操作。



笔记



我喜欢面包板上的8位计算机,并且喜欢做这个小型项目。我已经设计了该电路已有一段时间,当我将其放在一起并且一切正常时,我仍然感到震惊。这是某种魔术!几乎。



All Articles