项目背景:
现场变送器安装在变电站强电附近。产品批量生产使用一段时间后,最近突然有一个站点出现通讯故障问题。开始于某个变送器无法召唤数据,慢慢的所有变送器全部掉线。如果重新上电,变送器的数据都正常。掉线时间随机,掉线点位随机。
解决过程:
根据现象,分析应为现场总线上的干扰导致。之前用了TI的485芯片,做了基本的通讯线路保护,后查资料,最好使用带有隔离的485芯片,于是采用了金升阳的某一485隔离芯片。重新设计电路板后现场更换,运行一段时间仍然会出现这种现象。现场采集发现过485网关数据丢失数据的问题。
既然现场干扰问题不好解决,只能从变送器本身的做文章,主要下手的目标就是stm32主控芯片本身。
485总线的干扰会引起数据错误,高低电平不稳导致的芯片识别为不定长度的01010010组合,瞬间可能就把接收数组搞溢出。在更换隔离的485芯片的同时,将片内的看门狗已设置,那么如果是有HARDFAULT的话一段时间后也会重启程序。
下一步就查看DMA接收方面的资料,下面的链接给我了启发,干扰后可能导致DMA无法进入接收中断。
https://blog.csdn.net/hxkrrzq/article/details/102664983
https://www.jianshu.com/p/6995fb60364f
https://blog.csdn.net/qq_20999867/article/details/92961110
https://blog.csdn.net/tiantangmoke/article/details/103308851
由于我的经验有限,学习stm32 时使用的是HAL库,标准库的一个寄存器的使用不敢乱动。于是我就使用了比较蹩脚的方式:看门狗程序设置好,使用定时器监视总线数据收发,由于上位机程序轮询时间一般设置为1~3秒,于是将定时器设置为一秒溢出全局变量“catch_count”加一,在接受标志位处“catch_count”清零。判断“catch_count”大于5,也就是5秒内没有接收到数据,就将串口重新初始化。
更改程序后,进行人工干预485总线,连接多个变送器,老程序3个,新程序2个,干扰到都没有数据后,等待下次轮询结果,老程序就无法采集,新程序能正常恢复。
此方法虽然能解决问题,比较粗暴,能解决偶尔总线干扰引起的假死现象,但是如果现场干扰是持续发生的话,还是从现场总线屏蔽保护方面进行解决。
已下是stm32 cubemx的配置及程序部分内容:
看门狗设置:
MX_IWDG_Init();
尽量靠近while(1)大循环前开启看门狗,放置前置初始化外设时间过长。
HAL_IWDG_Refresh(&hiwdg);
喂狗函数。
超时未接收数据后进行串口重新初始化
if(catch_count > 5)
{
HAL_UART_MspDeInit(&huart2);
HAL_UART_MspInit(&huart2);
}
定时器设置
记得开启定时器中断
HAL_TIM_Base_Start_IT(&htim3);
有什么更好的办法欢迎交流。