stm32 usart 异步传输示例

STM32F103xE的USART异步数据传输示例

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

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

stm32 usart 异步传输示例_第1张图片

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

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

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

使能外设时钟

查阅手册

stm32 usart 异步传输示例_第2张图片

通过该图我们看到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为异步串行通信接口。

stm32 usart 异步传输示例_第3张图片

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

stm32 usart 异步传输示例_第4张图片

该表格清楚明了的说明了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引脚呀,因此继续在官方手册中查找

stm32 usart 异步传输示例_第5张图片

废话少说,直接上代码

配置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);//等待发送结束
    }
}

转载于:https://www.cnblogs.com/WingPig/p/5980805.html

你可能感兴趣的:(stm32 usart 异步传输示例)