簡體   English   中英

使用 MSP430 FR5994 的 UART 串​​行橋接器

[英]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。在這種情況下,您已經聲明的ij都可以使用,但也許pc_data_indexsensor_data_index會更好地理解。 您還需要另外兩個用於緩沖區大小的變量,可能是pc_data_countsensor_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM