一、485总线和硬件电路
典型的串行通讯标准是RS232和RS485,它们定义了电压,阻抗等,但不对软件协议给予定义。RS-485总线标准规定了总线接口的电气特性标准即对于2个逻辑状态的定义:正电平在+2V~+6V之间,表示一个逻辑状态;负电平在-2V~-6V之间,则表示另一个逻辑状态;数字信号采用差分传输方式,能够有效减少噪声信号的干扰。
RS485总线,传输距离长、抗干扰性能强、稳定性好。已经广泛的应用于工业设备的使用中。
通常使用AB双绞线连接,复杂场合可以使用带屏蔽层的双绞线。
MCU本身不具有485总线的通讯标准。但是可以采用中继转换芯片SP3485,将串口信号和485的信号做相应的电平转换。
实际中的具体电路(共占用MCU的3个IO口),其中有两根是串口通讯的RX和TX引脚。
还有一根是RE,高电平时,向外发送数据;低电平时,接收数据。
RS485通信
- 在软件程序层面,其实利用的就是单片机的串口功能,发送和接收数据。
- 在硬件层面,就是多加了1个电平转换芯片。将串口的ttl电平转换为了485使用的电平。
二、cubeMX配置
三、RS485驱动程序
最重要的逻辑:
当MCU往外发数据时候,RE=1,
当MCU发送完数据时候,RE=0,
任意空闲状态,RE=0
#include "rs485.h"
#include "../usart/usart.h"
#include "main.h"
void RS485_printf (char *fmt, ...)
{
char buff[USART2_REC_LEN+1];
uint16_t i=0;
va_list arg_ptr;
HAL_GPIO_WritePin(RS485_RE_GPIO_Port,RS485_RE_Pin, GPIO_PIN_SET);
va_start(arg_ptr,fmt);
vsnprintf(buff, USART2_REC_LEN+1,fmt,arg_ptr);
i=strlen(buff);
if(strlen(buff)>USART2_REC_LEN)i=USART2_REC_LEN;
HAL_UART_Transmit(&huart2,(uint8_t *)buff,i,0xffff);
va_end(arg_ptr);
HAL_GPIO_WritePin(RS485_RE_GPIO_Port,RS485_RE_Pin, GPIO_PIN_RESET);
}
#ifndef RS485_RS485_H_
#define RS485_RS485_H_
#include "stm32f1xx_hal.h"
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "stdio.h"
extern UART_HandleTypeDef huart2;
void RS485_printf (char *fmt, ...);
#endif
以上只有发送程序,至于接收程序,在USART.C
中的串口中断回调函数里面(和USART1\USART3一起)。
#include "usart.h"
uint8_t USART2_RX_BUF[USART2_REC_LEN];
uint16_t USART2_RX_STA=0;
uint8_t USART2_NewData;
uint8_t RS485orBT;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart ==&huart2)
{
USART2_RX_BUF[0]=USART2_NewData;
USART2_RX_STA++;
HAL_UART_Receive_IT(&huart2,(uint8_t *)&USART2_NewData, 1);
}
}
这边的接收只接受了一个字节的数据,没有什么意义。
四、应用程序
做这个实验需要两个及两个以上的485设备一起通信。暂时没法完成。
工业中RS485设备常使用的是Modbus通信协议。以后有时间可以写一下,这个通信协议。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)