简体   繁体   English

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

[英]UART Serial Bridge using MSP430 FR5994

I am trying to create a UART bridge using MSP430.我正在尝试使用 MSP430 创建一个 UART 桥。 I have a sensor sending strings to the MSP430 which I intend to send to my PC.我有一个传感器向 MSP430 发送字符串,我打算将其发送到我的 PC。 Additionally, the sensor responds to commands which I intend to send using my PC through the MSP430 bridge.此外,传感器响应我打算使用我的 PC 通过 MSP430 桥发送的命令。 The commands I am sending to the sensor reach it without any flaw.我发送到传感器的命令可以毫无瑕疵地到达它。 However, the messages sent by the sensor reach the TXBUF of the UART connected to my PC but does not appear on the terminal.但是,传感器发送的消息到达了连接到我的 PC 的 UART 的 TXBUF,但没有出现在终端上。 On checking the registers I see 0x000A on the TXBUF but it appears to recieve all the chahracters.在检查寄存器时,我在 TXBUF 上看到 0x000A,但它似乎收到了所有字符。 But nothing is printed.但是没有打印任何内容。

I am using the following code:我正在使用以下代码:

#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;
}

} }

Please help.请帮忙。 Thanks in advance.提前致谢。

First, the problems that I see with your listing:首先,我在您的列表中看到的问题:

(p1) Even though the baud rates of both UARTs are the same, your design does not make use of proper (see problem 3 below) buffering in the event that both the PC and the sensor is sending data at the same time. (p1) 即使两个 UART 的波特率相同,您的设计也不会在 PC 和传感器同时发送数据的情况下使用适当的(参见下面的问题 3)缓冲。 To make matters worse, both your ISRs contain blocking while loops that don't buffer and only waste time until the interrupt flags clears.更糟糕的是,您的两个 ISR 都包含阻塞 while 循环,这些循环不缓冲并且只会浪费时间直到中断标志清除。

(p2) Your source (shown below) is likely coded in error: (p2) 您的来源(如下所示)可能编码有误:

while(!(UCA1IFG&UCTXIFG));          //Trying to read a string
{
  *(msg+i) = UCA1RXBUF;
  j = *(msg+i);
  UCA3TXBUF = j;
  i++;
}

because the body of the while loop is actually empty due to the trailing ";"因为 while 循环的主体由于尾随“;”而实际上是空的so the code within the open/closing brackets that follows is not part of the while loop.所以后面的开/关括号内的代码不是while循环的一部分。

(p3) The pointer variable msg was never initialized. (p3) 指针变量msg从未被初始化。 Most likely it points to random heap memory or unused portion of the stack, so the program doesn't crash right away.它很可能指向随机堆内存或堆栈的未使用部分,因此程序不会立即崩溃。 Eventually, it would because the variable i is incremented but never decremented, so memory is "one time used" by the sensor ISR.最终,这是因为变量i增加但从未减少,因此传感器 ISR“一次使用”内存。

My suggestions:我的建议:

(s1) Declare two buffers, one for data arriving from the PC and the other for data arriving from the sensor. (s1) 声明两个缓冲区,一个用于来自 PC 的数据,另一个用于来自传感器的数据。 Remove the "unsigned char *msg" and replace with something like this:删除“unsigned char *msg”并替换为如下内容:

unsigned char pc_data[256];
unsigned char sensor_data[256];

The size 256 is on purpose to create a poor-mans circular buffer when used with an 8-bit index variable.大小 256 是为了在与 8 位索引变量一起使用时创建穷人循环缓冲区。 When the variable reaches 255 and is incremented, it will simply roll back to 0. In this case both i and j as you already declared can be used, but maybe pc_data_index and sensor_data_index would be better understood.当变量达到 255 并递增时,它将简单地回滚到 0。在这种情况下,您已经声明的ij都可以使用,但也许pc_data_indexsensor_data_index会更好地理解。 You also need two more variables for the size of the buffer, maybe pc_data_count and sensor_data_count .您还需要另外两个用于缓冲区大小的变量,可能是pc_data_countsensor_data_count If your procssor cannot afford this much buffer space, then decrease to a modular amount (ie, 2^BUFSIZE, where BUFSIZE = 32) and use the modular operator when updating the index like this:如果您的处理器无法承受这么多的缓冲区空间,则减少到模块化数量(即 2^BUFSIZE,其中 BUFSIZE = 32)并在更新索引时使用模块化运算符,如下所示:

pc_data_index = (pc_data_index + 1) % BUFSIZE;

(s2) Change both ISR routines to process both the USCI_UART_UCRXIFG and USCI_UART_UCTXIFG interrupt events. (s2) 更改两个 ISR 例程以处理 USCI_UART_UCRXIFG 和 USCI_UART_UCTXIFG 中断事件。 The ISRs should not contain any loops, simply buffer data or write data out from buffer. ISR 不应包含任何循环,只需缓冲数据或从缓冲区写出数据。 Here is an example:下面是一个例子:

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