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.

[参考译文] MSP430FR5969:微控制器不规则功能

Guru**** 2534260 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1169038/msp430fr5969-microcntroller-irregular-function

主题中讨论的其他器件:MSP430FR5969

您好!

我有一个定制电路、在该电路中、UART (UCA1)和带有 TIMERB0的计数器(TIMERERA0、TIMERERA1)作为计时器模块被同时使用。

TIMERB0模块用于创建1秒中断、TIMERRA0和 TIMERERA1用于对外部脉冲进行计数、UART (UCA1)用于在第二个间隔发送和接收数据、

大多数情况下,操作正常,但在不规则的时间间隔内,传输的数据会丢失,计数值也会超过提供的外部脉冲,如何解决此问题  

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

    您好、Sasi、

    我将不使用 TIMERA0和 TIMERA1开始解决此问题。 只使用 TIMERB0来生成1秒间隔、并在代码中通常读取 TIMERRA0和 TIMERRA1值、而是设置并递增变量、然后传输该值而不是计时器结果。  这将有助于排除 TIMERA0、A1的问题。

    此外、您能否尝试将代码减小到可能的绝对最小大小、并查看它是否表明了问题。  这意味着删除代码中除基本功能之外的所有其他内容:TIMERB0用于生成1秒计时、UCA1用于发送数据。  就这些。 这样做可能有助于发现与 TIMERB0或 UCA1无关的问题。

    如果您仍然看到问题、则这可能指向您用于传输数据的方法中的某个内容。 您能否共享代码中执行传输的部分?  

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

    尊敬的 Dennis:

    根据您的建议、我确实只运行计数器和 UART、因此当我尝试运行完整代码时、一切都正常。问题仍然存在、由于设计完成、无法更改微控制器、是否有任何可能的方法来解决此问题。

    在这个项目中、使用了两个 ISR、一个用于 TIMERB0、另一个用于 UARTA1、如果两个外设在同一持续时间内中断、任何中断都会下降、  

    如果其中一个 ISR 需要10ms 来完成其总体操作、那么另一个例程将等待并执行?

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

    您好、Sasi、

    好的、这有助于缩小问题的范围。

    无需担心同时发生两个不同的中断。  通过查看 MSP430FR5969数据表、表6-4、TI再 培训局的优先级高于 UART1。  这意味着如果两个中断同时发生、中断控制器将确认 TI再 培训中断并跳转到 TI再 培训 ISR。  同时、UART1中断将保持挂起状态(等待)、直到 TI再 培训 ISR 完成、然后调用 UART1 ISR。

    由于我们知道 TIMERB 中断每秒发生一次、因此 UART1 ISR 必须是一个最长需要10ms 才能完成的中断、这是有道理的、因为传输数据需要一些时间。 也许此时共享您的代码是有道理的。  可以这样做吗?

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

    尊敬的 Dennis:  

    我已连接 UART 配置和接收程序

    /* GPIO 初始化*/
    uint8_t looper9;
    P2SEL1 = 0x67;/* UART_A0 RS485_1 GPIO 引脚设置& UART_A1 RS485_2 GPIO 引脚设置*/
    PJDIR = 0x30;//禁用缓冲器 IC
    PJOUT = 0x20;
    P3DIR = 0x80;
    P3OUT = 0x00;

    /* UART 模块初始化为12MHz */

    UCA1CTLW0 = 0x0081;//为 UART 选择 SMclk */
    UCA1BRW = 0x0006;//波特率发生器的预分频器置位
    UCA1MCTLW = 0x2081;//过采样波特率生成设置为115200波特率*/
    UCA1CTLW0 = 0x0080;// UART 模块锁定*/
    UCA1IE = 0x0001;


    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=USCI_A1_vector
    _interrupt void USCI_A1_ISR (void)
    #endif


    Receive_buf[0]= UCA1RXBUF;
    UCA1IE = 0x0000;/*禁用 UART 中断*
    (void) UART_INTERRUPT (receive_buf);
    UCA1IE = 0x0001;

    空 UART_INTERRUPT (uint8_t receive_buff [])

    uint8_t looper16=0U、rx_buf_1=0U;//初始化缓冲区会导致寄存器中断*/
    INT_16T INT_reg;
    uint16_t int_reg1;
    INT_reg = UCA1IFG;
    int_reg1 =(uint16_t) int_reg & 0x0001U;
    while ((RX_Buf_1!= 0x21U))

    LOOOPE16++;
    while (!(int_reg1 == 0x0001U)/*轮询是为了创建完美的接收*/

    INT_reg = UCA1IFG;
    int_reg1 =(uint16_t) int_reg & 0x0001U;

    RX_BUF_1 =(uint8_t) UCA1RXBUF & 0xFFU;//接收 RS485_1的数据*
    Receive_buff[looper16]= rx_buf_1;/*读取缓冲区*/
    INT_reg1 = 0U;

    if (logop16 > 3U)

    (void)命令(receive_buff);

    其他

    (void) delay_loop (30);

    (void) delay_loop (300);
    P3OUT = 0x00;/*复位接收使能引脚*

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

    您好、Sasi、

    我查看了您提供的代码部分。  我看不到任何会导致您出现问题的主要问题。 完全了解这里发生的情况有点令人困惑、因此您可能需要在 TI Resource Explorer 中查看 MSP430FR5969的一些 UART 示例 、看看您是否可以对其进行调整以适合您。  您可能还需要查看 MSP430 Driverlib UART 函数。

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

    尊敬的 Dennis:

    在该代码中、代码有时会卡在标志状态检查函数中、因此这些差异会发生、我假设这是由于外部噪声、因为当我们使用 CSL42xx–USB 转 RS485转换器替换我们的 USB 转 RS485模块(DTECH)转换器时、大部分问题都得到解决

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

    您好、Sasi、

    您能否用示波器测量 UART RX 引脚上的噪声?

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

    你(们)好 Dennis

    连接 DTECH 电缆时、会发生复位、但很少会发生、数据会以每秒一次的间隔存储在 NAND 闪存中、该间隔也是 disreptede2e.ti.com/.../data142933-23_2D00_11_2D00_22.xlsx

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

    您好、Sasi、

    那么、您在断开/连接通信电缆时看到设备复位了吗?

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

    尊敬的 Dennis:

    是的、器件复位和大多数问题与器件断开连接和连接通信电缆有关

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

    您好、Sasi、

    当您连接/断开电缆时、可能会导致某种类型的电压尖峰。

    我建议将 MSP430 VDD 监控到尽可能靠近 MSP430的位置。  最佳位置是 MSP430附近的0.1旁路电容器。  然后连接/断开电缆并查看 VDD 的作用是什么?  压降了吗?  是否存在噪声或尖峰?  然后在 MSP430 RST 引脚上执行同样的操作。

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

    您好、Sasi、

    您是否有更新?  您是否能够监控 VDD 和 RST 引脚并观察到任何干扰?

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

    尊敬的 Dennis:

    我已经监控了 VDD、电压漂移无法显著测量、它从3.3V 降至3.2V、我正在尝试在 RESET 引脚进行检查

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

    尊敬的 Dennis:

    我无法监控复位引脚、但我不确定外部接口是否会产生干扰微控制器的噪声、但复位仅由软件看门狗计时器复位引起、 这意味着微控制器在特定的时间间隔内挂起或退出例程、导致此类挂起的原因是内存溢出、或者多个中断将导致此类挂起

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

    您好、Sasi、

    好的、我们正在取得进展。  

    由于 WDT 必须定期复位、我同意您的代码好像卡在例程中。  我的建议是查看任何例程、这些例程"阻止"或等待某个事件发生、例如 IO 引脚发生更改、或等待 UART 中接收下一个字节。  查看所有具有某种形式的"while (1)"循环的代码。

     如果这不能帮助解决问题、您可以做的另一件事是将代码最小化到绝对最小值、但仍然证明了这一问题。  很多时候、您会使用这种方法发现问题。

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

    尊敬的 Dennis:

    由于我在上面共享了一个代码示例以接收 UART 数据、在该代码中、while 条件用于验证 UART 接收标志、有时代码会滞留在整个程序中、如果单独执行、则不会出现此类问题

    while (!(int_reg1 == 0x0001U)/*轮询是为了创建完美的接收*/

    INT_reg = UCA1IFG;
    int_reg1 =(uint16_t) int_reg & 0x0001U;

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

    您好、Sasi、

    我已重新格式化您的代码、并重新发布、以方便您和可能关注此主题的其他人。

    我的第一个注释与您在中断 ISR 内进行的轮询有关。 正如您发现的、轮询中断 ISR 内的任何内容是一种很糟糕的做法。  如果轮询被卡住、您的代码将挂起、或者如果您使用 WDT、器件将最终复位。

    我不确定您到底要执行什么操作、但我建议 ISR 中的代码只读取从 UCA1RXBUF 接收到的字节、更新您的 Receive_buff []、然后退出 ISR。  在 main 中执行字节或缓冲区的所有处理。  这样、UART 中断就准备好在接收到下一个字节时生成另一个中断。

    为了帮助我了解 UART 接收到的内容、您能否描述预期数据以及您尝试对其执行的操作?

    __interrupt void USCI_A1_ISR(void)
    {
        receive_buf[0] = UCA1RXBUF;
        UCA1IE = 0x0000; /* Uart interrupt disabled */
        (void)uart_interrupt(receive_buf);
        UCA1IE = 0x0001;
    }
    
    void uart_interrupt(uint8_t receive_buff[])
    {
        uint8_t looper16=0U,rx_buf_1=0U; /* initializing buffer leads to drop of registers */
        int_16t int_reg;
        uint16_t int_reg1;
        int_reg = UCA1IFG;
        int_reg1 = (uint16_t)int_reg & 0x0001U;
        
        while((rx_buf_1 != 0x21U))
        {
            looper16++;
            
            while(!(int_reg1 == 0x0001U)) /* polling is done to create perfect reception */
            {
                int_reg = UCA1IFG;
                int_reg1 = (uint16_t)int_reg & 0x0001U;
            }
            rx_buf_1 = (uint8_t)UCA1RXBUF & 0xFFU; /* receive data for rs485_1 */
            receive_buff[looper16] = rx_buf_1; /* Read buffer */
            int_reg1 = 0U;
        }
        
        if(looper16 > 3U)
        {
            (void)command(receive_buff);
        }
        else
        {
            (void)delay_loop(30);
        }
        
        (void)delay_loop(300);
        
        P3OUT = 0x00; /* To reset receive enable pin */
    
    }

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

    尊敬的 Dennis:

    我必须接收不同长度的命令、因此在接收到第一个字节后、我禁用了 ISR、并使用轮询方法来接收即将到来的字符。 这是流程、现在我正尝试根据您的建议重写程序。