我正在使用PIC24H微控制器通过460Kbaud UART传输数据到蓝牙无线电模块。在大多数情况下,这个流程都很正常,当蓝牙模块的内部数据缓冲区满时,蓝牙模块使用CTS和RTS线路来管理流量控制。然而,蓝牙模块存在某种错误,当连续发送数据而没有任何休息时,它会被重置,这种情况会发生在我的数据在另一个瓶颈中被阻塞时。
如果模块能正常工作那就太好了,但这超出了我的控制范围。因此,我的唯一选择似乎是在我的端上进行一些数据限速,以确保我不超过数据吞吐量限制(我通过实验大致知道)。
我的问题是如何实现数据速率限制?
我的当前UART实现是一个RAM循环FIFO缓冲区,长度为1024字节,主循环将数据写入其中。当UART硬件发送出最后一个字节时,PIC触发外设中断,我的ISR从缓冲区读取下一个字节并将其发送到UART硬件。
以下是源代码的想法: uart_isr.c
如果模块能正常工作那就太好了,但这超出了我的控制范围。因此,我的唯一选择似乎是在我的端上进行一些数据限速,以确保我不超过数据吞吐量限制(我通过实验大致知道)。
我的问题是如何实现数据速率限制?
我的当前UART实现是一个RAM循环FIFO缓冲区,长度为1024字节,主循环将数据写入其中。当UART硬件发送出最后一个字节时,PIC触发外设中断,我的ISR从缓冲区读取下一个字节并将其发送到UART硬件。
以下是源代码的想法: 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];
}
}
编辑
在我看来,限流可以通过以下两种方式实现:
强制在UART字节之间施加时间延迟,从而对数据吞吐量设置上限。
记录在一定时间范围内传输的字节数,如果超过了该时间段内的最大字节数,则在继续传输之前创建稍长的延迟。
理论上,任何一种选项都可以起到限流的作用,但我想知道的是具体的实现方法。