串口RS485通信

2023-12-14 22:56:14

一、RS485的介绍? ? ? ??

????????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收发器

?SP3485 作为收发器,该芯片支持 3.3V 供电,最大传输速度可达10Mbps,支持多达 32 个节点,并且有输出短路保护。图中 A、B 总线接口,用于连接 485 总线。RO 是接收输出端,DI 是发送数据收入端,RE是接收使能信号(低电平有效),DE 是发送使能信号(高电平有效)。可以将RE和DE用同一个线连接,然后控制该脚的电平信号来确定是发送还是接收模式

三、实现代码

1)rs485.h?

#ifndef __RS485_H
#define __RS485_H

#include "head.h"

#define RX_MAX_LEN 64
#define RS485_TX_MODE    gpio_bit_set(GPIOA, GPIO_PIN_8) //U-NCA3485是半双工RS485收发器,将RS485设置为发送模式
#define RS485_RX_MODE    gpio_bit_reset(GPIOA, GPIO_PIN_8)//将RS485设置为接收模式

void RS485_Init(void);
void RS485_Send_Data(UCHAR *buf,UCHAR len);
void RS485_Receive_Data(UCHAR *buf,UCHAR *len);

extern UCHAR RS485_RX_BUF[RX_MAX_LEN];  	//接收缓冲,最大64个字节
extern UCHAR RS485_RX_CNT;   	//接收到的数据长度	  
extern USART_RX_FLAG rs485_recvFlag;

#endif

2)rs485.c

#include "rs485.h"

UCHAR RS485_RX_BUF[RX_MAX_LEN];  	//接收缓冲,最大64个字节
UCHAR RS485_RX_CNT=0;   	//接收到的数据长度	  
USART_RX_FLAG rs485_recvFlag=FLASE;

void USART0_IRQHandler(void) 
{
	UCHAR res;
	if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE))
	{
        res=usart_data_receive(USART0);
		if(RS485_RX_CNT<RX_MAX_LEN)
		{
			RS485_RX_BUF[RS485_RX_CNT]=res;		//记录接收到的值
			RS485_RX_CNT++;						//接收数据增加1 
		}
		usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE); //清中断标志
    }
	else if (RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)) 
	{
	    usart_interrupt_flag_clear(USART2, USART_INT_FLAG_IDLE);
		usart_data_receive(USART2); /* 清除接收完成标志位 */
		rs485_recvFlag = TRUE;     //事件通知接收完成
	}
}

void RS485_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOA); //enable GPIO clock 
	rcu_periph_clock_enable(RCU_USART0);// enable USART clock

	gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);	//RS485-RE0
	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);   //RS485-TX0(USARTx_Tx)
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);//RS485-RX0(USARTx_Rx)
	
	usart_deinit(USART0); //USART configure 
	usart_baudrate_set(USART0, 115200);                //设置波特率
	usart_word_length_set(USART0, USART_WL_8BIT);      //设置数据位
	usart_parity_config(USART0, USART_PM_NONE);        //设置奇偶校验位
	usart_stop_bit_set(USART0, USART_STB_1BIT);        //设置停止位
	usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); //禁用rts
	usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); //无硬件数据流控制
	usart_receive_config(USART0, USART_RECEIVE_ENABLE);        //使能接收器
	usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);      //使能发送器
		
	nvic_irq_enable(USART0_IRQn, 0, 0);//配置NVIC分组,初始化NVIC分组4
	usart_interrupt_enable(USART0, USART_INT_RBNE);//使能接收中断
	usart_interrupt_enable(USART0, USART_INT_IDLE);
	usart_enable(USART0);//使能串口
	
	RS485_RX_MODE;				//默认为接收模式	
}

void RS485_Send_Data(UCHAR *buf,UCHAR len)
{
	UINT i;
	RS485_TX_MODE;			//设置为发送模式
  	for(i=0;i<len;i++)		//循环发送数据
	{		   
		while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));//等待发送区为空
		usart_data_transmit(USART0,buf[i]);
	}	 
	while(RESET == usart_flag_get(USART0, USART_FLAG_TC));	 //发送完成中断 	
	RS485_RX_CNT=0;	  
	RS485_RX_MODE;				//设置为接收模式	
}

void RS485_Receive_Data(UCHAR *buf,UCHAR *len)
{
	UCHAR rxlen=RS485_RX_CNT;
	UCHAR i=0;
	*len=0;				
	delay_1ms(10);		//等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束,然后读取数据
	if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_RX_BUF[i];	
		}		
		*len=RS485_RX_CNT;	//记录本次数据长度
		RS485_RX_CNT=0;		//清零
	}
}

文章来源:https://blog.csdn.net/m0_61973119/article/details/135005139
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。