STM32 - 解决一次下位机偶校验收包乱码的问题

问题描述

我们有一个带IP的网口转串口的小设备,用在现场,接在路由器上,从网络来和485设备来通讯。
现场有很多485设备,如果是9600/n/8/1, 通讯没问题;如果校验不是无校验,我们做好的应用,就无法和设备通讯。

这设备固件是2017年写的,现在没人维护了。用起来没发现问题。
以前遇到过有校验的情况,当时是联系设备厂商,让他们指导如何将设备通讯参数改为无校验,就能通讯了。

这次在现场的设备是台空调,现场工程师在仪表面板中提供的功能中,并没有发现如何将空调的通讯参数改为无校验的UI界面。正在和厂家联系。

我从研发的角度看,公司有网转串设备的同型号现货,我可以先验证一下,是否真的是网转串设备本身不支持有校验的通讯方式。

我和同事做了测试,他从一台计算机上,从网口向设备的输入端网口发数据,我从设备的485输出端口接一个485转串口,在电脑上等着他发的数据。

当通讯参数为9600/n/8/1时,可以收到他发来的原样数据。
当通讯参数为9600/偶校验/8/1时,我这边的电脑调试助手收到的是乱码,他发来3个16进制字节,我收到4个16进制字节乱码。乱码和原样数据没人任何关系。

尝试解决

既然确定是设备有问题,从svn上迁出这个设备的固件工程看了一下。

我第一感觉是串口初始化参数有问题。

连上仿真器,单步一下,看下在校验方式设置时,是否有区别?
没看出区别。

去网上查STM32接收乱码的问题,网上说到一个上位机(e.g. 串口助手)数据长度为8,下位机(e.g. STM32固件)的数据长度要设为9。说是数据长度是数据位长度 + 停止位的和。

试了一下,将数据位设置位9, 可以通讯了。

去查一下,这个上位机数据长度为8,下位机数据长度必须设置为9,这个说法是从哪来的?没查到。
官方文档没说法。官方F1固件库中串口的例子工程,都是直接给串口通讯参数赋值,并没有根据上位机通讯参数来设置下位机通讯参数的例子。

那我估计,可能是前面的同学,自己试出来的。比如8位不行,又没有其他解决方法,那还有个9位可以用一下,试了一下好使这样子。

我们工程中,通讯参数是通过udp通讯,先设置到设备中,设备重启后,读通讯参数,然后串口初始化。

void STM32_UART1_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);	//UART时钟配置
	
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate   = setinfo.Device_Baudrate;			//比特率设定
	if(setinfo.USART_WordLength==7)
	{
	     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  	//8数据位长度	
	}
    else if(setinfo.USART_WordLength==8)
	{
	     USART_InitStructure.USART_WordLength = USART_WordLength_9b;  	//9数据位长度
	}

我们实施的同事,以前遇到这种有校验的方式,都是请厂家工程师指导我们改设备通讯参数,甚至跪求厂家工程师帮我们直接刷无校验的实现 😛

其实应用方面的问题,前面的同学大多都解决掉了。做一下实验,查一下资料,再做一下实验搞定:)

真的很少问题是确实前面的同学从来没解决过,没分享过,非要自己亲自操刀来解决,这种特殊情况很少的。

©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页