STM32使用485接口通讯

STM32使用485接口通讯

简单来说,485通信,实质还是串口通信。通过电平转换芯片,将TTL电平转换成485电平,即可使用485接口通信。

串口

串口是一种接口标准,只是物理层的一个标准。没有规定接口插件电缆以及使用的协议。
典型的串行通讯标准是RS232, RS485, RS422等,他们定义了电压,阻抗等,但不对软件协议给予定义。
串口通过电平转换电路,可以将串口电平(TTL)转换成485电平、232电平等。

RS485特点

  • 接口电平低
    • 逻辑“1”两线电压差为+(2~6)V;逻辑“0”两线电压差为-(2~6)V。
  • 传输速度高
    • 10米时,传输速度可达35Mbps
    • 1200米时,传输速度可达100Kbps
  • 抗干扰能力强
    • 使用平衡驱动器和差分接收器组合,抗共模干扰能力强,
  • 传输距离远,支持多节点
    • RS485总线最长可以传输1200m以上(速率<=100Kbps)
    • 一般支持32个节点,特定芯片支持128个,256,甚至400个节点
    • 此处采用的芯片是ADM2483,可以支持256个节点
  • RS485接口连接形式
    • 点对点 A-A B-B
    • 线性
    • 总线型
    • 不可是星型,环形
  • 常见接口
    • R O RO 接收输入端
    • D I DI 发送输出端
    • R E \overline {RE} 接收使能信号,低电平有效
    • D E DE 发送使能信号,高电平有效
    • 由于半双工,常将 R E \overline {RE} D E DE 连在一起,由MCU某个引脚控制。但本人使用的电路板具有收发自动切换电路(TX连到三极管上拉下拉,具体实现可以参考 https://blog.csdn.net/wangguchao/article/details/80200402 其中的5.3自动切换电路)

RS485通信注意

  • 对于MCU来说,485仅仅是使用电平转换芯片将TTL电平,转成485电平。即要使用485传输,本质上还是串口传输。
  • 两个485通信,其技术指标应该是相同的,否则不能通信。
    • 波特率
    • 数据长度
    • 停止位
    • 校验位
    • 硬件流控制
    • 收发模式

相关代码

  • 端口初始化与中断设置
/*
函数名称:	RS485_Bus_Init(void)
输入:		无
输出:		无
功能:		设置485所在串口的端口与中断
注意:		此处使用的是串口5,U5TX->PC12,U5RX->PD2
			使用了宏定义,请注意将宏定义内容添加到.h文件中
*/
void RS485_Bus_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
	
	//PC12->U5TX
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	//PD2->U5RX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5,ENABLE);//复位串口5
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5,DISABLE);//停止复位

	USART_InitStructure.USART_BaudRate = RS485_BUS_BOUND;//波特率设置
	USART_InitStructure.USART_WordLength = RS485_BUS_WORDLENGTH;//8位数据长度
	USART_InitStructure.USART_StopBits = RS485_BUS_STOPBITS;//一个停止位
	USART_InitStructure.USART_Parity = RS485_BUS_PARITY;///奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = RS485_BUS_FLOWCTRL;//无硬件数据流控制
	USART_InitStructure.USART_Mode = RS485_BUS_MODE;//收发模式

    USART_Init(UART5, &USART_InitStructure); //初始化串口
	
	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; //使能串口2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
	NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	
	USART_ITConfig(UART5,USART_IT_RXNE,ENABLE);
}
  • 中断服务函数
/*
函数名称:	UART5_IRQHandler(void)
输入:		无
输出:		无
功能:		串口接收非空中断,串口接收数据,存在串口缓存buf中
注意:		无
*/
void UART5_IRQHandler(void)
{
	u8 res;
	
	if(USART_GetITStatus(UART5,USART_IT_RXNE) != RESET)
	{
		res = USART_ReceiveData(UART5);
		if(RS485_BUS_RXCNT<64)
		{
			RS485_BUS_RXBUF[RS485_BUS_RXCNT]=res;
			RS485_BUS_RXCNT++;
		}
	}
}
  • 发送数据
/*
函数名称:	RS485_BUS_SendData(u8 *buf, u8 len)
输入:		u8 *buf 发送数据的数组
			u8 *len 发送数据的长度
输出:		无
功能:		将本地数据通过串口发送出去
注意:		无
*/
void RS485_BUS_SendData(u8 *buf, u8 len)
{
	u8 t;
	for(t=0;t<len;t++)
	{
		while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET);
		USART_SendData(UART5,buf[t]);
	}
	
	while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET);
	RS485_BUS_RXCNT = 0;
}
  • 接收数据
/*
函数名称:	RS485_BUS_ReceiveData(u8 *buf,u8 *len)
输入:		u8 *buf 存放接收数据的数组
			u8 *len 存放接收数据的长度
输出:		上述指针传递
功能:		从串口缓存中接收数据到本地缓存
注意:		串口缓存最大只能64个字节
*/
void RS485_BUS_ReceiveData(u8 *buf,u8 *len)
{
	u8 rxlen=RS485_BUS_RXCNT;
	u8 i=0;
	*len=0;
	delay_ms(10);
	if((rxlen==RS485_BUS_RXCNT)&&rxlen)				//接收到了数据且接收完成
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_BUS_RXBUF[i];
		}
		*len=RS485_BUS_RXCNT;
		RS485_BUS_RXCNT=0;
	}
}
  • rs485.h
#define RS485_BUS_BOUND				9600
#define RS485_BUS_WORDLENGTH		USART_WordLength_8b
									//USART_WordLength_8b
									//USART_WordLength_9b
#define RS485_BUS_STOPBITS			USART_StopBits_1
									//USART_StopBits_1
									//USART_StopBits_0_5
									//USART_StopBits_2
									//USART_StopBits_1_5
#define RS485_BUS_PARITY			USART_Parity_No
									//USART_Parity_No
									//USART_Parity_Even
									//USART_Parity_Odd
#define RS485_BUS_FLOWCTRL			USART_HardwareFlowControl_None
									//USART_HardwareFlowControl_None
									//USART_HardwareFlowControl_RTS
									//USART_HardwareFlowControl_CTS
									//USART_HardwareFlowControl_RTS_CTS
#define RS485_BUS_MODE				USART_Mode_Rx|USART_Mode_Tx
									//USART_Mode_Rx
									//USART_Mode_Tx

总结

485通信和串口通信,对MCU来说是没有差异的。了解串口通信,通过电平转换芯片即可以完成485通信。
第一篇文章,多有错漏还请各位斧正。

猜你喜欢

转载自blog.csdn.net/weixin_46587253/article/details/108425561