您的位置:首页 > 教育 > 培训 > 嵌入式基础知识-RS232通信协议电路与代码最全分析

嵌入式基础知识-RS232通信协议电路与代码最全分析

2024/10/6 6:51:37 来源:https://blog.csdn.net/qq_53863426/article/details/141871841  浏览:    关键词:嵌入式基础知识-RS232通信协议电路与代码最全分析

1.RS232基本概念

        RS232是异步通信,全双工传输(异步通信就是无时钟CLK信号,全双工就是能同时收发数据)。采用负逻辑传送,规定逻辑“1”的电平为-5V~-15 V,逻辑“0”的电平为+5 V~+15 V。选用该电气标准的目的在于提高抗干扰能力,增大通信距离,但是在工业中传输距离只有15m,相对RS485来说较短,所以在工业中用RS232不常见。RS232常见的接口是DB9,一般都有专门的线进行连接。

2.RS232电路设计

        在工业上控制器常采用从MCU-光电耦合-电平转换-DB9接口的设计,如图所示,一般会在MCU和转换电平中加入光电耦合芯片,光耦的主要作用是实现信号的隔离,通过光耦隔离来实现信号的隔离传输,使电平转换芯片与MCU系统不共地,完全隔离则有效的抑制了高共模电压的产生,大大降低232的损坏率,提高了系统稳定性。电平转换主要是由于TTL信号不能直接被RS232标准传输协议直接识别从而需要改变他的电平标准。光电耦合芯片一般采用6N137、TLP2361等,电平转换一般采用MAX3232、SP3232芯片。

        TTL电平标准,输出 L: <0.8V ; H:>2.4V。输入 L: <1.2V ; H:>2.0V。TTL器件输出低电平要小于0.8V,高电平要大于2.4V。输入,低于1.2V就认为是0,高于2.0就认为是1。于是TTL电平的输入低电平的噪声容限就只有(0.8-0)/2=0.4V,高电平的噪声容限为(5-2.4)/2=1.3V。

        RS232电平标准,逻辑1的电平为-3~-15V,逻辑0的电平为+3~+15V,注意电平的定义反相了一次。电路的具体方案可以大家去网上找原理图。

                                                          MAX3232电平芯片转换 

                                                            电路结构

3.HAL库程序编写

        RS232代码与配USART一样只需要配2个脚就行了,验证的话使用打印函数,在上位机上进行打印。分别是usart.h、usart.c、main.c

#ifndef __Usart_H
#define __Usart_H#include "sys.h"
#include "stdio.h"
#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收  
#define RXBUFFERSIZE   1 //缓存大小
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	
extern UART_HandleTypeDef UART1_RS232Handler; //UART句柄
extern u8 aRxBuffer[RXBUFFERSIZE];//HAL库USART接收Buffer
void RS232_init(u32 bound);
#endif

                                                             usart.h

        注意看一下你配置的2个引脚是不是对的,这个需要根据你的引脚更改

#include "Usart.h"/*-------------|----------------UART1	  PA9  <-> RS232_TX     对应控制板DB9母头接口UART1	  PA10 <-> RS232_RX	    对应控制板DB9母头接口-------------|----------------*/
#if EN_USART1_RX   //如果使能了接收 
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
u16 USART_RX_STA=0;       //接收状态标记	
u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
UART_HandleTypeDef UART1_RS232Handler; //UART句柄
/*********************************** **********************************************************************
*	函 数 名: RS232_Init
*	功能说明: RS232功能初始化,对应控制板DB9母头接口
*	形    参: bound波特率
*	返 回 值: 无
*********************************************************************************************************/
void RS232_init(u32 bound)
{	UART1_RS232Handler.Instance=USART1;					    //USART1UART1_RS232Handler.Init.BaudRate=bound;				    //波特率UART1_RS232Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式UART1_RS232Handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位UART1_RS232Handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位UART1_RS232Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控UART1_RS232Handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式HAL_UART_Init(&UART1_RS232Handler);					    //HAL_UART_Init()会使能UART1HAL_UART_Receive_IT(&UART1_RS232Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量}
/*********************************** **********************************************************************
*	函 数 名: HAL_UART_MspInit
*	功能说明: RS232引脚初始化,被HAL_UART_Init()直接调用;
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{//GPIO端口设置GPIO_InitTypeDef GPIO_Initure;if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化{__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟GPIO_Initure.Pin=GPIO_PIN_9;			//PA9GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出GPIO_Initure.Pull=GPIO_PULLUP;			//上拉GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9GPIO_Initure.Pin=GPIO_PIN_10;			//PA10HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10//#if EN_USART1_RX
//		HAL_NVIC_EnableIRQ(USART1_IRQn);				//使能USART1中断通道
//		HAL_NVIC_SetPriority(USART1_IRQn,3,3);			//抢占优先级3,子优先级3
#endif	}}
/*********************************************************************************************************
*	函 数 名: HAL_UART_RxCpltCallback
*	功能说明: 串口1回调函数,被HAL_UART_Receive_IT自动调用
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance==USART1)//如果是串口1{if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始else USART_RX_STA|=0x8000;	//接收完成了 }else //还没收到0X0D{	if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  }		 }}}
}
/*********************************************************************************************************
*	函 数 名: USART1_IRQHandler
*	功能说明: RS232接收中断,对应控制板DB9母头接口
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************/
void USART1_IRQHandler(void)                	
{ u32 timeout=0;	HAL_UART_IRQHandler(&UART1_RS232Handler);	//调用HAL库中断处理公用函数timeout=0;while (HAL_UART_GetState(&UART1_RS232Handler) != HAL_UART_STATE_READY)//等待就绪{timeout++;超时处理if(timeout>HAL_MAX_DELAY) break;		} timeout=0;while(HAL_UART_Receive_IT(&UART1_RS232Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1{timeout++; //超时处理if(timeout>HAL_MAX_DELAY) break;	} 											 
} /*********************************************************************************************************
*	函 数 名: fputc()
*	功能说明: 串口打印函数
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************/
int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&UART1_RS232Handler, (uint8_t *)&ch, 1, 0xffff);//HAL_UART_Transmit(&USART2_RS485Handler,(uint8_t *)&ch,1,1); //RS485串口return ch;
}

                                                                        usart.c

#include "usart.h"
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */RS232_init(115200);          //初始化USART/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){printf("HELLO STM32 !\n");}/* USER CODE END 3 */
}

                                                                main.c

        代码部分大家可以参考普通的usart串口通信配就行了,这个与那个配是一样的,然后打开上位机选择串口波特率看看有没有信息打印。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com