在使用官方的代码的时候,发现程序运行起来后就会复位。很是奇怪,然而发现之前应用的一段类似的代码却没有问题,一步步缩小错误范围之后发现,唯一的区别就是使用ROM中的函数程序运行正常,而使用库里面的函数则程序会自动复位。
最后定位到UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);这一个函数上。
使用UARTClockSourceSet程序会自动复位,而是用ROM_UARTClockSourceSet程序运转正常。
就是这个简单的命令行初始化函数。
void InitConsole(void) { // // Enable GPIO port A which is used for UART0 pins. // TODO: change this to whichever GPIO port you are using. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for UART0 functions on port A0 and A1. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); // // Enable UART0 so that we can configure the clock. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Use the internal 16MHz oscillator as the UART clock source. // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // // Select the alternate (UART) function for these pins. // TODO: change this to select the port/pin you are using. // GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, 16000000); }
这是官方提供的代码段,未做修改。
我在KEIL5中用Jlink仿真的时候,全速运行,程序后自动复位。
然后如果将断点设置在
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
一句上,再向下运行,程序则又可以运行。
于是我就怀疑是不是外设还没有使能,这函数才出错的,我就屏蔽掉
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
这一句外设使能。发现设置断点程序也会复位。
这时我就考虑在
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
前面加一句延时函数
SysCtlDelay(100000);
这时全速运行程序就没有错误了。
然后如果将官方代码
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
改为
ROM_UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
程序不需要延时也可以运行。
最后总结:
感觉应该是
UARTClockSourceSet函数中缺少判断外设是否使能的操作,然后外设还没来得及初始化,就操作那个寄存器,这样才导致系统复位的。
不知道理解是否有误,因为比赛临近,没时间细致研究库函数的寄存器操作是否有误了。
或者可能是我的忽略了哪个地方?库函数根本没有错误,望工程师们能帮我做个测试。帮我解决这个疑惑,谢了。。。。
上传我会出错的代码。代码完全是DK-TM4C123G Firmware Development Package\examples\peripherals\systick下的文件,未做修改。
库函数版本 2.1.0.12573 开发环境是Keil 5.1 芯片TM4C213GH6PGEI 仿真器是Jlink V8