文章目录

  • 一、硬件部分
  • 二、modbus CRC计算



本文为个人从零开始使用485的总结,我也仅仅在做项目时看文章学习的,没有过系统性的学习。下面将要说的也是从零开始使用485的见解,有什么不对的还请各位大佬评论区斧正。

一、硬件部分

485是什么?

Android 485串口数据接收 485串口读取指令_Android 485串口数据接收


来自百度词条。

看完之后一脸问号,更不知道是啥了。

简单来说,485就是用来通讯的。就像我们学单片机用的串口:UART、IIC、SPI等,是为了两个设备之间交换数据的。

不过为什么设备之间交换数据要用485嘞,SPI与IIC它不香吗,为啥还要再来一个这个的东西。

这就要开始说485的相对于其他通讯方式的优点了,因为485传输数据用的是差分信号,利用两根双绞线进行传输,抗干扰能力强,这是他相对于以上通讯方式最大的优点了。知道了以上这些,我们来谈一谈使用。

因为485传输的是差分信号,而我们的单片机并不能直接产生差分信号来传输,于是我们能在各个IC制造商(如TI、ADI等)看到他们有个485驱动器的IC。有了这个IC,我们就可以用单片机发出数字信号给485驱动器,485驱动器生成相应的差分信号传输出去。

下面看一下一些485驱动器的电路:

Android 485串口数据接收 485串口读取指令_单片机_02


可以看到左边的网络标号有RXD与TXD,没错,它就是接UART的那两个线。不过比UART多了一个choose,其作为接受和发送的选择端,二者选其一,所以485为半双工通讯。

右边的A和B就是输出差分信号的线,与其他的485器件的A和B连接。关于差分电平和终端电阻问题暂不讨论。

因为接触的不深,在这里不讨论四线的485.看了上面这些,下面就贴我已经试验过的485电路图吧。

Android 485串口数据接收 485串口读取指令_寄存器_03


我用了两个IC,一个隔离一个485驱动,成本在二十多(嘉立创报价),相对来说成本还是比较高的。不过本人也是第一次用485所以选择了最保守的方案,不过baud rate:4800~115200都已测试,可用。

UART接口用的是TI的隔离,电源用的是金升阳的5Vto5V的隔离电源,将485与单片机隔开。

而且选用的美信MAX13488的485IC,这款IC可以自动切换收发,无需IO控制收发,很是方便。虽然网上也有很多用外部电路实现的自动收发的电路,如[1]文章中用一个三极管解决的,不过我还是依旧保守,并没有采用这个方案,不过日后有机会可以试试。这个双IC的方案在PCB布局上也挺简单的,不过有点占地方。

Android 485串口数据接收 485串口读取指令_单片机_04


上面是我的PCB布局以供参考。

二、modbus CRC计算

代码如下(示例):

//-------------------------------------------------------------------------------------------------------------------
// @brief		modbus-CRC计算
// @param		data  想要计算的数组    len  数组的个数
// @param		CRC_H   计算出CRC值的高8位     CRC_L 计算出CRC值的低8位
// @return		void
//-------------------------------------------------------------------------------------------------------------------
void CRC_figure (uint8 *data,uint8 len,uint8 *CRC_H,uint8 *CRC_L)
{
	uint16 CRC_value = 0xffff;
	uint8 Data = 0;
	uint8 i;
	while (len--)
	{
		Data = *data;
		CRC_value ^= Data;
		for (i=0;i<8;i++)
		{
			if((CRC_value&0x0001) != 0)
			{
				CRC_value >>= 1;
				CRC_value ^= 0xA001;//0xA001是0x8005按位颠倒的
			}
			else CRC_value >>= 1;
		}
		data++;
	}
	*CRC_H = CRC_value & 0xff;//计算出的CRC是高位在后
	*CRC_L = CRC_value >> 8;  //             低位在前
}

如果不想理解CRC算法的话直接复制过去调用就可以了。因为不同的CRC校验的公式不一样,这个只能适用于modbus-RTU通讯。
以上是关于modbus的一个简单的应用,具体可以根据使用modbus的那一部分可以去看那一部分,例如功能码,输入寄存器,线圈寄存器和保持寄存器等;