串口通讯进入HardFault的问题
在对GPRS模块调试时,遇到了个问题, void ReadPhoneBook(void){ UART1_SendString("取消回显开始:\r\n"); Flag=0; Second_AT_Command("ATE0","OK",3); //取消回显 UART1_SendString(Uart2_Buf); //把模块返回的信息原样输出 UART1_SendString("取消回显结束:\r\n"); HAL_Delay(2000); UART1_SendString("读取电话号码开始:\r\n"); Flag=1; Second_AT_Command("AT+CPBR=1,2","OK",3); UART1_SendString(Uart2_Buf); //把模块返回的信息原样输出 UART1_SendString("读取电话号码结束:\r\n");}上面的紫色部分不要的话,在正常通讯3,4次后,就一定会掉进void HardFault_Handler(void)里。要的话,就一点问题都没有。我这里在对程序的关键点注释一下:因为对于紫色部分的Second_AT_Command("ATE0","OK",3); GPRS模块应答 就只回OK,只有一行。而对于Second_AT_Command("AT+CPBR=1,2","OK",3);则会应答2行以上的信息。所以在下的红字体做了区分。void HAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){ static chari; UNUSED(huart); if(huart==&huart1) { } else if(huart==&huart2) { //不定长接收 Uart2_Buf = uart2_RXdata; //接收不定长数据(其实是每次只接收一个字节),直到遇到\n,才进行处理。或者长度大于缓存数组的长度 if(i >= Buf2_Max || Uart2_Buf== '\n') { /*接收完一串数据后进行处理*/ RXend_usart2 =SET; if(!Flag) i=0; } } }关于,对于上面的2条指令,GPRS模块所反馈应答的内容,可以参看《PC通过串口调试助手模拟》图 ,另外MCU调试得截图也附上
void ReadPhoneBook(void){ UART1_SendString("取消回显开始:\r\n"); Flag=0; Second_AT_Command("ATE0","OK",3); //取消回显 UART1_SendString(Uart2_Buf); //把模块返回的信息原样输出 UART1_SendString("取消回显结束:\r\n");
HAL_Delay(2000);
UART1_SendString("读取电话号码开始:\r\n"); Flag=1; Second_AT_Command("AT+CPBR=1,2","OK",3);
UART1_SendString(Uart2_Buf); //把模块返回的信息原样输出 UART1_SendString("读取电话号码结束:\r\n");} 进入harddefault一般都是硬件问题引起的,好好检查下硬件 i >Buf2_Max有数据接收的话仍然会往接收数组中加数据,数组溢出肯定进hardfault freeelectron 发表于 2019-12-2 09:33
进入harddefault一般都是硬件问题引起的,好好检查下硬件
hardfault一般不是硬件问题引起,一般是内存溢出、越界、野指针等引起。他这个问题,很可能就是数组越界 如楼上所说数组越界的可能性大
if(i >= Buf2_Max || Uart2_Buf== '\n')
这个指令中应该是i>Buf2_Max 如果等于的话已经是越界了
比如buf这个数组只能存8个数但是i>=8的时候是存了9个数,i>8是存了8个数编程时需要注意一下 衔胆栖冰 发表于 2019-12-2 09:49
hardfault一般不是硬件问题引起,一般是内存溢出、越界、野指针等引起。他这个问题,很可能就是数组越界 ...
你说的对 我支持你 个人觉得,Uart2_Buf 如果是空字符串【HAL_UART_RxCpltCallback,没收到字符】,UART1_SendString(Uart2_Buf) 就有问题。
楼主应注意这点,如何确保 UART1_SendString(Uart2_Buf) 时,Uart2_Buf 不空 https://www.stmcu.org.cn/module/forum/thread-621377-1-1.html 一般这种问题时数组溢出导致,建议查看接收缓存,还有发送缓存的空间。如果容易复现,建议在线调试,进入fault后,通过寄存器判断进入fault的代码产生再哪一行。网上有很多介绍进入fault原因的分析方法。
页:
[1]
2