STM32串口实验(学习大纲)


此为网上收集整理
1.Systick原理和配置方法
2.延时函数delay
 
 
 
 
 
 
 
 
 
 
 
 
 
void USART_DeInit(USART_TypeDef* USARTx);
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);  
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
 
 
void USART_Init()函数: 
原型: void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);  
作用: 根据指定参数初始化相应串口(波特率,字长,停止位,奇偶校验,硬件流控制等) 主要是用来初始化寄存器BRR以及CR1,CR2,CR3控制寄存器  
使用范例:
USART_InitTypeDef USART_InitStructure;              
USART_InitStructure.USART_BaudRate = 9600;//波特率设置;        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(USART1, &USART_InitStructure); //初始化串口
 
void USART_Cmd()函数: 
原型: void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);  
作用: 使能相应的串口,用来设置寄存器CR1的串口使能位   
使用范例: USART_Cmd(USART1, ENABLE);  //使能串口 1
 
void USART_ITConfig()函数:
原型:      void USART_ITConfig(USART_TypeDef* USARTx,                                                  
                                                    uint16_t    USART_IT, FunctionalState NewState);  
作用:            开启串口相应中断,设置串口控制寄存器    
使用范例:            USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                                                                  //开启读数据寄存器非空中断
 
USART_SendData()函数:
原型:       void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);  
作用:            发送数据到串口。   
使用范例:          USART_SendData(USART1, 0x12);                    //使能串口 1
 
uint16_t USART_ReceiveData()函数:
原型: uint16_t USART_ReceiveData(USART_TypeDef* USARTx)            获取串口最新接受的值。          使用范例:            USART_ReceiveData(USART1);
 
四个状态标志相关的函数:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
详细请见STM32固件库使用手册
 
 
void USART1_IRQHandler(void)                 //串口1中断服务程序
{
 
}
 
串口设置的一般步骤可以总结为如下几个步骤:
1) 串口时钟使能, GPIO 时钟使能
2) 串口复位
3) GPIO 端口模式设置
4) 串口参数初始化
5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
6) 使能串口
7) 编写中断处理函数

1. 串口时钟使能。 
串口是挂载在 APB2 下面的外设,所以使能函数为:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 );

2. 串口复位。 
当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。
一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。
复位的是在函数 USART_DeInit()中完成:
void USART_DeInit(USART_TypeDef* USARTx);//串口复位
比如我们要复位串口 1,方法为:
USART_DeInit(USART1); //复位串口 1

3. 串口参数初始化 & GPIO 端口模式设置
串口初始化是通过 USART_Init()函数实现的,
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
这个函数的的第一个入口参数是指定初始化的串口标号,这里选择 USART1。第二个入口参数是一个 USART_InitTypeDef类型的结构体指针,这个结构体指针的成员变量用来设置串口的一些参数。
一般的实现格式为:
USART_InitStructure.USART_BaudRate = bound; //一般设置为 9600;
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(USART1, &USART_InitStructure); //初始化串口
从上面的初始化格式可以看出初始化需要设置的参数为:
波特率,字长,停止位,奇偶校验位,
硬件数据流控制,模式(收,发)。
我们可以根据需要设置这些参数。
具体参考:STM32中文参考手册_V10.pdf中的8.1.11外设GPIO配置章节

4. 数据发送与接收。 
STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到收据的时候,也是存在该寄存器内。
STM32 库函数操作 USART_DR 寄存器发送数据的函数是:
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
通过该函数向串口寄存器 USART_DR 写入一个数据。
STM32 库函数操作 USART_DR 寄存器读取串口接收到的数据的函数是:
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
通过该函数可以读取串口接受到的数据。

5. 串口状态。 
串口的状态可以通过状态寄存器 USART_SR 读取。 USART_SR 的各位描述如
图 8.1.1 所示:

这里我们关注一下两个位,第 5、 6 位 RXNE 和 TC。
 
RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。

TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。
该位也有两种清零方式: 
1 )读 USART_SR,写USART_DR。 
2)直接向该位写 0。
状态寄存器的其他位我们这里就不做过多讲解,大家需要可以查看中文参考手册。
在我们固件库函数里面, 读取串口状态的函数是:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如上面讲解的RXNE(读数据寄存器非空)以及 TC(发送完成)。
例如我们要判断读寄存器是否非空(RXNE),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
我们要判断发送是否完成(TC),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_TC);

这些标识号在 MDK 里面是通过宏定义定义的:
#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE ((uint16_t)0x0360)
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)

6. 串口使能。 
串口使能是通过函数 USART_Cmd()来实现的,这个很容易理解,使用方法是: 
USART_Cmd(USART1, ENABLE); //使能串口

7. 开启串口响应中断。 
有些时候当我们还需要开启串口中断,那么我们还需要使能串口中断,使能串口中断的函数是:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState)
这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。比如在接收到数据的时候( RXNE 读数据寄存器非空),我们要产生中断,那么我们开启中断的方法是:
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断
我们在发送数据结束的时候( TC,发送完成)要产生中断,那么方法是:
USART_ITConfig(USART1, USART_IT_TC, ENABLE);

8. 获取相应中断状态。 
当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是:
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
比如我们使能了串口发送完成中断,那么当中断发生了, 我们便 可以在中断处理函数中调用这个函数来判断到底是否是串口发送完成中断,方法是:
USART_GetITStatus(USART1, USART_IT_TC)
返回值是 SET,说明是串口发送完成中断发生。
通过以上的讲解,我们就可以达到串口最基本的配置了,关于串口更详细的介绍,请参考
《STM32 参考手册》第 516 页至 548 页,通用同步异步收发器一章。

/初始化 IO 串口 1
//bound:波特率
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//①串口时钟使能, GPIO 时钟使能,复用时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|
RCC_APB2Periph_GPIOA, ENABLE); //使能 USART1 ,GPIOA 时钟
//②串口复位
USART_DeInit(USART1); //复位串口 1
//③GPIO 端口模式设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //ISART1_TX PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RX PA.10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.10
//④串口参数初始化
USART_InitStructure.USART_BaudRate = bound; //波特率设置
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(USART1, &USART_InitStructure); //初始化串口
#if EN_USART1_RX //如果使能了接收
//⑤初始化 NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART1 _IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //中断优先级初始化
//⑤开启中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断
#endif
//⑥使能串口
USART_Cmd(USART1, ENABLE); //使能串口
}
从该代码可以看出,其初始化串口的过程,和我们前面介绍的一致。我们用标号①~⑥标
示了顺序:
① 串口时钟使能, GPIO 时钟使能
② 串口复位
③ GPIO 端口模式设置
④ 串口参数初始化
⑤ 初始化 NVIC 并且开启中断
⑥ 使能串口
这里需要重申的是,对于复用功能下的 GPIO 模式怎么判定,这个需要查看《中文参
考手册 V10》 P110 的表格“ 8.1.11 外设的 GPIO 配置”,这个我们在前面的端口复用章节有
提到,这里 还是拿出来再讲解一下吧。查看手册得知, 配置全双工的串口 1,那么 TX(PA9)
管脚需要配置为推挽复用输出, RX(PA10)管脚配置为浮空输入或者带上拉输入。模式配置
参考下面表格:

对于 NVIC 中断优先级管理,我们在前面的章节( 4.5 中断优先级管理)也有讲解,这里不
做重复讲解了。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在 usart.h 里面设置
EN_USART1_RX 为 1(默认设置就是 1 的) 。该函数才会配置中断使能,以及开启串口 1 的
NVIC 中断。这里我们把串口 1 中断放在组 2,优先级设置为组 2 里面的最低。
接下来,根据之前讲解的步骤 7,还要编写中断服务函数。串口 1 的中断服务函数
USART1_IRQHandler,在 5.3.3 已经有详细介绍了,这里我们就不再介绍了,大家可以翻过去
看看。
从该代码可以看出,其初始化串口的过程,和我们前面介绍的一致。 先计算得到
USART1->BRR 的内容。然后开始初始化串口引脚,接着把 USART1 复位,然之后设置波特率
和奇偶校验等。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在 usart.h 里面设置
EN_USART1_RX 为 1(默认设置就是 1 的) 。该函数才会配置中断使能,以及开启串口 1 的
NVIC 中断。这里我们把串口 1 中断放在组 2,优先级设置为组 2 里面的最低。


对于 NVIC 中断优先级管理,我们在前面的章节( 4.5 中断优先级管理)也有讲解,这里不做重复讲解了。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在 usart.h 里面设置EN_USART1_RX 为 1(默认设置就是 1 的) 。该函数才会配置中断使能,以及开启串口 1 的NVIC 中断。这里我们把串口 1 中断放在组 2,优先级设置为组 2 里面的最低。
接下来,根据之前讲解的步骤 7,还要编写中断服务函数。串口 1 的中断服务函数USART1_IRQHandler,在 5.3.3 已经有详细介绍了,这里我们就不再介绍了,大家可以翻过去看看。从该代码可以看出,其初始化串口的过程,和我们前面介绍的一致。 先计算得到USART1->BRR 的内容。然后开始初始化串口引脚,接着把 USART1 复位,然之后设置波特率和奇偶校验等。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在 usart.h 里面设置EN_USART1_RX 为 1(默认设置就是 1 的) 。该函数才会配置中断使能,以及开启串口 1 的NVIC 中断。这里我们把串口 1 中断放在组 2,优先级设置为组 2 里面的最低。
串口 1 的中断服务函数 USART1_IRQHandler, 在(STM32不完全手册) 5.3.1 已经有详细介绍了,这里就不再介绍了。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM