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 验证 C 代码、从而实现 MSP430FR5994

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1369060/msp430fr5994-need-help-verifying-c-code-using-uart-for-msp430fr5994-implementation

器件型号:MSP430FR5994
主题中讨论的其他器件: MSP430FR2311

工具与软件:

我是一名学生、目前正在从事一个涉及 MSP430FR5994微控制器的项目。 我的任务是实现 UART 通信、以将数据从微控制器发送到我的 PC。 验证我的 C 代码。

发送字符时接收效果很好、但发送整数时遇到问题。 令人惊讶的是、我根本没有收到任何消息、甚至指示数据传输的 LED 也不会切换。

以下是我使用的 C 代码:

#包含
#包含

///详细说明
void initClock (void);
void initUART (void);
void initPort (void);
void sendBuffer (void);

int main (void){
//停止看门狗计时器
WDTCTL = WDTPW + WDTHOLD;

//初始化事件
initClock();
initPort();
inituart();

while (1){
//通过 UART 发送预定义的缓冲区
sendBuffer();
P1OUT ^= BIT0;//切换 LED 以指示正在发送数据
__delay_cycles (1000000);//添加延迟以避免循环过快

返回0;

//初始化
void initClock (void){
CSCTL0_H = CSKEY >> 8;// D é verrouillage du module CS
CSCTL1 = DCOFSEL_6;// S é lection de DCO à 8 MHz (selon la documentation MSP430)
CSCTL2 = SELM__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;//配置地址源
CSCTL3 = DIVA__1 | DIVS__1 | DIVM_1;//重组
CSCTL0_H = 0;//应对模块 CS

//初始化 UART
void initUART (void){
UCA0CTLW0 = UCSWRST;//将 à 重新初始化模块 UART
P2SEL0 &=~(BIT0 | BIT1);//配置加密产品 P2.0 et P2.1
P2SEL1 |=(BIT0 | BIT1);
UCA0CTLW0 |= UCSSEL_SMCLK;// SMCLK 通信源模块 UART
UCA0BRW = 52;//配置 du d é bit en bauds à 9600 bauds
UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49;//配置 DES paramètres DE 调制
UCA0CTLW0 &=~UCSWRST;//错误地进行重新初始化
UCA0IE |= UCRXIE;//激活中断接收 UART

//初始化 DES 端口 GPIO
void initPort (void){
P1OUT = 0x00;
P1DIR = 0xFF;
P1OUT |= BIT0;

P2OUT = 0x00;
P2DIR = 0xFF;

P3OUT = 0x00;
P3DIR = 0xFF;

P4OUT = 0x00;
P4DIR = 0xFF;

P5OUT = 0x00;
P5DIR = 0xFF;

P6OUT = 0x00;
P6DIR = 0xFF;

P7OUT = 0x00;
P7DIR = 0xFF;

P8OUT = 0x04;
P8DIR = 0xFF;

P9OUT = 0x00;
P9DIR = 0xFF;

PAOUT = 0x00;
PADIR = 0xFF;

PBOUT = 0x00;
PBDIR = 0xFF;

PCOUT = 0x00;
PCDIR = 0xFF;

PDOUT = 0x00;
PDDIR = 0xFF;

PEOUT = 0x00;
PEDIR = 0xFF;

PJOUT = 0x00;
PJDIR = 0xFF;

P2SEL0 &=~(BIT0 | BIT1);
P2SEL1 |=(BIT0 | BIT1);


//通过 UART 发送预定义缓冲器的函数
void sendBuffer (void){
//要发送的数据缓冲区
uint8_t buffer[]={0x01、0x02、0x03、0x04、0x05};

//通过 UART 发送缓冲区
INT I;
对于(i = 0;i < sizeof (buffer);i++){
//等待传输寄存器准备就绪
while (! (UCA0IFG & UCTXIFG));

//发送缓冲元素
UCA0TXBUF =缓冲器[i];

//等待传输完成
while (UCA0STATW 和 UCBUSY);

如果深入了解可能导致此问题的原因以及如何解决此问题、我将不胜感激。 此外、如果您对我的 C 代码有任何建议或改进、我将非常感谢您提供宝贵意见。

感谢您的参与和协助!

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

    您是说、如果您更改

    uint8_t buffer[]={0x01、0x02、0x03、0x04、0x05};

    uint8_t buffer []={'h'、'e'、'l'、'l'、'o'};

    它的工作原理是什么?

    您不需要同时进行忙时等待、第一个:while (! (UCA0IFG & UCTXIFG));应该足够了。

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

    这不起作用  

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

    那么什么代码"当我发送字符完美工作"? 从这里开始。 此外、还可以查看基于中断的 UART 回显示例。

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

    我使用了另一个代码用于发送字符。 它将整数转换为字符并逐个发送。

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

    我想您的意思是使用 sprintf()之类的东西创建整数的 ASCII 字符串。 但现在您希望直接发送整数。

    采用原始程序。 只需直接发送整数即可。 这样可以吗?

    如果是、现在只需为数组中的每个字符生成循环。

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

    对于此处粘贴的代码:

    您是否删除了

    while (UCA0STATW 和 UCBUSY);

    忙等待?

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

    您的原始代码可以很好地满足我的要求。 我必须对我可用的 MSP430FR2311的引脚和时钟进行一些更改。

    #include <msp430.h>
    #include <stdint.h>
    
    void Software_Trim();            // Software Trim to get the best DCOFTRIM value
    #define MCLK_FREQ_MHZ 8                     // MCLK = 8MHz
    
    // Déclarations des fonctions
    
    void initUART(void);
    void initPort(void);
    void sendBuffer(void);
    
    int main(void)
    {
    // Stop watchdog timer
        WDTCTL = WDTPW + WDTHOLD;
    
    // Initialisation des périphériques
        initPort();
        PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
                              // to activate 1previously configured port settings
    
        __bis_SR_register(SCG0);                 // disable FLL
        CSCTL3 |= SELREF__REFOCLK;               // Set REFO as FLL reference source
        CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3; // DCOFTRIM=3, DCO Range = 8MHz
        CSCTL2 = FLLD_0 + 243;                  // DCODIV = 8MHz
        __delay_cycles(3);
        __bic_SR_register(SCG0);                // enable FLL
        Software_Trim();             // Software Trim to get the best DCOFTRIM value
    
        CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
                                                   // default DCODIV as MCLK and SMCLK source
        initUART();
    
        while (1)
        {
    // Send a predefined buffer via UART
            sendBuffer();
    
    
    
            P1OUT ^= BIT0; // Toggle LED to indicate sending data
            __delay_cycles(1000000); // Add a delay to avoid too fast a loop
        }
    
    }
    // Initialisation de l'horloge
    void Software_Trim()
    {
        unsigned int oldDcoTap = 0xffff;
        unsigned int newDcoTap = 0xffff;
        unsigned int newDcoDelta = 0xffff;
        unsigned int bestDcoDelta = 0xffff;
        unsigned int csCtl0Copy = 0;
        unsigned int csCtl1Copy = 0;
        unsigned int csCtl0Read = 0;
        unsigned int csCtl1Read = 0;
        unsigned int dcoFreqTrim = 3;
        unsigned char endLoop = 0;
    
        do
        {
            CSCTL0 = 0x100;                         // DCO Tap = 256
            do
            {
                CSCTL7 &= ~DCOFFG;                  // Clear DCO fault flag
            }
            while (CSCTL7 & DCOFFG);               // Test DCO fault flag
    
            __delay_cycles((unsigned int) 3000 * MCLK_FREQ_MHZ); // Wait FLL lock status (FLLUNLOCK) to be stable
                                                                 // Suggest to wait 24 cycles of divided FLL reference clock
            while ((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0))
                ;
    
            csCtl0Read = CSCTL0;                   // Read CSCTL0
            csCtl1Read = CSCTL1;                   // Read CSCTL1
    
            oldDcoTap = newDcoTap;               // Record DCOTAP value of last time
            newDcoTap = csCtl0Read & 0x01ff;       // Get DCOTAP value of this time
            dcoFreqTrim = (csCtl1Read & 0x0070) >> 4;       // Get DCOFTRIM value
    
            if (newDcoTap < 256)                    // DCOTAP < 256
            {
                newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
                if ((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
                    endLoop = 1;                   // Stop while loop
                else
                {
                    dcoFreqTrim--;
                    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4);
                }
            }
            else                                   // DCOTAP >= 256
            {
                newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
                if (oldDcoTap < 256)                // DCOTAP cross 256
                    endLoop = 1;                   // Stop while loop
                else
                {
                    dcoFreqTrim++;
                    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim << 4);
                }
            }
    
            if (newDcoDelta < bestDcoDelta)         // Record DCOTAP closest to 256
            {
                csCtl0Copy = csCtl0Read;
                csCtl1Copy = csCtl1Read;
                bestDcoDelta = newDcoDelta;
            }
    
        }
        while (endLoop == 0);                      // Poll until endLoop == 1
    
        CSCTL0 = csCtl0Copy;                       // Reload locked DCOTAP
        CSCTL1 = csCtl1Copy;                       // Reload locked DCOFTRIM
        while (CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1))
            ; // Poll until FLL is locked
    }
    
    // Initialisation de l'UART
    void initUART(void)
    {
        // Configure UART pins
        P1SEL0 |= BIT6 | BIT7;                  // set 2-UART pin as second function
    
        UCA0CTLW0 = UCSWRST; // Mise à la réinitialisation du module UART
        UCA0CTLW0 |= UCSSEL__SMCLK; // Sélection de SMCLK comme source d'horloge UART
        UCA0BRW = 52; // Configuration du débit en bauds à 9600 bauds
        UCA0MCTLW = UCOS16 | UCBRF_1 | 0x49; // Configuration des paramètres de modulation
        UCA0CTLW0 &= ~UCSWRST; // Sortie de la réinitialisation
        UCA0IE |= UCRXIE; // Activation des interruptions de réception UART
    }
    
    // Initialisation des ports GPIO
    void initPort(void)
    {
        P1OUT = 0x00;
        P1DIR = 0xFF;
        P1OUT |= BIT0;
    
        P2OUT = 0x00;
        P2DIR = 0xFF;
    
        PAOUT = 0x00;
        PADIR = 0xFF;
    
        PJOUT = 0x00;
        PJDIR = 0xFF;
    
        P2SEL0 &= ~(BIT0 | BIT1);
        P2SEL1 |= (BIT0 | BIT1);
    }
    
    // Function to send a predefined buffer via UART
    void sendBuffer(void)
    {
    // Data buffer to send
        uint8_t buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
    
    // Send buffer via UART
        int i;
    
        for (i = 0; i < (sizeof(buffer)); i++)
        {
    // Wait until transmission register is ready
            while (!(UCA0IFG & UCTXIFG))
                ;
    
    // Send buffer element
            UCA0TXBUF = buffer[i];
    
    // Wait until transmission is complete
            while (UCA0STATW & UCBUSY)
            ;
        }
    }

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

    通常情况下发生这种情况时-特别是当 LED 停止切换时-这意味着你得到一个中断、在存根我看到你正在激活 UART 接收中断时、将你发送到无尽的中断。 如果接收到任何没有处理程序的字符、则可能会发生这种情况。

    此外,注释掉你的 sendBuffer()函数,看看延迟环路+ LED 是否有效。 否则、您遇到时钟或其他问题。

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

    我终于解决了它。 实际上,问题在于 UART 配置(应配置 MSB),并且函数 sizeof(Buffer)未向 IDE 返回精确值,因此未 处理 for Loop 。 感谢您的帮助  

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

    我看了看 sizeof ()的东西,但由于 sizeof (uint8_t )是1 ,它似乎是可以的。