stm32 usart 异步传输示例

STM32F103xE的USART异步数据传输示例

USART全称Universal Synchronous/Asynchronous Receiver/Transmitter,是一种可以进行同步/异步通信的串行设备接口。

通过查阅STM32官方手册得之,STM32f10x系列一共有五个USART传输串口。其中USART1、USART2、USART3为同步/异步串行通信接口,USART4、USART5为异步串行通信接口。

USART

STM32外设的初始化步骤基本上是:

  1. 使能外设时钟
  2. 配置外设所需要的I/O端口
  3. 配置外设
  4. 使能外设

根据这个步骤首先我们使能外设时钟

使能外设时钟

查阅手册

Clock-Tree

通过该图我们看到USART1位于总线APB2上面,而USART2、3和UART4、5位于总线APB1上面。

因此我们开启USART1的时钟

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//开启USART1时钟

配置外设所需I/O端口

通过查阅STM32官方手册得之,STM32f10x系列一共有五个USART传输串口。其中USART1、USART2、USART3为同步/异步串行通信接口,USART4、USART5为异步串行通信接口。

USART

在这里我们将使用USART1同步/异步串行通信接口为例,进行介绍。既然想通过USART1通信接口发送数据,那肯定GPIO引脚呀,因此继续在官方手册中查找

USART1-Port

该表格清楚明了的说明了USART1的各个引脚。其中TX(Transmit data发送数据输出)、RX(Receive data接受数据输入)、CK(Clock发送时钟输出)、CTS(Clear to Send允许发送)、RTS(Request to Send请求发送)分别对应于PA09、PA10、PA08、PA11、PA12。

因此我们配置I/O端口:

GPIO_InitTypeDef  GPIO_InitStrue;
//时钟使能	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//GPIO10使能TX	
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10脚
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_Init(GPIOB,&GPIO_InitStrue);	//根据设定参数初始化GPIOB_10
//GPIO10使能RX 
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11脚
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根据设定参数初始化GPIOB_11

配置外设

在这里外设当然是USART1啦。我们只需要根据自己的需要配置就行啦。主要的配置项有波特率有无硬件控制流发送/接受有无奇偶校验停止位数据位

其中波特率指的是数据传输到速度指每秒钟发送多少bit的数据;硬件控制流指是否通过CTS和RTS控制数据传输;有无奇偶校验则比较简单就是是否对传输的数据进行奇偶校验;因为USART接口传输需要对数据进行封装,即在原有的数据中加上开始位,在原始数据的尾部加上停止位,因此停止位值得就是停止位的长度;数据位指的是每次传输中有效数据的长度。

一个配置的示例:

USART_InitStrue.USART_BaudRate=9600;//波特率9600
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控制
USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能发送、接收
USART_InitStrue.USART_Parity=USART_Parity_No;//无基偶校验
USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
USART_InitStrue.USART_WordLength=USART_WordLength_8b;//数据8位
USART_Init(USART1,&USART_InitStrue);//根据设定初始化USART1

使能外设

直接使能USART即可

USART_Cmd(USART1,ENABLE);

接下来配置USART1的中断

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开中断USART1
NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子优先级
NVIC_Init(&NVIC_InitStrue);

以及中断服务函数

在该函数中我们首先判断中断类型,是否为接受中断;如果是接受中断则接受字符并通过USART1发送出去,最后我们使用了一个while函数来确保数据成功发送。

//中断服务函数
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3发送数据
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
	}
}

废话少说,直接上最终代码

配置IO引脚、USART、中断向量优先级等参数:

//串口初始化
void USART1_init()
{
	GPIO_InitTypeDef  GPIO_InitStrue;
	USART_InitTypeDef USART_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	//时钟使能	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	//GPIO10使能TX	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10脚
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	//根据设定参数初始化GPIOB_10
	//GPIO10使能RX 
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11脚
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根据设定参数初始化GPIOB_11
	//USART初始化
	USART_InitStrue.USART_BaudRate=9600;//波特率9600
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控制
	USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能发送、接收
	USART_InitStrue.USART_Parity=USART_Parity_No;//无基偶校验
	USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
	USART_InitStrue.USART_WordLength=USART_WordLength_8b;//数据8位
	USART_Init(USART1,&USART_InitStrue);//根据设定初始化USART1
	//USART1使能
	USART_Cmd(USART1,ENABLE);
	//开中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开中断USART1
	NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子优先级
	NVIC_Init(&NVIC_InitStrue);
}

中断接受函数

//中断服务函数
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
	}
}

将使用USART1同步/异步串行通信接口为例,进行介绍。既然想通过USART1通信接口发送数据,那肯定GPIO引脚呀,因此继续在官方手册中查找

USART1-Port

废话少说,直接上代码

配置IO引脚、USART、中断向量优先级等参数:

//串口初始化
void USART1_init()
{
	GPIO_InitTypeDef  GPIO_InitStrue;
	USART_InitTypeDef USART_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	//时钟使能	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART1,ENABLE);
	//GPIO10使能TX	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;	//10脚
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	//根据设定参数初始化GPIOB_10
	//GPIO10使能RX 
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;//11脚
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStrue);	 //根据设定参数初始化GPIOB_11
	//USART初始化
	USART_InitStrue.USART_BaudRate=9600;//波特率9600
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控制
	USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能发送、接收
	USART_InitStrue.USART_Parity=USART_Parity_No;//无基偶校验
	USART_InitStrue.USART_StopBits=USART_StopBits_1;//停止位1位
	USART_InitStrue.USART_WordLength=USART_WordLength_8b;//数据8位
	USART_Init(USART1,&USART_InitStrue);//根据设定初始化USART1
	//USART1使能
	USART_Cmd(USART1,ENABLE);
	//开中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开中断USART1
	NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//通道
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子优先级
	NVIC_Init(&NVIC_InitStrue);
}

中断接受函数

//中断服务函数
void USART1_IRQHandler(void)
{
	u8 USART1_in;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
			USART1_in=USART_ReceiveData(USART1);
			USART_SendData(USART1, USART1_in);//向串口3发送数据
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
	}
}
posted @ 2016-10-20 20:11  WingPig99  阅读(2911)  评论(0编辑  收藏  举报