通过RS485控制福禄克8808A台式数字多用表时,MCU发送的控制指令的有效性不一致(有时候需要重复发送多次控制指令才能成功)。解决方法及该问题出现的原因分析。

 一、错误现象

        台式数字多用表无法按照MCU发送的控制指令正常工作。MCU发送的控制指令时而有效,时而无效。一条控制指令有时候需要重复发送多次才能生效!

二、错误排查与分析

        首先,我们先以宏观的角度开始排查,该通讯的对象是由控制模块(STM32)和被控模块(台式数字多用表)组成的,所以我们应该先把问题的大概位置方向找出来。因此我通过串口助手来发送相同的控制指令,来判断问题的根源是不是在被控模块(台式数字多用表),但是发现使用串口助手发送的控制指令能够正常地控制被控模块(台式数字多用表),由此可知,问题应该出自控制模块(STM32)。之后,我使用示波器查看STM32输出的波形、RS485芯片输出的波形以及该电路末端的波形,发现波形很好看,挺标准的矩形波。由此可以排除不是电路上的电容的影响了。至此,我依然坚信不是我代码的问题,但是结果打脸了!我通过示波器观察和比对串口助手发送的控制指令波形和STM32发送的控制指令波形,发现STM32发送的控制指令波形末端比串口助手发送的控制指令波形多发送了一个字节的波形。至此错误问题的根源找到了。MCU发送的控制指令之所以无效,是因为我发送控制指令多个一个未知的字节。该未知字节其实是\0 。

图1:串口助手发送的控制指令波形

图2:STM32发送的控制指令波形 

 

三、自我犯错的原因分析

sizeof实际上是获取了数据在内存中所占用的存储空间,以字节为单位来计数。

C语言会自动在在双引号""括起来的内容的末尾补上"\0"代表结束,ASCII中的0号位也占用一个字符。

//直流电流指令
uint8_t directCurrentCmd[] = "ADC\r\n";

void UART_Transmit( uint8_t channel,uint8_t* pdat,uint16_t lenght,uint16_t time)
{
	UART_RTS_SET(channel,OUT);
	huart[channel].Instance->CR1 |=  USART_CR1_TE;
	HAL_Delay(1);
	HAL_UART_Transmit(&huart[channel], pdat, lenght, time);
	huart[channel].Instance->CR1 &=  ~USART_CR1_TE;
}


//发送控制指令
UART_Transmit(USART_03, directCurrentCmd, (sizeof(directCurrentCmd)-1), 600);

使用sizeof计算数组的长度时,它会把\0也会计算进去的,所以要注意sizeof计算出来的长度可能不是你输入数据的长度。

解决方法:

        1、把多计算的\0的数值去掉,剩下的就是你想要的数据长度。(不推荐,有局限性,麻烦)

        2、改用strlen函数计算数组的长度。

      size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电气码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值