你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

串口通讯进入HardFault的问题

[复制链接]
hqw 提问时间:2019-12-2 08:48 /
在对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 char  i;
                          UNUSED(huart);
               if(huart==&huart1)
               {
                                                         }
               else if(huart==&huart2)
               {
                    //不定长接收
                    Uart2_Buf[i++] = uart2_RXdata;
                                                                                       //接收不定长数据(其实是每次只接收一个字节),直到遇到\n,才进行处理。或者长度大于缓存数组的长度
                          if(i >= Buf2_Max || Uart2_Buf[i-1]== '\n')
                         {
                              /*接收完一串数据后进行处理*/
                                                                                          RXend_usart2 =SET;
                                                                                         if(!Flag) i=0;                                                                 
                   }
                                                        }
        }
关于,对于上面的2条指令,GPRS模块所反馈应答的内容,可以参看《PC通过串口调试助手模拟》图

另外MCU调试得截图也附上

MCU程序调试.png
PC通过串口模拟.png

ReadPhoneNumber1131 - light - 副本.rar

下载

8.6 MB, 下载次数: 0, 下载积分: ST金币 -1

收藏 评论10 发布时间:2019-12-2 08:48

举报

10个回答
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

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

衔胆栖冰 回答时间: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[i-1]== '\n')
这个指令中应该是i>Buf2_Max   如果等于的话已经是越界了
比如buf[8]这个数组  只能存8个数  但是i>=8的时候是存了9个数,i>8是存了8个数  编程时需要注意一下

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

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

你说的对 我支持你
慎微 回答时间:2019-12-2 15:42:11
个人觉得,Uart2_Buf 如果是空字符串【HAL_UART_RxCpltCallback,没收到字符】,UART1_SendString(Uart2_Buf) 就有问题。
楼主应注意这点,如何确保 UART1_SendString(Uart2_Buf) 时,Uart2_Buf 不空

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

废鱼 回答时间:2019-12-4 09:06:57
一般这种问题时数组溢出导致,建议查看接收缓存,还有发送缓存的空间。如果容易复现,建议在线调试,进入fault后,通过寄存器判断进入fault的代码产生再哪一行。网上有很多介绍进入fault原因的分析方法。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

cloudcn 回答时间:2019-12-4 12:01:17
出现Hardfalt 大部原因都是读写越界
如果用 MDK调试的话注意关注CALL STACK里面能看出在调用那个函数挂的
仔细查就是了

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版