[英]UART Serial Bridge using MSP430 FR5994
我正在嘗試使用 MSP430 創建一個 UART 橋。 我有一個傳感器向 MSP430 發送字符串,我打算將其發送到我的 PC。 此外,傳感器響應我打算使用我的 PC 通過 MSP430 橋發送的命令。 我發送到傳感器的命令可以毫無瑕疵地到達它。 但是,傳感器發送的消息到達了連接到我的 PC 的 UART 的 TXBUF,但沒有出現在終端上。 在檢查寄存器時,我在 TXBUF 上看到 0x000A,但它似乎收到了所有字符。 但是沒有打印任何內容。
我正在使用以下代碼:
#include <msp430.h>
unsigned char *msg;
unsigned char i=0 , j=0;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
// Pin Initialization
P6SEL1 |= BIT1;
P6SEL0 &= ~BIT1;
P6SEL1 |= BIT0;
P6SEL0 &= ~BIT0;
P2SEL1 |= BIT5;
P2SEL0 &= ~BIT5;
P2SEL1 |= BIT6;
P2SEL0 &= ~BIT6;
PM5CTL0 &= ~LOCKLPM5;
// UART Initialization
UCA1CTLW0 |= UCSWRST;
UCA1CTLW0 |= UCSSEL__SMCLK; // Using 1 MHZ clock
UCA3CTLW0 |= UCSWRST;
UCA3CTLW0 |= UCSSEL__SMCLK;
UCA3BRW = 6; // Baud Rate set to 9600
UCA3MCTLW = UCOS16 | UCBRF_8 | 0x2000;
UCA1BRW = 6;
UCA1MCTLW = UCOS16 | UCBRF_8 | 0x2000;
UCA3CTLW0 &= ~UCSWRST;
UCA1CTLW0 &= ~UCSWRST;
UCA3IE |= UCRXIE;
UCA1IE |= UCRXIE;
__enable_interrupt(); // Interrupt enable
while (1)
{}
}
// UART A3 connected to the PC.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A3_VECTOR
__interrupt void USCI_A3_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A3_VECTOR))) USCI_A3_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCA3IV, USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
while(!(UCA3IFG&UCTXIFG));
UCA1TXBUF = UCA3RXBUF;
__no_operation();
break;
case USCI_UART_UCTXIFG: break;
case USCI_UART_UCSTTIFG: break;
case USCI_UART_UCTXCPTIFG: break;
default: break;
}
}
// UART A1 connected to the sensor.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A1_VECTOR))) USCI_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
while(!(UCA1IFG&UCTXIFG)); //Trying to read a string
{
*(msg+i) = UCA1RXBUF;
j = *(msg+i);
UCA3TXBUF = j;
i++;
}
break;
case USCI_UART_UCTXIFG: break;
case USCI_UART_UCSTTIFG: break;
case USCI_UART_UCTXCPTIFG: break;
default: break;
}
}
請幫忙。 提前致謝。
首先,我在您的列表中看到的問題:
(p1) 即使兩個 UART 的波特率相同,您的設計也不會在 PC 和傳感器同時發送數據的情況下使用適當的(參見下面的問題 3)緩沖。 更糟糕的是,您的兩個 ISR 都包含阻塞 while 循環,這些循環不緩沖並且只會浪費時間直到中斷標志清除。
(p2) 您的來源(如下所示)可能編碼有誤:
while(!(UCA1IFG&UCTXIFG)); //Trying to read a string
{
*(msg+i) = UCA1RXBUF;
j = *(msg+i);
UCA3TXBUF = j;
i++;
}
因為 while 循環的主體由於尾隨“;”而實際上是空的所以后面的開/關括號內的代碼不是while循環的一部分。
(p3) 指針變量msg從未被初始化。 它很可能指向隨機堆內存或堆棧的未使用部分,因此程序不會立即崩潰。 最終,這是因為變量i增加但從未減少,因此傳感器 ISR“一次使用”內存。
我的建議:
(s1) 聲明兩個緩沖區,一個用於來自 PC 的數據,另一個用於來自傳感器的數據。 刪除“unsigned char *msg”並替換為如下內容:
unsigned char pc_data[256];
unsigned char sensor_data[256];
大小 256 是為了在與 8 位索引變量一起使用時創建窮人循環緩沖區。 當變量達到 255 並遞增時,它將簡單地回滾到 0。在這種情況下,您已經聲明的i和j都可以使用,但也許pc_data_index和sensor_data_index會更好地理解。 您還需要另外兩個用於緩沖區大小的變量,可能是pc_data_count和sensor_data_count 。 如果您的處理器無法承受這么多的緩沖區空間,則減少到模塊化數量(即 2^BUFSIZE,其中 BUFSIZE = 32)並在更新索引時使用模塊化運算符,如下所示:
pc_data_index = (pc_data_index + 1) % BUFSIZE;
(s2) 更改兩個 ISR 例程以處理 USCI_UART_UCRXIFG 和 USCI_UART_UCTXIFG 中斷事件。 ISR 不應包含任何循環,只需緩沖數據或從緩沖區寫出數據。 下面是一個例子:
switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
// Byte was received from sensor, so buffer it
sensor_data[sensor_data_count++] = UCA1RXBUF;
sensor_data_index = (sensor_data_index + 1) % BUFSIZE;
// Enable the TX interrupts to send the buffered data
UCA1IE |= UCTXIE;
break;
case USCI_UART_UCTXIFG:
// Sensor UART is ready to send next byte
UCA3TXBUF = sensor_data[sensor_data_index];
sensor_data_count--;
// Disable the TX interrupt if no more data to send
if (sensor_data_count == 0) UCA1IE &= ~UCTXIE;
break;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.