RS485是主流的一种多机通信方式,多用于不同设备间的数据传送。最常见的是主控板和485接口的传感器间的通信。下面介绍常用的通信方式及代码,包括常用的CRC校验。
初始化代码:(初始化控制引脚(收发)和对应串口(看硬件连接))
//bound:波特率
void RS485_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PE1端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
USART2_Init_JAVE( bound);
RS485_TX_EN=0; //默认为接收模式
}
下面是发送和接收部分的代码
//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
u8 t;
RS485_TX_EN=1; //设置为发送模式
for(t=0;t
RX2_Point是串口2的接收指针。
解释一下接收函数,首先定义一个临时变量并赋予它RX2_Point的值,然后做一定的延时。如果这时候已经接收完成了,那么RX_Point的值不会变,rxlen也依然等于它。若还没接收完成,RX2_Point 的值会继续增加rxlen就不会相等,这时候执行这个函数就不会有想得到的结果了,所以在发送和接收之间必须有足够的延时等待从机响应主机的命令。后面以一个传感器读数示例会体现这一点。
RS485通信通常需要使用两个字节的校验码来增加信号传输的可靠性,如果传输过程无误,校验码输出0。
获取CRC代码:
参数分别为:输入数字首地址,校验长度,输出结果(16位,即两字节)
有关于CRC的计算流程可自查百度
void Get_CRC(u8 *buf,u8 len,u16 *crc_out)
{
int i=0,j=0;
u16 crc,out;
crc=0xffff;
for(i=0;i>= 1;
crc=crc^0xa001;
}
else{
crc >>= 1;
}
}
}
*crc_out=crc;
}
主从通信中,主机给从机发送命令,一般也要带校验码,这个校验码有些设备的说明书会带上命令对应的校验码。可以直接发送,也可以程序根据命令计算出校验码后发送。
下面以一485接口的传感器通信为例:
float Task_Read_485Senor(void)
{
unsigned char RS485[11]={0x01,0x04,0x00,0x00,0x00,0x03,0,0};
unsigned char num=6;
u16 CRC_RES=0,temp;
RS485_Init(9600); //初始化485
Get_CRC(RS485,num,&CRC_RES); //获取命令CRC
RS485[6]=CRC_RES%256; //CRC低位
RS485[7]=CRC_RES/256; //CRC高位
RS485_Send_Data(RS485,8); //发送8个字节读取命令
delay_ms(2000); //延时一定时间,确保接收完成了
RS485_Receive_Data(RS485,&num); //接收结果写入数组
Get_CRC(RS485,num,&CRC_RES); //接收结果CRC校验
if( CRC_RES == 0 ){ //有效数据
//return 读数;
}
else{ //无效
MyPrintf("CRC校验错误\r\n");
return 0xff; //返回失败
}
return 0xff;
}