485串口测试工具软件_探索者 STM32F407 开发板资料连载第三十一章 485 实验

1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子

612ff8a80e27c8f47665695066f20bf8.png

第三十一章 485 实验

本章我们将向大家介绍如何使用 STM32F4 的串口实现 485 通信(半双工)。在本章中,我

们将使用 STM32F4 的串口 2 来实现两块开发板之间的 485 通信,并将结果显示在 TFTLCD 模

块上。本章分为如下几个部分:

31.1 485 简介

31.2 硬件设计

31.3 软件设计

31.4 下载验证

31.1 485 简介

485(一般称作 RS485/EIA-485)是隶属于 OSI 模型物理层的电气特性规定为 2 线,半双工,

多点通信的标准。它的电气特性和 RS-232 大不一样。用缆线两端的电压差值来表示传递信号。

RS485 仅仅规定了接受端和发送端的电气特性。它没有规定或推荐任何数据协议。

RS485 的特点包括:

1)

接口电平低,不易损坏芯片。RS485 的电气特性:逻辑“1”以两线间的电压差为

+(2~6)V

表示;逻辑“0”以两线间的电压差为-(2~6)V 表示。接口信号电平比 RS232 降低了,

不易损坏接口电路的芯片,且该电平与 TTL 电平兼容,可方便与 TTL 电路连接。

2)

传输速率高。10 米时,RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,

传输速度可达 100Kbps。

3)

抗干扰能力强。RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能

力增强,即抗噪声干扰性好。

4)

传输距离远,支持节点多。RS485 总线最长可以传输 1200m 以上(速率≤100Kbps)

一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,

最大的可以支持到 400 个节点。

RS485 推荐使用在点对点网络中,线型,总线型,不能是星型,环型网络。理想情况下 RS485

需要 2 个终端匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般为 120Ω)。没有特性阻抗

的话,当所有的设备都静止或者没有能量的时候就会产生噪声,而且线移需要双端的电压差。

没有终接电阻的话,会使得较快速的发送端产生多个数据信号的边缘,导致数据传输出错。485

推荐的连接方式如图 31.1.2 所示:

463fd967efcf116d2a2871588a2b0abe.png

图 31.1.2 RS485 连接

在上面的连接中,如果需要添加匹配电阻,我们一般在总线的起止端加入,也就是主机和

设备 4 上面各加一个 120Ω的匹配电阻。

由于 RS485 具有传输距离远、传输速度快、支持节点多和抗干扰能力更强等特点,所以

RS485 有很广泛的应用。

探索者 STM32F4 开发板采用 SP3485 作为收发器,该芯片支持 3.3V 供电,最大传输速度

可达 10Mbps,支持多达 32 个节点,并且有输出短路保护。该芯片的框图如图 31.1.2 所示:

f1927a622a9081614c2d2066acbb6db6.png

图 31.1.2 SP3485 框图

图中 A、B 总线接口,用于连接 485 总线。RO 是接收输出端,DI 是发送数据收入端,RE

是接收使能信号(低电平有效),DE 是发送使能信号(高电平有效)。

本章,我们通过该芯片连接 STM32F4 的串口 2,实现两个开发板之间的 485 通信。本章将

实现这样的功能:通过连接两个探索者 STM32F4 开发板的 RS485 接口,然后由 KEY0 控制发

送,当按下一个开发板的 KEY0 的时候,就发送 5 个数据给另外一个开发板,并在两个开发板

上分别显示发送的值和接收到的值。

本章,我们只需要配置好串口 2,就可以实现正常的 485 通信了,串口 2 的配置和串口 1

基本类似,只是串口的时钟来自 APB1,最大频率为 42Mhz。

31.2 硬件设计

本章要用到的硬件资源如下:

1) 指示灯 DS0

2) KEY0 按键

3) TFTLCD 模块

4) 串口 2

5) RS485 收发芯片 SP3485

前面 3 个之前都已经详细介绍过了,这里我们介绍 SP3485 和串口 2 的连接关系,如图 31.2.1

所示:

7d30cbf2c484a42167d233dfd46d196f.png

图 31.2.1 STM32F4 与 SP3485 连接电路图

从上图可以看出:STM32F4 的串口 2 通过 P9 端口设置,连接到 SP3485,通过 STM32F4

的 PG8 控制 SP3485 的收发,当 PG8=0 的时候,为接收模式;当 PG8=1 的时候,为发送模式。

这里需要注意,PA2,PA3 和 ETH_MDIO 和 PWM_DAC 有共用 IO,所以在使用的时候,注意

分时复用,不能同时使用。另外 RS485_RE 信号,也和 NRF_IRQ 共用 PG8,所以他们也不可

以同时使用,只能分时复用。

另外,图中的 R38 和 R40 是两个偏置电阻,用来保证总线空闲时,A、B 之间的电压差都

会大于 200mV(逻辑 1)。从而避免因总线空闲时,A、B 压差不定,引起逻辑错乱,可能出

现的乱码。

然后,我们要设置好开发板上P9排针的连接,通过跳线帽将PA2和PA3分别连接到485_TX

和 485_RX 上面,如图 31.2.2 所示:

2ca1b2f2030d50b9ad6cacce50fd0b00.png

图 31.2.2 硬件连接示意图

最后,我们用 2 根导线将两个开发板 RS485 端子的 A 和 A,B 和 B 连接起来。这里注意不

要接反了(A 接 B),接反了会导致通讯异常!!

31.3 软件设计

打开我们的 485 实验例程,可以发现项目中加入了一个 rs485.c 文件以及其头文件 rs485 文

件,同时 485 通信因为底层用的是串口 2,所以需要引入库函数 stm32f4xx_hal_usart.c 文件和对

应的头文件 stm32f4xx_hal_usart.h。

打开 rs485.c 文件,代码如下:

UART_HandleTypeDef USART2_RS485Handler; //USART2 句柄(用于 RS485)#if EN_USART2_RX//如果使能了接收//接收缓存区u8 RS485_RX_BUF[64]; //接收缓冲,最大 64 个字节.//接收到的数据长度u8 RS485_RX_CNT=0;void USART2_IRQHandler(void){ u8 res; if((__HAL_UART_GET_FLAG(&USART2_RS485Handler,UART_FLAG_RXNE)!=RESET)) //接收中断{ HAL_UART_Receive(&USART2_RS485Handler,&res,1,1000); if(RS485_RX_CNT<64) { RS485_RX_BUF[RS485_RX_CNT]=res;//记录接收到的值 RS485_RX_CNT++;//接收数据增加 1 }}}#endif//初始化 IO 串口 2//bound:波特率void RS485_Init(u32 bound){ //GPIO 端口设置GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOA_CLK_ENABLE();//使能 GPIOA 时钟__HAL_RCC_USART2_CLK_ENABLE();//使能 USART2 时钟GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3;//PA2,3GPIO_Initure.Mode=GPIO_MODE_AF_PP;//复用推挽输出GPIO_Initure.Pull=GPIO_PULLUP;//上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速GPIO_Initure.Alternate=GPIO_AF7_USART2;//复用为 USART2HAL_GPIO_Init(GPIOA,&GPIO_Initure);//初始化 PA2,3//PG8 推挽输出,485 模式控制 GPIO_Initure.Pin=GPIO_PIN_8;//PG8GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLUP;//上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速 HAL_GPIO_Init(GPIOG,&GPIO_Initure); //USART 初始化设置USART2_RS485Handler.Instance=USART2; //USART2USART2_RS485Handler.Init.BaudRate=bound; //波特率USART2_RS485Handler.Init.WordLength=UART_WORDLENGTH_8B;//字长为 8 位数据格式USART2_RS485Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位USART2_RS485Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位USART2_RS485Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;//无硬件流控USART2_RS485Handler.Init.Mode=UART_MODE_TX_RX; //收发模式HAL_UART_Init(&USART2_RS485Handler); //HAL_UART_Init()会使能 USART2 __HAL_UART_DISABLE_IT(&USART2_RS485Handler,UART_IT_TC);#if EN_USART2_RX__HAL_UART_ENABLE_IT(&USART2_RS485Handler,UART_IT_RXNE);//开启接收中断HAL_NVIC_EnableIRQ(USART2_IRQn); //使能 USART1 中断HAL_NVIC_SetPriority(USART2_IRQn,3,3); //抢占优先级 3,子优先级 3#endifRS485_TX_EN=0; //默认为接收模式}//RS485 发送 len 个字节.//buf:发送区首地址//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过 64 个字节)void RS485_Send_Data(u8 *buf,u8 len){RS485_TX_EN=1;//设置为发送模式HAL_UART_Transmit(&USART2_RS485Handler,buf,len,1000);//串口 2 发送数据RS485_RX_CNT=0;RS485_TX_EN=0;//设置为接收模式}//RS485 查询接收到的数据//buf:接收缓存首地址//len:读到的数据长度void RS485_Receive_Data(u8 *buf,u8 *len){u8 rxlen=RS485_RX_CNT;u8 i=0;*len=0;//默认为 0delay_ms(10);//等待 10ms,连续超过 10ms 没有接收到一个数据,则认为接收结束if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了{for(i=0;i

此部分代码总共 4 个函数,其中 RS485_Init 函数为 485 通信初始化函数,其实基本上就是

在配置串口 2,只是把 PG8 也顺带配置了,用于控制 SP3485 的收发。同时如果使能中断接收

的话,会执行串口 2 的中断接收配置。USART2_IRQHandler 函数用于中断接收来自 485 总线的

数据,将其存放在 RS485_RX_BUF 里面。最后 RS485_Send_Data 和 RS485_Receive_Data 这两

个函数用来发送数据到 485 总线和读取从 485 总线收到的数据,都比较简单。

头文件 rs485.h 文件中,我们通过下面一行代码打开了接受中断:

#define EN_USART2_RX 1//0,不接收;1,接收.

其他内容就是一些函数什么,所以这里我们不细说。

接下来,我们来看看主函数代码:

int main(void){ u8 key;u8 i=0,t=0;u8 cnt=0;u8 rs485buf[5]; HAL_Init();//初始化 HAL 库 Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhzdelay_init(168);//初始化延时函数uart_init(115200);//初始化 USARTusmart_dev.init(84);//初始化 USMARTLED_Init();//初始化 LEDKEY_Init();//初始化 KEYLCD_Init();//初始化 LCDRS485_Init(9600);//初始化 RS485 POINT_COLOR=RED;LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");LCD_ShowString(30,70,200,16,16,"RS485 TEST");LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2017/4/14");LCD_ShowString(30,130,200,16,16,"KEY0:Send"); //显示提示信息POINT_COLOR=BLUE;//设置字体为蓝色LCD_ShowString(30,150,200,16,16,"Count:");//显示当前计数值LCD_ShowString(30,170,200,16,16,"Send Data:");//提示发送的数据LCD_ShowString(30,210,200,16,16,"Receive Data:");//提示接收到的数据while(1) { key=KEY_Scan(0);if(key==KEY0_PRES)//KEY0 按下,发送一次数据 { for(i=0;i<5;i++){ rs485buf[i]=cnt+i;//填充发送缓冲区LCD_ShowxNum(30+i*32,190,rs485buf[i],3,16,0X80);//显示数据 } RS485_Send_Data(rs485buf,5);//发送 5 个字节}RS485_Receive_Data(rs485buf,&key);if(key)//接收到有数据{if(key>5)key=5;//最大是 5 个数据.for(i=0;i

此部分代码,我们通过函数 RS485_Init(9600),初始化串口 2 的波特率为 9600。cnt 是一个

累加数,一旦 KEY0 按下,就以这个数位基准连续发送 5 个数据。当 485 总线收到数据的时候,

就将收到的数据直接显示在 LCD 屏幕上。

31.4 下载验证

在代码编译成功之后,我们通过下载代码到 ALIENTEK 探索者 STM32F4 开发板上(注意

要 2 个开发板都下载这个代码哦),得到如图 31.4.1 所示:

8fbd570358642cc530c430be56ea5c75.png

图 31.4.1 程序运行效果图

伴随 DS0 的不停闪烁,提示程序在运行。此时,我们按下 KEY0 就可以在另外一个开发板

上面收到这个开发板发送的数据了。如图 31.4.2 和图 31.4.3 所示:

06f4fe82cd0d110b7e6d4dba3fdf88c9.png

图 31.4.2 RS485 发送数据

891f14526670f5749201b58f235f0591.png

图 31.4.3 RS485 接收数据

图 31.4.2 来自开发板 A,发送了 5 个数据,图 31.4.3 来自开发板 B,接收到了来自开发板

A 的 5 个数据。

本章介绍的 485 总线时通过串口控制收发的,我们只需要将 P9 的跳线帽稍作改变,该实

验就变成了一个 RS232 串口通信实验了,通过对接两个开发板的 RS232 接口,即可得到同样的

实验现象,有兴趣的读者可以实验一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值