Tôi đang truyền dữ liệu từ vi điều khiển PIC24H của tôi qua 460Kbaud UART sang mô-đun vô tuyến bluetooth. Trong hầu hết các điều kiện, dòng này hoạt động tốt và mô-đun bluetooth sử dụng các dòng CTS và RTS để quản lý kiểm soát luồng khi bộ đệm dữ liệu nội bộ của nó đầy. Tuy nhiên, có một loại lỗi trong mô-đun bluetooth đặt lại khi dữ liệu được liên tục gửi đến nó mà không bị gián đoạn, điều này xảy ra nếu dữ liệu của tôi được sao lưu trong một nút cổ chai khác.Làm thế nào để tăng tốc truyền dẫn UART gián đoạn PIC24H?
Sẽ tốt hơn nếu mô-đun hoạt động bình thường, nhưng đó là ngoài tầm kiểm soát của tôi. Vì vậy, có vẻ như lựa chọn duy nhất của tôi là làm một số dữ liệu điều chỉnh về phía tôi để đảm bảo rằng tôi không vượt quá giới hạn thông lượng dữ liệu (mà tôi biết gần bằng thử nghiệm).
Câu hỏi của tôi là cách triển khai điều chỉnh tốc độ dữ liệu?
Triển khai UART hiện tại của tôi là bộ đệm FIFO RAM tròn dài 1024 byte mà vòng lặp chính ghi dữ liệu vào. Một ngắt ngoại vi được kích hoạt bởi PIC khi byte cuối cùng đã được gửi ra bởi phần cứng UART và ISR của tôi đọc byte tiếp theo từ bộ đệm và gửi nó đến phần cứng UART.
Dưới đây là một ý tưởng về mã nguồn:
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];
}
}
Sửa
Có hai cách mà throttling thể được thực hiện như tôi thấy:
Thực thi một khoảng thời gian trễ giữa byte UART được viết để đặt giới hạn trên về thông lượng dữ liệu.
Giữ số đếm byte được truyền qua một khung thời gian nhất định và nếu vượt quá số byte tối đa cho khoảng thời gian đó tạo ra độ trễ lâu hơn một chút trước khi tiếp tục truyền.
Hoặc là tùy chọn về mặt lý thuyết sẽ hoạt động, việc triển khai của tôi sẽ tự hỏi.
Mô tả loại "ngắt" nào mà mô-đun yêu cầu hoạt động ... –
@Ben Jackson sẽ rất tuyệt nếu tôi biết. Đó là một lỗi không phải là một tính năng để nó không được ghi lại. Về cơ bản nó reset sau khoảng 3 giây thông lượng không đổi, mặc dù nó được điều khiển luồng. Tôi có thể lấy đi khoảng 25kbps thông lượng trung bình. – CodeFusionMobile