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

串口通讯进入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

查看全部评分

斯文人 回答时间: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 不空

评分

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

查看全部评分

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

评分

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

查看全部评分

12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版