基于STM32F103的485modbus通信问题,

我用STM32F103单片机的UART3连接一个sp3485芯片,利用485通信,485总线上挂载了四个485传感器,分别是采集PH,电导率,液位,和含氧量的四个传感器。

出现了以下问题
1.while循环中 其中有四行代码 ,分别是

(1)采集PH,

(2)采集液位高度

(3)采集液体电导率

(4)采集含氧量

这四行代码是分别封装的函数,里面的通信格式是用Modbus,用串口轮询方式HAL_UART_Transmist 发送指令给传感器,再用串口轮询接收HAL_UART_Receive方式接收传感器返回来的数据。


但是,只能维持一天的时间左右,大概过了30个小时,单片机又会采集到全部都是零的数据,但是不是死机的状态,他其他程序还是可以运行,就是采不到数据。
折腾了好多天,都不知道是什么问题。

       然后我通过抓包  将485总线线上的信号通过485转USB串口返回电脑,通过串口助手发现:

代码的预期指令数据和发出去的指令数据不一致,比如,我代码要求的是串口通过轮询的方法发送

指令 :01  03  00 02  00  01  DA  8F  (这一串指令放在一个uint8_t 的全局数组里面),但是发送到到485总线上的信号是 : 00 00  00  02  00  01 DA  8F  ,这就不难奇怪,为什么我的传感器返回的数据是0了,因为485通信的机制是一问一答,modbus的通信就是主机发送指令 (指令包含地址码、功能码、数据、CRC校验码),当你的指令其中任何一个内容发生异常改变,传感器都不会产生应答返回数据,因为只要有一个内容出错,那么CRC校验码肯定会出错,所以这条指令肯定是无效的。

        但是为什么会出现这个问题呢?

这个bug相当于是全局变量发生的异常改变;

1、定义的全局数组在其他线程被更改了  (但是通过查看,在程序的其他地方并没有发现这个全局数组被引用了)

2、被编译器优化 (尝试加volatile,结果无效)

3、数组或者指针越界,栈溢出(编译没报错)

        解决办法,在全局数组的前面加 const  关键字,和将全局数组定义成局部数组,需要的时候就重新初始化,用完立即释放内存。

笔者觉得应当是内存问题。所以,当你希望一个数据它不被修改的时候记得加上 “const” 修饰。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值