zoukankan      html  css  js  c++  java
  • 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);//等待发送结束
    	}
    }
    
  • 相关阅读:
    OC
    提取AppDelegate.m中的"RDVTabBarController"第三方框架的方法
    spring_aop
    spring_xml配置&依赖注入
    关于idea运行web项目时出现的浏览器问题
    Java中main方法参数类型个人粗略理解
    函数式编程_lambda
    反射_注解
    pl/sql使用小技巧
    触发器&索引&视图
  • 原文地址:https://www.cnblogs.com/WingPig/p/5980805.html
Copyright © 2011-2022 走看看