hqw 发表于 2019-12-2 08:48:39

串口通讯进入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调试得截图也附上

hqw 发表于 2019-12-2 08:54:17

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");}

freeelectron 发表于 2019-12-2 09:33:52

进入harddefault一般都是硬件问题引起的,好好检查下硬件

衔胆栖冰 发表于 2019-12-2 09:47:46

i >Buf2_Max有数据接收的话仍然会往接收数组中加数据,数组溢出肯定进hardfault

衔胆栖冰 发表于 2019-12-2 09:49:24

freeelectron 发表于 2019-12-2 09:33
进入harddefault一般都是硬件问题引起的,好好检查下硬件

hardfault一般不是硬件问题引起,一般是内存溢出、越界、野指针等引起。他这个问题,很可能就是数组越界

mylovemcu 发表于 2019-12-2 09:54:55

如楼上所说数组越界的可能性大

if(i >= Buf2_Max || Uart2_Buf== '\n')
这个指令中应该是i>Buf2_Max   如果等于的话已经是越界了
比如buf这个数组只能存8个数但是i>=8的时候是存了9个数,i>8是存了8个数编程时需要注意一下

斯文人 发表于 2019-12-2 13:56:30

衔胆栖冰 发表于 2019-12-2 09:49
hardfault一般不是硬件问题引起,一般是内存溢出、越界、野指针等引起。他这个问题,很可能就是数组越界 ...

你说的对 我支持你

mikecai 发表于 2019-12-2 15:42:11

个人觉得,Uart2_Buf 如果是空字符串【HAL_UART_RxCpltCallback,没收到字符】,UART1_SendString(Uart2_Buf) 就有问题。
楼主应注意这点,如何确保 UART1_SendString(Uart2_Buf) 时,Uart2_Buf 不空

songshiqun2010 发表于 2019-12-3 10:33:44

https://www.stmcu.org.cn/module/forum/thread-621377-1-1.html

发表于 2019-12-4 09:06:57

一般这种问题时数组溢出导致,建议查看接收缓存,还有发送缓存的空间。如果容易复现,建议在线调试,进入fault后,通过寄存器判断进入fault的代码产生再哪一行。网上有很多介绍进入fault原因的分析方法。
页: [1] 2
查看完整版本: 串口通讯进入HardFault的问题