先上代码:
//***************************************************************************** // // The UART interrupt handler. // //***************************************************************************** void UARTIntHandler(void) {uint32_t ui32Status;unsigned char Temp = 0;//// Get the interrrupt status.//ui32Status = ROM_UARTIntStatus(UART0_BASE, true);//// Clear the asserted interrupts.//ROM_UARTIntClear(UART0_BASE, ui32Status);//// Loop while there are characters in the receive FIFO.//while(ROM_UARTCharsAvail(UART0_BASE)){switch(STE) { case 0: { Temp=ROM_UARTCharGetNonBlocking(UART0_BASE); if(Temp==0xA5){DATA_OK=0;STE=1;} else{STE=0;} }break; case 1: { Temp=ROM_UARTCharGetNonBlocking(UART0_BASE); if(Temp==0x5A){STE=2;} else{STE=0;} }break; case 2: { Temp=ROM_UARTCharGetNonBlocking(UART0_BASE); if((Temp==0x11)||(Temp==0x04)||(Temp==0x05)) { cDATA[0]=Temp; COUNT_M=Temp; UART_COUNT=COUNT_M-1; STE=3; } else{STE=0;COUNT_M=UART_COUNT=0;} }break; case 3: { cDATA[COUNT_M-UART_COUNT]=ROM_UARTCharGetNonBlocking(UART0_BASE); if(UART_COUNT==2){STE=4;} else{UART_COUNT--;} }break; case 4: { Temp=ROM_UARTCharGetNonBlocking(UART0_BASE); if(Temp==0x12){STE=5;COUNT_M=UART_COUNT=0;} else{STE=0;} }break; case 5: { Temp=ROM_UARTCharGetNonBlocking(UART0_BASE); if(Temp==0x34){STE=6;} else{STE=0;} }break; case 6: { ROM_UARTCharGetNonBlocking(UART0_BASE); DATA_OK=1; STE=0; }break; default:break; }} }
然后,附上UART0配置:
//// Enable the peripherals used by this example.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//// Set GPIO A0 and A1 as UART pins.//ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//// Configure the UART for 9,600, 8-N-1 operation.//ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 9600,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));ROM_UARTFIFOEnable(UART0_BASE);ROM_UARTFIFOLevelSet(UART0_BASE,UART_FIFO_TX4_8, UART_FIFO_RX1_8);ROM_IntMasterEnable();ROM_IntEnable(INT_UART0);ROM_UARTIntEnable(UART0_BASE, UART_INT_RX );IntPrioritySet(INT_UART0, 0x00);
简单的执行程序,是可以正确接收到数据。
BUT,当我同时读取MPU6050并通过DCM解算欧拉角时,(在MAIN函数中while 1 循环读取MPU6050,然后定时器中断中进行DCM更新,并求Eulers,200Hz)
问题来了:
1 ) cDATA[ ]数组中的值竟然会发生变化,即使发送端没有发送任何UART信号。也没有对数组做任何操作。
2) 当我开始发送信号,能读回前几位,然而后面就不对了,而且会卡在STE=3。
3) 持续发送信号,出错,进入死循环
FaultISR(void) {//// Enter an infinite loop.//while(1){} }
。。。
在排查问题的时候,我把更新DCM的定时器关了,即不进行200Hz的姿态解算,UART接收正常了。。发送停止时,数组也不会乱跳。
我已经把UART中断优先级放到最高,然后是I2C,再是TIMER。
系统时钟16M,没有用PLL,FPU已使能。
不知道问题出在哪了,求高手解答…
PS: UART发送格式:A5 5A 11 XX XX XX XX XX XX XX XX XX XX XX XX XX 12 34 XX;
状态机自己写的,很有可能有漏洞,请高手指点..如果有TI官方的UART 连续 接收 程序就更好了,在此我不关心发送。。
xyz549040622:
cDATA[ ]数组中的值竟然会发生变化,即使发送端没有发送任何UART信号。也没有对数组做任何操作。关键就在这里,你跟踪看看cDATA[ ]数组中的值为什么会变化呢,没有发送的话,为什么会变化呢,应该是你哪里误操作了。
Dehua Mo:
回复 xyz549040622:
估计也是自己UART使用的不对吧。。我觉得还是以uDMA–UART的方式来做吧,正在尝试
Dehua Mo:
回复 Dehua Mo:
终于查出原因了。
问题出在——数组变量的声明和初始化。
应该用volatile定义我的数组,因为只用uchar,则很有可能被编译器优化..发生不可预期的跳变!
http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html
不了解volatile的可以去这个博客看看。
Dehua Mo:
查出来了。
问题出在数组变量的定义。
应该加上volatile,否则可能被编译器优化,发生不可预期的操作。
xyz549040622:
回复 Dehua Mo:
那么应该是你的这个数组没有进行写的操作,被编译器优化了。优化等级调一下。。。