You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATXMEGA16E5的TCC4定时器无诱因停止问题求助

ATXMEGA16E5 TCC4定时器无诱因停止问题排查

问题描述

  • 10台相同设备中约半数出现同一异常,其余设备正常
  • 通过UART向ATXMEGA16E5发送文本指令,由myFunction处理并更新Values数组对应myIndex索引的值
  • 仅当myIndex等于3且执行InputValue函数时,TCC4定时器会无诱因停止;重启后操作其他myIndex值则无问题
  • 已在测试程序中验证CommaIndex和InputValue函数功能正常

更新内容

  • 已按建议为Rxbuf添加0x00终止符,问题仍存在
  • 发送给芯片的消息格式为:cmnd,lmn,1000(cmnd为4字符指令,lmn为指定标识,数值范围0-16383),通过'\n'判断消息接收完成,且myFunction仅被调用一次、执行过程无干扰,Rx中断未丢数据

测试发现

  • 注释myFunction中的两条UsartSendString语句后,问题消失
  • 在UsartTxChar中添加1ms延时后,即使保留UsartSendString语句,问题也不再出现,但不确定这是根本解决方案还是临时规避方法

相关代码

主程序及定时器相关代码

#define BUFLEN 50       // for UART
#define CHARGE_LVLs     10 
char Rxbuf[BUFLEN];
volatile uint16_t Values[LVLs] = {12400, 4600, 2250, 1150, 430, 210, 15980, 15630, 15000, 13700};

int main(void)
{
    ...
    RTCInit();
    IRQInit(1, 1, 1);
    TimerInit();
    ...
    sei();
    
    while(1) 
    {
        ... 
        if(Rxflag==1)
        {
            if (strstr(Rxbuf, "myString,"))
                myFunction();
            Rxflag=0;
        }

    }
}

void myFunction()
{
    if(strstr(Rxbuf, ",abc,")) {myIndex=0; isUpdated = 1;}
    if(strstr(Rxbuf, ",def,")) {myIndex=1; isUpdated = 1;}
    if(strstr(Rxbuf, ",ghi,")) {myIndex=2; isUpdated = 1;}
    if(strstr(Rxbuf, ",lmn,")) {myIndex=3; isUpdated = 1;} // <------
    if(strstr(Rxbuf, ",opq,")) {myIndex=4; isUpdated = 1;}
    if(strstr(Rxbuf, ",rst,")) {myIndex=5; isUpdated = 1;}
    if(strstr(Rxbuf, ",uvz,")) {myIndex=6; isUpdated = 1;}
    if(strstr(Rxbuf, ",123,")) {myIndex=7; isUpdated = 1;}
    if(strstr(Rxbuf, ",456,")) {myIndex=8; isUpdated = 1;}
    if(strstr(Rxbuf, ",789,")) {myIndex=9; isUpdated = 1;}
    
    if(isUpdated == 1)
    {
        if(strstr(Rxbuf, WRITE_CALIB))
        {
            comma_index = CommaIndex(s, BUFLEN);
            if (InputValue(s, comma_index) > MAXVALUE) // <------
                Values[myIndex] = MAXVALUE;
            else
                Values[myIndex] = InputValue(s, comma_index);
            
            answ=1;
            UsartSendString(OK);
        }
    }
    
    UsartSendString("\r\n");
}

char CommaIndex(char s[], char strlength)
{
    int i;
    
    for(i=5; i<strlength; i++)  
        if (s[i] == ',')
        break;
    return (char)i;
}

uint16_t InputValue(char s[], char comma_index)
{
    return atoi(s+comma_index+1);
}

void IRQInit(char hi, char med, char lo) {
    PMIC.CTRL = (hi<<PMIC_HILVLEN_bp)|(med<<PMIC_MEDLVLEX_bp)|(lo<<PMIC_LOLVLEN_bp);
}

void RTCInit(void) {
    RTC.PER = 100;                              // 100ms
    RTC.INTCTRL = RTC_OVFINTLVL_MED_gc;         
    RTC.CTRL = RTC_PRESCALER_DIV1_gc;           // No prescaler
}

void TimerInit(void)
{
    TCC4.CTRLA =  TC_CLKSEL_DIV64_gc;           // CLKSEL=DIV64 : 32MHz/64=500KHz
    TCC4.PER = 4;                               // 500KHz/4 = 125KHz        @ 32 MHz
    TCC4.INTCTRLA = TC_CCAINTLVL_HI_gc;         // Int pri HI 
    TCC4.CTRLGCLR = 0b00000000;                 // Up direction
}

// *** Timer Overflow: 125KHz (8us) ***
ISR(TCC4_OVF_vect)
{
    if(emission)
    {
        PULSE_ON;
        
        emission = 0;
    }
    else
    {
        PULSE_OFF;
    }
    
    //************************************
    // Only for debug *********
    interruptCounter++;
    
    if (interruptCounter > 125000)
    {
        UsartSendString("Running");
        interruptCounter = 0;
    }
    //************************************

    TCC4.INTFLAGS = 1;
}

UART相关代码

void
UsartInit(void)
{

    USARTC0.CTRLA = USART_DRIE_bm | USART_RXCINTLVL_MED_gc; // RX Int + Med pri
    USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;  // RX & TX enable, Clk 1x
    USARTC0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc; // Asynch, 8 bit, 1 stop, par none
    USARTC0.CTRLD = 0;                  // No encoding
    USARTC0.BAUDCTRLA = 51;             // BSEL
    USARTC0.BAUDCTRLB = 0b00100000;     // BSCALE 2 @ 32MHz
}

void
UsartTxChar(char b)
{
    USARTC0.DATA = b;

    _delay_ms(1);  // <---- THIS SOLVES THE ISSUE *****************

    while (!(USARTC0.STATUS & USART_TXCIF_bm)) {
    };

}

void
UsartSendString(char *b)
{
    int i;

    i = 0;
    while (b[i]) {
        UsartTxChar(b[i]);
        i++;
    }
}

ISR(USARTC0_RXC_vect)
{

    Rxchar = USARTC0.DATA;

    if (!Rxflag) {
        Rxbuf[Rxpnt] = Rxchar;
        Rxpnt++;
        if (Rxpnt == BUFLEN)
            Rxpnt--;
    }

    if (Rxchar == '\n') {
        Rxflag = 1;
        Rxpnt = 0;
    }
}

内容的提问来源于stack exchange,提问作者user1941332

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 00:55:55