gpt4 book ai didi

arm - 在小型 ARM 微 Controller 中实现 uart 接收缓冲器的正确方法?

转载 作者:行者123 更新时间:2023-12-04 14:50:35 28 4
gpt4 key购买 nike

我正在为一个小型应用程序寻找接收缓冲区的想法,该应用程序通过 rs485 处理 921.6Kbaud 的 15 字节数据包。我正在考虑使用循环缓冲区作为 UART ISR 和 main 之间的接口(interface)。因为它是一个微处理器,我想把

while (uartindex!=localindex) { do stuff } 

在里面
while (;;) {do forever} 

主要的一部分,但我被告知这是 Not Acceptable 。

在类似情况下,人们如何处理他们的 UART?

最佳答案

ISR 应该填充一个 FIFO。主要应该消耗它。

下面是一个非常简单的fifo算法:

#define RINGFIFO_SIZE (1024)              /* serial buffer in bytes (power 2)   */
#define RINGFIFO_MASK (RINGFIFO_SIZE-1ul) /* buffer size mask */

/* Buffer read / write macros */
#define RINGFIFO_RESET(ringFifo) {ringFifo.rdIdx = ringFifo.wrIdx = 0;}
#define RINGFIFO_WR(ringFifo, dataIn) {ringFifo.data[RINGFIFO_MASK & ringFifo.wrIdx++] = (dataIn);}
#define RINGFIFO_RD(ringFifo, dataOut){ringFifo.rdIdx++; dataOut = ringFifo.data[RINGFIFO_MASK & (ringFifo.rdIdx-1)];}
#define RINGFIFO_EMPTY(ringFifo) (ringFifo.rdIdx == ringFifo.wrIdx)
#define RINGFIFO_FULL(ringFifo) ((RINGFIFO_MASK & ringFifo.rdIdx) == (RINGFIFO_MASK & (ringFifo.wrIdx+1)))
#define RINGFIFO_COUNT(ringFifo) (RINGFIFO_MASK & (ringFifo.wrIdx - ringFifo.rdIdx))

/* buffer type */
typedef struct{
uint32_t size;
uint32_t wrIdx;
uint32_t rdIdx;
uint8_t data[RINGFIFO_SIZE];
} RingFifo_t;
RingFifo_t gUartFifo;

(必须注意此 FIFO 算法,大小必须是 2 的幂)

ISR 的行为应如下所示:
void ISR_Handler()
{
uint8_t c;
while(UART_NotEmpty()) {
c = UART_GetByte();
RINGFIFO_WR(gUartFifo, c);
}
}

主要:
while(1)
{
if (!RINGFIFO_EMPTY(gUartFifo)) {
/* consume fifo using RINGFIFO_RD */
}
}

该算法直接从主循环读取 FIFO,您应该使用一个中间层来检查缓冲区中是否有一个完整的数据包,并以这样的方式处理它,main 将是这样的:
uint8_t ptrToPacket;
uint32_t packetSize;
while(1)
{
if (!Uart_HasValidPacket()) {
Uart_GetPacket(&ptrToPacket, &packetSize)
/* Process packet using ptrToPacket and packetSize */
}
}

关于arm - 在小型 ARM 微 Controller 中实现 uart 接收缓冲器的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6822548/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com