我最近在职业生涯中遇到了类似的问题。我们用完了硬件 UART,需要在 GPIO 上使用单线实现 UART 协议。
现在,如果我对您的理解正确(或者我是否错过了您所询问的特定架构?),您正在尝试在某种可以(或正在)运行 linux 的微处理器上实现这一点。根据您的硬件和可用的调试工具/编程器类型,您几乎有两种选择来获得基本的裸机(阅读:无操作系统)UART 通信运行,可以通过串行端口配置进行扩展(并且通常是简化)在操作系统级别的 linux 内核中。我不会详细介绍在操作系统级别配置串行端口,但是如果您可以在裸机上进行配置,则可以在操作系统中进行;我将重点介绍这两个基本解决方案。
编辑:我现在意识到您确实处于成熟的操作系统中。以下所有内容均适用于您必须开发并与 Gautham Kantharaju 描述的调用相关联的固件。所以软件 UART 可能并不完全有帮助。
这些是:
- 您的微控制器/微处理器上的硬件 UART 端口已经具有用于 UART 配置和 FIFO 的专用寄存器。
- 您只能访问 GPIO 模块,并且只能访问纯 GPIO 功能 - 输出逻辑高/低、中断配置(上升沿中断、下降沿中断;发送中断到向量或 DMA 请求等)。和一个输入数据寄存器。
无论哪种情况,您都需要查看微处理器的数据表和参考手册,以首先了解其 UART 寄存器的工作原理。您还几乎肯定会找到在您的芯片上实现和启用 UART 的应用说明。它在硬件中是相当标准的,它们之间只有微小的差异。几乎总是有代码示例可以为您完成这些任务,但根据您的需要,您可能必须至少修改一些配置设置。
你应该看到某种形式的寄存器:
- 某种形式的启用寄存器可有效地为模块供电。这可能涉及取消时钟寄存器(没有时钟模块无法运行)和其他一些可能更具体的硬件步骤。
- 注册设置流控制。这里可以有很多。一起启用流控制,CTS线是否高/低有效,是否启用中断以及中断标志在哪里等。
- 通用 UART 配置(可能这将是初始化阶段的一部分,因为某些 UART [例如飞思卡尔的 ARM] 可以通过写入配置寄存器来初始化。这些是您将看到停止位数、数据位数的地方、奇偶校验位等。使用UART可以配置的东西很多……这是一个非常成熟的标准。
- 您的 FIFO 寄存器以及如何访问它们。
同样,您的库/应用程序堆栈可能会包含提供宏和函数以完成所有这些配置选项的示例,并且在许多情况下默认配置将起作用。您可能需要进入串行驱动程序(通常是serial.c)并更改代码以满足您的需要,但是如果您知道寄存器和配置发生了什么,那么了解哪些设置会更容易
现在,如果是后者,你需要实现一个软件UART。那里有很多示例,但除非您了解 GPIO 引脚的端口控制的来龙去脉以及 UART 硬件完成的细节,否则它对您没有任何好处。这听起来比实际困难得多。您希望有两条线路:一条用于 RX,一条用于 TX。如果您不需要流量控制,那么这就是您所需要的。否则,您将需要 RTS 和 CTS 线路。这些只是简单的 GPIO,通过 RTS 引脚上驱动的“活动”逻辑电平(可以是高电平或低电平,具体取决于硬件 - 阅读您的数据表)来控制方向,以指示 请求发送 和来自 CTS 行的确认,表明现在可以开始传输了。
假设暂时没有流量控制,让我们从简单的接收开始。基本上,您需要在起始位上进行某种形式的中断。在中断的处理程序中,启动某种硬件定时器(您必须配置另一个寄存器/模块),并以周期性间隔对 RX 线进行采样,直到数据帧结束(start_bit + data_bits + stop_bit(s) + parity_bit)或使用计时器来计时一条线保持高/低的时间,并在另一个函数中执行一些数学运算(不在中断处理程序中!)。在大多数情况下,您将需要前一种计时器,但如果有一个有趣的设备涉及特定的握手,您可能需要更灵活的计时并选择第二种形式的采样传入数据。此外,缓冲区在调试时将非常有用且必不可少,因此您可能非常希望在实施此操作时牢记这一点。
要传输,您需要禁用中断(或屏蔽它们),以便您的传输不会被中断(对于单线实现尤其重要)。然后,您必须解析数据以确定每个位是 1 还是 0(高电平有效或低电平有效),并为一个“位时间”(波特率的倒数)设置一个硬件计时器。
如果需要流量控制,您只需在进入主动接收之前添加另一个简单的轮询方法,以便设备知道它是“允许”进行通信的。
如果启用了奇偶校验位,则还需要在传输期间处理这些位,以便与数据一起发送出去,或者在接收之后确定数据是否传输成功。
Google 搜索“software uart”会得到许多来自 ATMEL 的 AVR 芯片示例,以及其他详细说明如何实施的示例。 This app note is good for the basics and underlying theory 和此页面上 ZIP 中链接的代码really helps explain how to code it。
希望这能给你一些好的起点。