This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR5994:使用 UART 接收数据

Guru**** 656470 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1167735/msp430fr5994-receiving-data-by-using-uart

器件型号:MSP430FR5994

大家好

我想通过 UART 从 CCS 终端接收数据。 我将波特率固定为9600。 并初始化 LED、以便在终端的数据匹配时闪烁。 但是当我通过终端写入数据时、LED 指示灯不亮、终端上有一些垃圾正在打印。所以、有人能帮我获得正确的输出。 我在这里共享代码。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   正是 C///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   

#include
#include
#include
#include
#include
#include

unsigned char addr[30]="";

void pin_setup()

P1DIR = 0x02;
P1OUT =~0x02;


void clk_setp()

CSCTL0_H = CSKKEY_H;
CSCTL1 = DCOFSEL_6;//8MHz |DCOFSEL_0 -1MHz
CSCTL2 = SELA_VLOCLK | SELESS__DCOCLK | SELM_DCOCLK;//设置 SMCLK = MCLK = DCO
CSCTL3 = DIVA_1|DIVS_1|DIVM_1;
CSCTL0_H = 0;


空 UART_CONFIG ()

P2SEL0 &=~(BIT0 | BIT1);
P2SEL1 |=(BIT0 | BIT1);// USCI_A0 UART 操作
PM5CTL0 &=~LOCKLPM5;
UCA0CTLW0=UCSWRST;
UCA0CTLW0 |=UCSSEL_SMCLK;
UCA0BRW = 52;
UCA0MCTLW |= UCOS16 | UCBRF_1 | 0x49;
UCA0CTLW0 &=~UCSWRST;//初始化 eUSCI
UCA0IE |= UCRXIE;//启用 USCI_A0 RX 中断


空 UART_Receive ()

PIN_setup();
_bis_SR_register (LPM0_bits|GIE);
sprintf (addr、"%s\r\n、RXData);
if (addr="y")

P1OUT=0x02;


int main (空)

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
clk_setp ();
UART_CONFIG();

while (1)

UART_Receive ();

返回0;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   UART.H   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include
#include
#include

volatile int rx_index=0;
volatile unsigned int rx_key=0;
volatile int Tx_index=0;
volatile unsigned int Tx_key=0;
int size=0;
unsigned char TXData[15]="";
unsigned char RXData[5]="";

#pragma vector = EUSCI_A0_Vector
_interrupt void USCI_A0_ISR (void)

switch (__evo_in_range (UCA0IV、USCI_UART_UCTXCPTIFG))

USCI_NONE 案例:中断;
USCI_UART_UCRXIFG 案例:
RX_KEY = 0;
RXData[RX_index]=UCA0RXBUF;
if (((RXData[RX_index]='\x0d'/*'\r'*/)||(RXData[RX_index]='\n')||(RXData[RX_index]=='\r'))

_BIC_SR_REGISTER_ON_EXIT (CPUOFF|GIE);
UCA0IE &=~UCRXIE;
RX_index=0;
RX_KEY = 0;
中断;

RX_index++;
中断;
USCI_UART_UCTXIFG 案例:
if (Tx_key=1)

if (Tx_index>size)

_BIC_SR_REGISTER_ON_EXIT (CPUOFF|GIE);
UCA0IE &=~UCTXIE;
UCA0IE &=~UCTXCPTIE;
TX_KEY = 0;
中断;

UCA0TXBUF = TXData[Tx_index];
TX_index++;
TX_KEY = 0;

中断;
案例 USCI_UART_UCSTTIFG:中断;
USCI_UART_UCTXCPTIFG 案例:
TX_KEY = 1;
UCA0IFG|=UCTXIFG;
中断;
默认值:break;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好。

    也许您可以逐步调试 、以查看 UCA0RXBUF 是否正确。

    我修改了示例代码、初始化与您的代码相同。 一切看起来都不错。

    或者、如果您需要、我可以向您发送代码。

    谢谢、致以诚挚的问候

    赵玉豪

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yuhao、

    我已经调试了它在中断处停止的代码。 您能不能共享您的代码。这对我很有帮助。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好。

    首先、您可能可以检查 UART 是否正确接收数据。 如果 UART 接收正常、则检查数据处理是否存在问题。  

    代码从示例代码'fr599x_euscia0_UART_01.c'修改。 它只是一个简单的代码、其功能是将接收到的数据发回。  

    e2e.ti.com/.../msp430fr599x_5F00_euscia0_5F00_uart_5F00_01.c.txt

    谢谢、致以诚挚的问候

    赵玉豪

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yuhao、

    非常感谢您提供的代码、它非常有效。 我的主代码上没有接收到 UART。 我必须使用 UART 设置 RTC 值。 但数据没有进入缓冲区。我正在共享这里的代码、请帮我。

    ///////////////////////   main.c  ///////////////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <rtc.h>
    
    unsigned char addr[30]="";
    
    
    
    void pin_setup()
    {
       // P1DIR |= BIT0; //Set P1.0 (red LED) to output
        P1DIR = 0x03; //Set P1.0 to output direction
    
        //P1OUT &=~0X02;
        PM5CTL0=LOCKLPM5;
    }
    void clk_setp()
    {
         CSCTL0_H = CSKEY_H;
         CSCTL1 = DCOFSEL_6; //8MHz |DCOFSEL_0 -1MHz
         CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO
         CSCTL3 = DIVA_1|DIVS__1|DIVM__1;
         CSCTL0_H = 0;
    }
    
    void RTC_clk_setup()
    {
       /* P1DIR |= BIT0;
        P1OUT &= ~BIT0;// Set P1.0 as output*/
        PJSEL0 = BIT4 | BIT5;                   // Initialize LFXT pins
       // Disable the GPIO power-on default high-impedance mode to activate
       // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
       // Configure LFXT 32kHz crystal
        CSCTL0_H = CSKEY_H;                     // Unlock CS registers
        CSCTL4 &= ~LFXTOFF;                     // Enable LFXT
         do
         {
            CSCTL5 &= ~LFXTOFFG;                  // Clear LFXT fault flag
            SFRIFG1 &= ~OFIFG;
         } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag
           CSCTL0_H = 0;                           // Lock CS registers*/
    }
    
    
    
    void uart_config()
     {
         P2SEL0 &= ~(BIT0 | BIT1);
         P2SEL1 |= (BIT0 | BIT1);                // USCI_A0 UART operation
         PM5CTL0 &= ~LOCKLPM5;
         UCA0CTLW0=UCSWRST;//eUSCI in reset mode(disabling) and this will automatically SETS the UCTXIFG and RESETS the UCRXIFG,UCRXIE,UCTXIE
         UCA0CTLW0 |=UCSSEL__SMCLK;//CLOCK is SMCLK=8MHZ
         UCA0BRW = 52;
         UCA0MCTLW |= UCOS16 | UCBRF_1 | 0x49;
         UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
         UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt
     }
    
    void print(unsigned char *str)
    {
        strcpy(Data, str);
        size = strlen(Data);
        Tx_index=0;
        UCA0IE |= UCTXIE | UCTXCPTIE;
        UCA0TXBUF=Data[Tx_index];
        Tx_index++;
        __bis_SR_register(LPM0_bits|GIE);
        }
    
    
    void RTC_init()
    {
           print("SET TIME\r\n");
           RTC_clk_setup();
           RTCCTL0_H = RTCKEY_H;                   // Unlock RTC
           RTCCTL0_L = RTCTEVIE_L | RTCRDYIE_L;    // enable RTC read ready interrupt
                                                   // enable RTC time event interrupt
           RTCCTL13 = RTCBCD | RTCHOLD | RTCMODE;  // RTC enable, BCD mode, RTC hold
           RTCYEAR = 0x2022;                       // Year = 0x2022
           RTCMON = 0x11;                           // Month = 0x10 = nov
           RTCDAY = 0x02;                          // Day = 0x26 = 26th
           RTCDOW = 0x03;                          // Day of week = 0x04 = thurs
           print("ENTER HOURS: \r\n");
           UCA0IE |= UCRXIE | UCTXCPTIE;
          __bis_SR_register(LPM0_bits | GIE);
           RTCHOUR = RXData; // Hour = 0x23
          // printf("%x",RTCHOUR);
           print("ENTER MINITUS: \r\n");
           UCA0IE |= UCRXIE | UCTXCPTIE;
           __bis_SR_register(LPM0_bits | GIE);
           RTCMIN = RXData;
          // printf("%x",RTCMIN);
           print("ENTER SECONDS: \r\n");
           UCA0IE |= UCRXIE | UCTXCPTIE;// Minute = 0x00
           __bis_SR_register(LPM0_bits | GIE);
           RTCSEC = RXData; // Seconds = 0x00
          // printf("%x",RTCSEC);
           RTCCTL13 &= ~(RTCHOLD);                 // Start RTC
    
         //  __bis_SR_register(LPM3_bits | GIE);     // Enter LPM3 mode w/ interrupts enabled
           __bis_SR_register(GIE);     // Enter LPM3 mode w/ interrupts enabled
           __no_operation();
           return 0;
    }
    
    
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;               // Stop Watchdog Timer
        clk_setp();
        uart_config();
        RTC_init();
        pin_setup();
        while(1)
        {
            sprintf(addr, "%x:%x:%x\r\n", hours,mins,secs);
             print(addr);
    
            __delay_cycles(8000000);
           }
    }
    
    
    
    /////////////////////////  rtc.h   ////////////////////////////////
    
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    unsigned char Data[15]="";
    unsigned char RXData[5]="";
    unsigned char time_1[]="11:45:00";
    unsigned char time_2[]="11:47:00";
    unsigned int hr=11;
    unsigned int min1=45;
    unsigned int min2=47;
    int secs=0;
    int hours=0;
    int mins=0;
    int day=0;
    int month=0;
    int year=0;
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=RTC_C_VECTOR
    __interrupt void RTC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(RTC_C_VECTOR))) RTC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(RTCIV, RTCIV__RT1PSIFG))
        {
            case RTCIV__NONE:      break;       // No interrupts
            case RTCIV__RTCOFIFG:  break;       // RTCOFIFG
            case RTCIV__RTCRDYIFG:              // RTCRDYIFG
                P1OUT ^= 0x01;// Toggles P1.0 every second
                hours=RTCHOUR;
                mins=RTCMIN;
                secs=RTCSEC;
                day=RTCDAY;
                month=RTCMON;
                year=RTCYEAR;
                 break;
            case RTCIV__RTCTEVIFG:              // RTCEVIFG
                __no_operation();               // Interrupts every minute - SET BREAKPOINT HERE
                break;
            case RTCIV__RTCAIFG:   break;       // RTCAIFG
            case RTCIV__RT0PSIFG:  break;       // RT0PSIFG
            case RTCIV__RT1PSIFG:  break;       // RT1PSIFG
            default: break;
        }
    }
    
    
    
    #pragma vector = EUSCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
        switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
        {
            case USCI_NONE: break;
            case USCI_UART_UCRXIFG:
                Rx_key=0;
                RXData[Rx_index]=UCA0RXBUF;
                if((RXData[Rx_index] == '\x0d'/*'\r'*/) || (RXData[Rx_index] ==  '\n')||(RXData[Rx_index] == '\r'))
                {
                    __bic_SR_register_on_exit(CPUOFF|GIE);
                    UCA0IE &= ~UCRXIE;
                    Rx_index=0;
                    Rx_key=0;
                    break;
                }
                Rx_index++;
                break;
            case USCI_UART_UCTXIFG:
                if(Tx_key==1)
                {
                    if(Tx_index>size)
                    {
                        __bic_SR_register_on_exit(CPUOFF|GIE);
                        UCA0IE &= ~UCTXIE;
                        UCA0IE &= ~UCTXCPTIE;
                        Tx_key=0;
                        break;
                    }
                    UCA0TXBUF = Data[Tx_index];
                    Tx_index++;
                    Tx_key=0;
                }
                break;
            case USCI_UART_UCSTTIFG: break;
            case USCI_UART_UCTXCPTIFG:
                Tx_key=1;
                UCA0IFG|=UCTXIFG;
                break;
            default: break;
        }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它可能与中断设置有关。 我稍后将检查代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    UCA0IE |= UCTXIE | UCTXCPTIE;

    不好主意。 请参阅勘误表 USCI42。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 David:

    感谢您的回答。 我将再次检查。 但很抱歉、我没有遇到这条线的问题、因为我已经在终端上读取了 RTC 值。 现在、当我开始修改代码以使用 UART 接收来设置 RTC 值时、我开始遇到问题。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yuhao、

    首先、我想在进入主程序之前从 UART 读取字符串。 我将从 UCA0RXBUF 获取到 RXData 的数据。 但它不会从 RXData 获取到下面代码中的数据变量。  

    void RXdata()

    unsigned int 数据;
    int i;
    UCA0IE |= UCRXIE;
    _bis_SR_register (LPM0_bits | GIE);
    Data=RXData;

    我已通过 MSP430作为来自 UART 终端的数据。 我正在共享完整的计划 、请帮助我获取数据。

    //////////////////////// main.c  /////////////////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <uart.h>
    unsigned char data[20]="";
    unsigned char receive_data;
     void pin_config()
     {
         P2SEL1|=BIT0|BIT1;
         P2SEL0 &=~BIT0|BIT1;
     }
     void clock_setup()
     {
         // Startup clock system with max DCO setting ~8MHz
         CSCTL0_H = CSKEY_H;                     // Unlock CS registers
        // CSCTL1 = DCOFSEL_3 | DCORSEL;           // Set DCO to 8MHz
         CSCTL1 = DCOFSEL_6 ;
         CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
         CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers
         CSCTL0_H = 0;
     }
     void UART_config()
     {
         UCA0CTLW0 = UCSWRST;                    // Put eUSCI in reset (p788)
         UCA0CTLW0 |= UCSSEL__SMCLK;             // CLK = SMCLK
         UCA0BRW = 52;                           
         UCA0MCTLW |= UCOS16 | UCBRF_1 | 0x49; 
         UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
         _BIS_SR(GIE);
         UCA0IE = UCTXCPTIE;                       // Enable USCI_A0 RX interrupt
     }
    
     void RXdata()
     {
         UCA0IE |= UCRXIE;
         __bis_SR_register(LPM0_bits | GIE);
         data=RXData;
    
     }
     int main(void)
     {
         WDTCTL = WDTPW | WDTHOLD; // stop watchdog time
            pin_config();
            PM5CTL0&=~LOCKLPM5;
            clock_setup();
            UART_config();
    
            while(1)
            {
            RXdata();
            }
     }
     
     
     
     //////////////////////// uart.h  ///////////////////////////
     
     
     #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    unsigned char RXData[20]="";
    unsigned char Data[15]="";
    
    #pragma vector = EUSCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
        switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
        {
            case USCI_NONE: break;
            case USCI_UART_UCRXIFG:
                Rx_key=0;
                RXData[Rx_index]=UCA0RXBUF;
                if((RXData[Rx_index] == '\x0d'/*'\r'*/) || (RXData[Rx_index] ==  '\n')||(RXData[Rx_index] == '\r'))
                {
                    __bic_SR_register_on_exit(CPUOFF|GIE);
                    UCA0IE &= ~UCRXIE;
                    Rx_index=0;
                    Rx_key=0;
                    break;
                }
                Rx_index++;
                break;
            case USCI_UART_UCTXIFG:
                if(Tx_key==1)
                {
                    if(Tx_index>size)
                    {
                        __bic_SR_register_on_exit(CPUOFF|GIE);
                        UCA0IE &= ~UCTXIE;
                        UCA0IE &= ~UCTXCPTIE;
                        Tx_key=0;
                        break;
                    }
                    UCA0TXBUF = Data[Tx_index];
                    Tx_index++;
                    Tx_key=0;
                }
                break;
            case USCI_UART_UCSTTIFG: break;
            case USCI_UART_UCTXCPTIFG:
                Tx_key=1;
                UCA0IFG|=UCTXIFG;
                break;
            default: break;
        }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    一些问题:

     UCA0IE = UCTXCPTIE;                      //启用 USCI_A0 RX 中断

    注释与代码不匹配。

    仅在单个字符的大写中使用不同的函数和变量名称将导致混淆。

    Data=RXData;

    声明为字符数组的两个变量。 C 不会复制数组、而是将 RXData[]的地址写入数据的第一个字节[]。

    解决此类问题的最佳方法是从简单开始。 让它正常工作、然后添加到它。 让每个位正常工作。