Cod*_*ile 8 c embedded microcontroller interrupt
我通过460Kbaud UART将PIC24H单片机的数据传输到蓝牙无线电模块.在大多数情况下,此流程工作正常,蓝牙模块使用CTS和RTS线路来管理其内部数据缓冲区已满时的流量控制.但是,蓝牙模块中存在某种类型的错误,当数据连续发送到它而没有任何中断时会重置它,如果我的数据在另一个瓶颈中备份,就会发生这种情况.
如果模块正常工作会很好,但这是我无法控制的.因此,似乎我唯一的选择是在我的端部进行一些数据限制,以确保我不超过数据吞吐量限制(我通过实验大致知道).
我的问题是如何实现数据速率限制?
我当前的UART实现是一个RAM循环FIFO缓冲区,其长度为1024字节,主循环将数据写入.当最后一个字节由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;
}
Run Code Online (Sandbox Code Playgroud)
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];
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
我认为有两种方法可以实现限制:
在要写入的UART字节之间强制执行时间延迟,这会对数据吞吐量设置上限.
保持在某个时间帧内传输的字节运行计数,如果超过该时间跨度的最大字节数,则在继续传输之前产生稍长的延迟.
任何一个选项在理论上都可行,它是我想知道的实现.
小智 3
也许配额方法正是您想要的。使用相关时间尺度的定期中断,将“要传输的字节”配额添加到全局变量,以确保您不会超过针对相关洪水调整的某个级别。然后在发送字节之前检查是否有配额。在新的传输中,最初会出现大量的传输,但随后配额将限制传输速率。
~~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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2440 次 |
| 最近记录: |