我通過460Kbaud UART將數據從我的PIC24H微控制器傳輸到藍牙無線電模塊。在大多數情況下,此流程工作正常,藍牙模塊在其內部數據緩衝區已滿時使用CTS和RTS線路管理流量控制。但是,藍牙模塊中存在某種類型的錯誤,當數據連續發送到藍牙模塊時不會發生任何中斷,如果我的數據在另一個瓶頸中備份,就會發生這種錯誤。如何節制中斷驅動的UART傳輸PIC24H?
如果模塊能夠正常工作,那很好,但那不在我的控制範圍之內。所以看來,我唯一的選擇是在我的一端做一些數據調節,以確保不超過數據吞吐量限制(我大致通過實驗知道這一點)。
我的問題是如何實現數據速率的限制?
我當前UART實現是長1024個字節,主迴路中的數據寫入RAM圓形的FIFO緩衝器。當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字節,用於把上的數據吞吐量的上限的時間延遲。
保持在某個時間幀中發送的字節流水賬並且如果超過該時間跨度的最大字節數創建稍長的繼續傳輸之前延遲。
任何一個選項理論上都可以工作,我想知道它的實現。
描述模塊需要什麼樣的「休息」來工作...... –
@Ben Jackson如果我知道的話,這將是很好的。這是一個不是功能的bug,所以沒有記錄。基本上它會在持續吞吐量約3秒後重置,即使它是流量控制的。我平均可以獲得大約25kbps的吞吐量。 – CodeFusionMobile