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.

[参考译文] CCS/MSP430F5529:MSP430F5529

Guru**** 2595800 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/817245/ccs-msp430f5529-msp430f5529

器件型号:MSP430F5529

工具/软件:Code Composer Studio

仅针对最后一个字节触发 RX 中断。 我使用的是具有8-N-1的115200波特。 我能够顺利地进行传输。 我在分析器上看到接收到的数据-不确定为什么不触发中断  

下面的代码片段:  

extern void UART_init (void)

GPIO_SET_PERIPHERAL_MODULE_OUTPUT (UART_TX);
GPIO_Set_Peripheral_MODULE_OUTPUT (UART_RX);

USCI_A_UART_initParam param ={0};
param.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;//1.04MHz  
param.clockPrescalar = 9;
param.firstModReg = 0;
param.secondModReg = 1;
param.parity = USCI_A_uart_no_parity;
param.msborLsbFirst = USCI_A_UART_LSB_FIRST;
param.numerofStopBits = USCI_A_UART_One_STOP_BIT;
param.uartMode = USCI_A_UART_MODE;
param.overSAMPLING = 0;

USCI_A_UART_INIT (USCI_A0_BASE、param);
USCI_A_UART_ENABLE (USCI_A0_BASE);

USCI_A_UART_clearInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit 中断_FLAG);
USCI_A_UART_clearInterrupt (USCI_A0_BASE、USCI_A_UART_Receive_interrupt_FLAG);

USCI_A_UART_enableInterrupt (USCI_A0_BASE、USCI_A_UART_receive_interrupt);
USCI_A_UART_enableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit _INTERRUPT);

#pragma vector=USCI_A0_Vector
_interrupt void USCI_A0_ISR (void)

switch (__evo_in_range (UCA0IV、4))

//如果 RX BUF 挂起
案例2:
UartRcvBuf[UartRcvBufIndex++]= UCA0RXBUF;

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

    您好!

    是否启用了全局中断?

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

    是的、我在主函数中启用了它。 奇怪的是、传输工作正常、但接收多个字节时遇到问题。  

    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

    disable_interrupts ();
    enable_interrupts ();

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

    > USCI_A_UART_enableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit _INTERRUPT);

    您不应该这样做、因为您的 ISR 不处理 TXIFG、因此在 Tx 字节之间、您的程序将持续循环执行 ISR。 (听起来是(?) 就好像您使用的是轮询 Tx 一样。)  

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

    这是我的整个中断函数。 我有一个例程来处理我的 TX 中断。 我假设这些是根据优先级处理的、我看到 Rx 中断具有更高的优先级。 不确定为什么接收到的数据包的第一个字节没有触发 RX 中断。

    #pragma vector=USCI_A0_Vector
    _interrupt void USCI_A0_ISR (void)

    switch (__evo_in_range (UCA0IV、4))

    //如果 RX BUF 挂起
    案例2:
    _nop();

    //如果 TX BUF 挂起
    案例4:
    IF (UART_TX_COUNTER < UART_TX_LENGTH)

    //发送下一个数据
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    UART_TX_COUNTER++;

    其他

    //最后一个字节
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    USCI_A_UART_DisableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit 中断);

    中断;

    默认值:break;

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

    [您的"案例2:"似乎已消失。 我将假定它是复制/粘贴错误。]

    我在这里没有发现任何明显的错误、因此我想在程序的其他地方会发生什么事情。 我正在寻找一个长时间运行且禁用中断的代码序列(例如 ISR 中的延迟循环)、此序列能够在一个完整字节时间(~85usec)内锁定 UCA0 ISR。

    您如何对此进行测试? 断点? 或者等待它达到 DONE (-ish)状态并暂停调试器?

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

    噢、是的、我删除了那里的代码、只是测试它是否进入了中断。 只是复制粘贴错误。  

    我实际上没有任何其他东西在运行。 我基本上启动、发送7个字节、需要从另一个器件读取14个字节。 我使其工作的方式是、我按字节启动发送-传输、然后它几乎应该只需转到 Rx 中断来读取第一个字节。  

    我在_nop()上有断点来检查我返回的数据。 我还在 Rx int 内的_nop()处设置了断点、但它只在那里执行了一次。 这也很奇怪、因为我看到分析仪上的全帧。  

    我还应该提到、我使用的是 Launchpad、并且我已连接到引脚3.4和3.3以使用 A0UART。  

    MAIN ()

    disable_interrupts ();
    enable_interrupts ();
    UART_INIT();

    UART_SEND ();

    _nop();

    void UART_send (uint8_t * data、uint8_t length、uint8_t * rxdata、uint8_t rxlength)

    UART_TX_COUNTER = 0;
    UART_TX_LENGTH =长度- 1;
    UART_TX_buffer =数据;

    UART_Rx_COUNTER = 0;
    UART_Rx_length = rxlength - 1;
    UART_Rx_buffer = rxdata;

    //发送第一个字节-因为 Tx 已准备就绪
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    UART_TX_COUNTER++;

    #pragma vector=USCI_A0_Vector
    _interrupt void USCI_A0_ISR (void)

    switch (__evo_in_range (UCA0IV、4))

    //如果 RX BUF 挂起
    案例2:
    _nop();

    //如果 TX BUF 挂起
    案例4:
    IF (UART_TX_COUNTER < UART_TX_LENGTH)

    //发送下一个数据
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    UART_TX_COUNTER++;

    其他

    //最后一个字节
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    USCI_A_UART_DisableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit 中断);

    中断;

    默认值:break;

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

    请不要在"案例2"中断点、尝试让其自由运行、然后再查看 UartRcvBuf。 当您处于断点时、一些 MCU 时钟会保持运行。

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

    缓冲区仅与最后一个字节一同退出。  

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

    如果我让程序在没有任何断点的情况下运行(在 main 中也没有断点)、我无法看到缓冲区的内容-它返回的标识符未找到。 调试这种情况的最佳方法是什么?  

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

    以下是我对器件进行写入和读取的代码:  

    我的 UART 函数位于与主文件不同的文件中。  

    主{

    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

    disable_interrupts ();
    enable_interrupts ();

    uint8_t sendata[8]={0xAA、0xBB、0x03、0x03、0x01、 0x2A、0x00、0x3A};

    uint8_t recv[14];
    uint8_t * p = recv;

    UART_INIT();

    UART_SEND (sendata、8、p、14);

    静态易失性 uint8_t UART_TX_COUNTER;
    静态易失性 uint8_t UART_TX_length;
    静态易失性 uint8_t * UART_TX_buffer;

    静态易失性 uint8_t UART_Rx_counter;
    静态易失性 uint8_t UART_Rx_length;
    静态易失性 uint8_t * UART_Rx_buffer;

    extern void UART_init (void)

    GPIO_SET_PERIPHERAL_MODULE_OUTPUT (UART_TX);
    GPIO_Set_Peripheral_MODULE_OUTPUT (UART_RX);

    USCI_A_UART_initParam param ={0};
    param.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
    param.clockPrescalar = 9;
    param.firstModReg = 0;
    param.secondModReg = 1;
    param.parity = USCI_A_uart_no_parity;
    param.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    param.numerofStopBits = USCI_A_UART_One_STOP_BIT;
    param.uartMode = USCI_A_UART_MODE;
    param.overSAMPLING = 0;

    USCI_A_UART_INIT (USCI_A0_BASE、param);
    USCI_A_UART_ENABLE (USCI_A0_BASE);

    USCI_A_UART_clearInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit 中断_FLAG);
    USCI_A_UART_clearInterrupt (USCI_A0_BASE、USCI_A_UART_Receive_interrupt_FLAG);

    USCI_A_UART_enableInterrupt (USCI_A0_BASE、USCI_A_UART_receive_interrupt);
    USCI_A_UART_enableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit _INTERRUPT);

    void UART_send (uint8_t * data、uint8_t length、uint8_t * rxdata、uint8_t rxlength)

    UART_TX_COUNTER = 0;
    UART_TX_LENGTH =长度- 1;
    UART_TX_buffer =数据;

    UART_Rx_COUNTER = 0;
    UART_Rx_length = rxlength - 1;
    UART_Rx_buffer = rxdata;

    //发送第一个字节-因为 Tx 已准备就绪
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    UART_TX_COUNTER++;

    #pragma vector=USCI_A0_Vector
    _interrupt void USCI_A0_ISR (void)

    switch (__evo_in_range (UCA0IV、4))

    //如果 RX BUF 挂起
    案例2:
    *(UART_Rx_buffer + UART_Rx_counter)= UCA0RXBUF;
    UART_Rx_COUNTER++;
    中断;

    //如果 TX BUF 挂起
    案例4:
    IF (UART_TX_COUNTER < UART_TX_LENGTH)

    //发送下一个数据
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    UART_TX_COUNTER++;

    其他

    //最后一个字节
    USCI_A_UART_transmitData (USCI_A0_BASE、*(UART_TX_buffer + UART_TX_counter));
    USCI_A_UART_DisableInterrupt (USCI_A0_BASE、USCI_A_UART_Transmit 中断);

    中断;

    默认值:break;

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

    因此、我最终看到我在缓冲器中看到的内容。 自由运行、然后断点。 如何实现此等待读取完成?  

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

    一种简单的方法是让主等待("LPM0;")、然后让 ISR 根据某些标准(例如缓冲区已满、缓冲区未空)唤醒主系统("LPM0_EXIT;")。 标准选择可能取决于您期望字节到达的速度。

    您还应该考虑字节未到达时应该发生的情况(永远等待与超时)。

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

    谢谢、我会尝试一下。 这是否允许触发中断?  

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

    LPM0宏不(自身)启用中断、因此您应该提前__ENABLE_INTERRUPT ()。  

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

    如果我在此处添加另一行以检查最后一个字节:

    案例2:

    *(UART_Rx_buffer + UART_Rx_counter)= USCI_A_UART_receiveData (USCI_A0_BASE);
    UART_Rx_COUNTER++;

    if (最后一个字节)

    {退出 lpm0}

    中断;

    我发现如果添加 if 语句、我将丢失一个字节的数据。 是否有办法在不影响 UART 读取操作的情况下订阅定时器?  

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

    >if (最后一个字节)

    由于这不是一个实际的 C 代码行、我的第一个猜测是您的实际代码不会检查您的想法。

    --------------

    也就是说:执行超时的一种简单方法是:

    1)选择一个计时器、例如 A0、设置 TA0CCR0 =您的超时、并设置 TA0CCTL0:CCIE (对于向上计数模式、MC = 1)

    2) 2)每次收到一个字节时、清除计时器(TA0CTL |= TACLR)

    3) 3)如果您曾到达 vector=TIMER0_A0_vector、请设置错误标志并执行 LPM0_EXIT 以唤醒 main。

    4) 4)缓冲区满后、用 TA0CTL=0停止计时器。

    这不会干扰 UART Rx。