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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1092609/msp430fr5994-uart-not-printing-every-value-before-termination

部件号:MSP430FR5994

我已经根据 UART教程中使用的代码为UART发射器编写了一些代码。 在我的代码中,发送器将两个输入转换为字符串,然后通过UART将两个输入转换为计算机上的UART终端。

在我的代码中,我将发送值“120”和“23”。 不过,我只是从终端收到“1”,这是这样的。

我的代码,如下所示。

#include <msp430.h>
#include <stdio.h>

int i = 120;
int j = 23;
char message1[3];
char message2[3];

unsigned char TXbytes_A = 0;
unsigned char TXbytes_B = 0;

int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;               // Stop Watchdog


    // Configure GPIO
    P2SEL0 &= ~(BIT0 | BIT1);
    P2SEL1 |= (BIT0 | BIT1);                // USCI_A0 UART operation (p93_s)

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Startup clock system with max DCO setting ~8MHz
    CSCTL0_H = CSKEY_H;                       // Unlock CS registers
    CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
    CSCTL0_H = 0;                             // Lock CS registers

    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                    // Put eUSCI in reset (p788)
    UCA0CTLW0 |= UCSSEL__SMCLK;             // CLK = SMCLK
    // Baud Rate calculation for 19200
    // 8000000/(16*19200) = 26.042
    // Fractional portion = 0.042
    // User's Guide Table 21-4: UCBRSx = 0xD6
    // UCBRFx = int ( (52.083-52)*16) = 1
    UCA0BRW = 26;                           // 8000000/16/19200, p789
    UCA0MCTLW |= UCOS16 | UCBRF_1 | 0xD600; // UCOS16 = Oversampling enable, used when high frequency clk is used, probably divides everything by 16, UCBRF = fine turner when UCOS16 is active
                                            // 0xD600 is for first 8 bits,
    UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
    UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt
    while(1){
    __delay_cycles(200000);
    UCA0IE |= UCTXIE;
    //i++;
    __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled
    __no_operation();                           // For debugger
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
      case USCI_NONE: break;
      case USCI_UART_UCRXIFG:
          break;

      case USCI_UART_UCTXIFG:           //TXIFG = transmission flag, needs manual activation

          sprintf(message1, "%d", i);

          sprintf(message2, "%d", j);

          // Transmit the byte
          // UCA0TXBUF is taking char message.
          for(TXbytes_A = 0; TXbytes_A < 3; TXbytes_A++){
              UCA0TXBUF = message1[TXbytes_A];   //TXBUF = Transmit Buffer, p791
              }

          // If last byte sent, start sending next message
          if(TXbytes_A == 3)
          {
              UCA0TXBUF = 13; //Next line, see ASCII chart
          }

          for(TXbytes_B = 0; TXbytes_B < 3; TXbytes_B++){
              UCA0TXBUF = message2[TXbytes_B];   //TXBUF = Transmit Buffer, p791
              }
          if(TXbytes_B == 3)
          {
              UCA0TXBUF = 13; //Next line
              UCA0IE &= ~UCTXIE;
          }
          __bic_SR_register_on_exit(LPM3_bits);
          break;

      case USCI_UART_UCSTTIFG: break;
      case USCI_UART_UCTXCPTIFG: break;
      default: break;
    }
}

但是,当我在包含中断的线路78和88的for循环中放置相当大的延迟时,我能够接收到整套值。 如下所示:

#include <msp430.h>
#include <stdio.h>

int i = 120;
int j = 23;
char message1[3];
char message2[3];

unsigned char TXbytes_A = 0;
unsigned char TXbytes_B = 0;

int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;               // Stop Watchdog


    // Configure GPIO
    P2SEL0 &= ~(BIT0 | BIT1);
    P2SEL1 |= (BIT0 | BIT1);                // USCI_A0 UART operation (p93_s)

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Startup clock system with max DCO setting ~8MHz
    CSCTL0_H = CSKEY_H;                       // Unlock CS registers
    CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers
    CSCTL0_H = 0;                             // Lock CS registers

    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                    // Put eUSCI in reset (p788)
    UCA0CTLW0 |= UCSSEL__SMCLK;             // CLK = SMCLK
    // Baud Rate calculation for 19200
    // 8000000/(16*19200) = 26.042
    // Fractional portion = 0.042
    // User's Guide Table 21-4: UCBRSx = 0xD6
    // UCBRFx = int ( (52.083-52)*16) = 1
    UCA0BRW = 26;                           // 8000000/16/19200, p789
    UCA0MCTLW |= UCOS16 | UCBRF_1 | 0xD600; // UCOS16 = Oversampling enable, used when high frequency clk is used, probably divides everything by 16, UCBRF = fine turner when UCOS16 is active
                                            // 0xD600 is for first 8 bits,
    UCA0CTLW0 &= ~UCSWRST;                  // Initialize eUSCI
    UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt
    while(1){
    __delay_cycles(200000);
    UCA0IE |= UCTXIE;
    //i++;
    __bis_SR_register(LPM3_bits | GIE);       // Enter LPM3, interrupts enabled
    __no_operation();                           // For debugger
    }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
      case USCI_NONE: break;
      case USCI_UART_UCRXIFG:
          break;

      case USCI_UART_UCTXIFG:           //TXIFG = transmission flag, needs manual activation

          sprintf(message1, "%d", i);

          sprintf(message2, "%d", j);

          // Transmit the byte
          // UCA0TXBUF is taking char message.
          for(TXbytes_A = 0; TXbytes_A < 3; TXbytes_A++){
              UCA0TXBUF = message1[TXbytes_A];   //TXBUF = Transmit Buffer, p791
              __delay_cycles(10000);
              }

          // If last byte sent, start sending next message
          if(TXbytes_A == 3)
          {
              UCA0TXBUF = 13; //Next line, see ASCII chart
          }

          for(TXbytes_B = 0; TXbytes_B < 3; TXbytes_B++){
              UCA0TXBUF = message2[TXbytes_B];   //TXBUF = Transmit Buffer, p791
              __delay_cycles(10000);
              }
          if(TXbytes_B == 3)
          {
              UCA0TXBUF = 13; //Next line
              UCA0IE &= ~UCTXIE;
          }
          __bic_SR_register_on_exit(LPM3_bits);
          break;

      case USCI_UART_UCSTTIFG: break;
      case USCI_UART_UCTXCPTIFG: break;
      default: break;
    }
}

有了这个代码,包括延迟,我就能收到这个。

我很想最终处理空数组值,但这完全是另一个问题。 如果需要更多信息,请告诉我。 如果能就如何修改我的守则提出具体建议,我将不胜感激。

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

    您需要阅读有关串行端口如何工作的说明文件。 每个传输中断仅传输到TXBUF的一个字节之类的小细节。

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

    您好,

    您需要参阅sprintf函数说明。 它会将120或23保存到数组中的字符串中,键入%d 有关详细信息,您需要参阅用户指南中的UART章节。