我最近在我的职业生涯中遇到了类似的问题。我们用完了硬件 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(高电平有效或低电平有效),并为一个“位时间”(波特率的倒数)设置一个硬件计时器。
如果需要流量控制,您只需在进入主动接收之前添加另一种简单的轮询方法,以便设备知道它是“允许”通信的。
如果启用了奇偶校验位,则还需要在传输期间与数据一起发送或在接收后处理这些位,以确定数据是否成功传输。
谷歌搜索“software uart”将得到许多来自 ATMEL 的 AVR 芯片示例,以及其他详细说明如何实施的示例。这个应用笔记对基础知识和基础理论很有帮助,本页 ZIP 中链接的代码确实有助于解释如何对其进行编码。
希望这能给你一些好的起点。