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
相关产品推荐
相关产品推荐

