利用RS485通信、串口收发数据的硬件连接及部分代码 您所在的位置:网站首页 单片机与显示屏的串口连接 利用RS485通信、串口收发数据的硬件连接及部分代码

利用RS485通信、串口收发数据的硬件连接及部分代码

2023-12-29 11:49| 来源: 网络整理| 查看: 265

1、设计思路 1.1、总体设计思路

设计思路:单片机A检测单片机B的功能,单片机B待检测的地方全部引出,然后再将一些功能信息发送到屏幕。单片机A和单片机B之间、单片机A和屏幕(一种可视化编辑的屏幕,规定好通信协议,利用485通信将字符串发送过去就能显示相应的内容,屏幕:TK607ID) 。

注:本文只对单片机B的485通信功能进行检测,所用的单片机芯片皆为STM32F103C8T6,用到的485通信芯片为XL3485。

1.2、软件设计思路

软件设计思路:相当于单片机B的功能是否正常要通过屏幕显示出来,而单片机A是中间的桥梁,由于485是半双工,单片机B只有收到询问指令的数据才会发送响应的数据(单片机B程序不可更改,被动);屏幕是不断的询问单片机A,单片机A收到询问后再发送响应的数据给屏幕,屏幕作出指令(主动)。由单片机A发送一个数据后等待回应,收到单片机B的数据后解析相应的功能,处理好后再发送给屏幕,中间有个时间差。

2、单片机引脚定义及连接

下面是单片机A和单片机B之间的通信:通过查找手册串口收发引脚。

黄色高亮的是串口通信收发引脚。 

3、XL3485芯片 3.1引脚分布

 3.2引脚定义

3.3接线方式

A、B总线接口,用于连接485总线。RO是接收输出端DI是发送数据收入端,RE是接收使能信号 (低电平有效) DE是发送使能信号(高电平有效)。所以直接将RE和DE连接一块,接PA6引脚,当输出高电平时发送数据,输出低电平时接受数据。

仅供参考,具体详见XL3485规格书。

4、遇到的问题及解决方法

 遇到的问题:遇到了第一个问题,接受不到单片机B发送的数据,不知道单片机A是否发送数据。我参考了致远电子的RS485通信的详细说明,在XL3485的A总线加上一个上拉电阻、B总线加上一个下拉电阻,如下:

 飞线接了上拉电阻和下拉电阻后,调试发现发送数组和接受数组有相应的值,问题解决。

我查找相关数据手册和资料发现,在485通信中,连接一个120Ω的电阻是为了实现信号的匹配和防止信号反射。这个电阻被称为终端电阻或者终端电阻器,120R电阻加在信号线末端,原因是:高频信号传输时,信号波长相对传输线较短,信号在传输线终端会形成反射波,干扰原信号,所以需要在传输线末端加终端电阻,使信号到达传输线末端后不反射,对于低频信号则不用,如下图:

 5、串口通信和485通信 5.1串口通信

关于串口通信和RS485通信:串口通信很简单,有三个端口即可收发数据,发送端TX,接收端RX,以及公共地GND。发送和接受的数据实际上是一串高低电平的信号,所以要公共地GND来区别是高电平还是低电平。

5.2RS485通信

RS485通信是串口通信的一种,通常是由单片机的串口连接485通信芯片,再由485芯片和485芯片之间通信。另外RS485采用差分信号的方式,由A端和B端接受到信号后进行差值运算来识别是高电平还是低电平,这样不仅可以减少外界对信号传输的干扰,而且只需要俩根线就可以完成传输。在多设备通信,远距离通信上应用广泛。

6、代码部分 6.1串口初始化

RS485通信也是利用串口通信,第一步要对串口进行初始化,以串口2为例。

void Uart2_Init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能 GPIOA 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能 USART2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE); USART_DeInit(USART2); //复位串口1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART2_TX PA.2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //USART2_RX PA.3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = bound; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式 USART_Init(USART2, &USART_InitStructure); //初始化串口 USART_Cmd(USART2, ENABLE); //使能串口2 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启接收中断 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //485芯片使能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.1 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级 0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级 0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能 NVIC_Init(&NVIC_InitStructure); //中断优先级初始化 }

配置好响应的引脚以及参数。

6.2数据发送 u8 USART_Send_Data(u8 *buf,u16 len,USART_TypeDef* USARTx) { u16 t; for(t=0;t>8; Usart2_Printf(USART_TX_BUF_Two,8); //发送数据

本设计RS485通信用的是MODBUS通信协议,需要CRC检验来判断发送的数据是否正确,可采用其他不同的通信协议,也可以自己定义一种通信的协议。这样通过对函数的调用即可实现发送数据。

6.3数据的接收

数据在接收时同样定义一个数组USART_RX_BUF_Two,通过中断来接收数据(和串口通信一样):

void USART2_IRQHandler(void) { u8 Data; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接受中断 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); Data = USART_ReceiveData(USART2); //(USART2->DR); //读取接收到的数据 USART_RX_BUF_Two[RxTwoNum++] = Data; Cnt_Two = 0; //计时清零 } }

再定义一个定时器,每隔一段时间读取寄存器的值。

void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIM3更新中断标志 if(RxTwoNum) //串口2定时接收,RxTwoNum不等于0时即为接收到了数据 { if(++ Cnt_Two >= 4) //接收210/4ms { Cnt_Two = 0; RxTwoNum = 0; //接收计数清零 PreRevTwoLong = RxTwoNum; ReveceFinishTwo = 1; //串口1接收成功标志位 } } } }

RS485是半双工的通信,可以根据定时结束后视为接受一次数据对标志位进行操作,接收到数据后才进行发送或者发送后才接受数据,将收发数据分开,以免数据紊乱。收到数据的时间根据需求设置中断函数。

这样每隔一段时间就可以自动接受到一次数据了。

RS485通信的收发数据和串口收发数据大同小异,要注意到RS485通信方式是半双工收发要间隔开。另外RS485在收发数据时要注意芯片的RE是接收使能信号 (低电平有效), DE是发送使能信号(高电平有效),通常可接在一起使用。

注:-2到-6电平代表逻辑0;2到6电平代表逻辑1.



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有