gpt4 book ai didi

c - 如何限制中断驱动的 UART 传输 PIC24H?

转载 作者:太空狗 更新时间:2023-10-29 17:03:23 25 4
gpt4 key购买 nike

我正在通过 460Kbaud UART 将数据从我的 PIC24H 微 Controller 传输到蓝牙 radio 模块。在大多数情况下,这个流程工作得很好,蓝牙模块在其内部数据缓冲区已满时使用 CTS 和 RTS 线路来管理流程控制。但是,蓝牙模块中存在某种错误,当数据连续不断地发送给它时,蓝牙模块会重置它,如果我的数据在另一个瓶颈中备份,就会发生这种情况。

如果模块能正常工作就好了,但这不在我的控制范围内。因此,我唯一的选择似乎是在我这边进行一些数据限制,以确保我不超过数据吞吐量限制(我通过实验大致知道)。

我的问题是如何实现数据速率限制?

我当前的 UART 实现是一个 1024 字节长的 RAM 循环 FIFO 缓冲区,主循环将数据写入其中。当最后一个字节已由 UART 硬件发出并且我的 ISR 从缓冲区读取下一个字节并将其发送到 UART 硬件时,PIC 会触发外设中断。

这是源代码的想法:

uart_isr.c

//*************** Interrupt Service routine for UART2 Transmission  
void __attribute__ ((interrupt,no_auto_psv)) _U2TXInterrupt(void)
{
//the UART2 Tx Buffer is empty (!UART_TX_BUF_FULL()), fill it
//Only if data exists in data buffer (!isTxBufEmpty())
while(!isTxBufEmpty()&& !UART_TX_BUF_FULL()) {
if(BT_CONNECTED)
{ //Transmit next byte of data
U2TXREG = 0xFF & (unsigned int)txbuf[txReadPtr];
txReadPtr = (txReadPtr + 1) % TX_BUFFER_SIZE;
}else{
break;
}
}
IFS1bits.U2TXIF = 0;
}

uart_methods.c

//return false if buffer overrun
BOOL writeStrUART(WORD length, BYTE* writePtr)
{
BOOL overrun = TRUE;
while(length)
{
txbuf[txWritePtr] = *(writePtr);
//increment writePtr
txWritePtr = (txWritePtr + 1) % TX_BUFFER_SIZE;
if(txWritePtr == txReadPtr)
{
//write pointer has caught up to read, increment read ptr
txReadPtr = (txReadPtr + 1) % TX_BUFFER_SIZE;
//Set overrun flag to FALSE
overrun = FALSE;
}

writePtr++;
length--;
}

//Make sure that Data is being transmitted
ensureTxCycleStarted();

return overrun;
}


void ensureTxCycleStarted()
{
WORD oldPtr = 0;
if(IS_UART_TX_IDLE() && !isTxBufEmpty())
{
//write one byte to start UART transmit cycle
oldPtr = txReadPtr;
txReadPtr = (txReadPtr + 1) % TX_BUFFER_SIZE;//Preincrement pointer
//Note: if pointer is incremented after U2TXREG write,
// the interrupt will trigger before the increment
// and the first piece of data will be retransmitted.
U2TXREG = 0xFF & (unsigned int)txbuf[oldPtr];
}
}

编辑
在我看来,可以通过两种方式实现节流:

  1. 在要写入的 UART 字节之间强制执行时间延迟,这对数据吞吐量设置了上限。

  2. 保持在特定时间范围内传输的字节数的运行计数,如果超过该时间跨度的最大字节数,则在继续传输之前创建稍长的延迟。

这两种选择在理论上都可行,我想知道它的实现方式。

最佳答案

也许配额方法就是您想要的。使用相关时间尺度的周期性中断,将“要传输的字节数”的配额添加到全局变量,直到您不超过针对相关洪水调整的某个级别。然后在你来发送一个字节之前检查是否有配额。在新的传输中,最初会出现大量洪水,但随后配额会限制传输速率。

~~some periodic interrupt
if(bytes_to_send < MAX_LEVEL){
bytes_to_send = bytes_to_send + BYTES_PER_PERIOD;
}
~~in uart_send_byte
if(bytes_to_send){
bytes_to_send = bytes_to_send - 1;
//then send the byte

关于c - 如何限制中断驱动的 UART 传输 PIC24H?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6602933/

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