STM32 RS232通信

STM32 RS232通信



1、RS232特性概述

RS-232是是串行通信接口,由电子工业协会(Electronic Industries Association, EIA)所制定的异步传输标准接口。在1962年发布,命名为EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。RS是英文“推荐标准”的缩写,232为标识号。RS232是全双工通信,通信距离最远15米内,
以前的计算机比较多使用RS-232接口标准是25个脚的DB-25连接器,现在比较流行使用9个脚的DB-9连接器了。但是慢慢的发现又更加流行使用USB来代替 了,更加省空间。工业控制中RS-232接口一般只使用TXD, RXD和GND三条线就可以实现数据传输。

1.1 DB9 引脚定义

在这里插入图片描述

DB9引脚定义及功能对照表:
在这里插入图片描述

实物图:

在这里插入图片描述
在这里插入图片描述

1.2 电气特性

RS-232电平与COMS/TTL电平对比:
在这里插入图片描述
需要注意他们之间的信号无法直接进行通信,232使用的是负逻辑,逻辑电压也不同。

2、通信原理图

在这里插入图片描述

3、通信协议

在这里插入图片描述

数据帧格式:
起始位:占1位,规定为逻辑0电平。
有效数据位:可选5、6、7、8、9个位,LSB在前(最低有效位),MSB在后(最高有效位),即位0到位7,传输有效信息。
校验位:可选占1位,也可以没有该位。
停止位:必须有,可选0.5、1、1.5、2个位,规定为逻辑1电平。

4、核心代码

主要代码如下:
注意:这个例程是直接在串口例程上面改的,直接把串口1改为串口2,并且把系统部分的删除了,所以功能是和串口1的实验效果是一样的。

uart.c
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{
    
     
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{
    
     
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{
    
          
	while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
    USART2->DR = (u8) ch;      
	return ch;
}
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记

void uart2_Init(u32 baudrate)
{
    
    
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能USART2,GPIOA时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//PA.2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3

    //USART 初始化设置
    USART_InitStructure.USART_BaudRate = baudrate;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式

    USART_Init(USART2, &USART_InitStructure); //初始化串口2
    USART_Cmd(USART2, ENABLE);                    //使能串口2
}

void USART2_IRQHandler(void)                	//串口2中断服务程序
{
    
    
	u8 Res;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
    
    
		Res =USART_ReceiveData(USART2);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
    
    
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
    
    
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{
    
    	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
    
    
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
}
uart.h

#define USART_REC_LEN  			200  	//定义最大接收字节数 200
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
main.c

 int main(void)
 {
    
    		
 	u16 t;  
	u16 len;	
	u16 times=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
 	while(1)
	{
    
    
		if(USART_RX_STA&0x8000)
		{
    
    					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
			{
    
    
				USART_SendData(USART2, USART_RX_BUF[t]);//向串口2发送数据
				while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
    
    
			times++;
			if(times%5000==0)
			{
    
    
				printf("\r\n战舰STM32开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\n");  
			if(times%30==0)LED1=!LED1;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}	 
 }

这里是把RS232接到了串口2上,所以初始化串口2就可以,如果需要使用中断,则需要编写中断处理函数和串口重定向功能就可以用来打印信息了。


5、总结

使用RS232实际上就是使用usart,原理是一样的,需要添加一下电平转换芯片就可以用两种进行通信了。

猜你喜欢

转载自blog.csdn.net/weixin_53944340/article/details/128721409