STM32串口的理解
串口设置的一般步骤可以总结为如下几个步骤:
1) 串口时钟使能,GPIO 时钟使能
2) 串口复位
3) GPIO 端口模式设置
4) 串口参数初始化
5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
6) 使能串口
7) 编写中断处理函数
淡蓝色是以串口1举例,深蓝色是以结构体函数,可拿结构体复制到Keil5中,右键
仔细看结构体里要求的模式等
1.串口时钟使能:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
2.串口复位:
void USART_DeInit(USART_TypeDef* USARTx);//串口复位
假设,复位串口 1:
USART_DeInit(USART1); //复位串口
3.串口参数初始化:设置波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式(收,发):
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
假设,对串口1参数初始化
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); //初始化串口
4.数据发送与接收:
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.串口状态:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
RXNE:读取数据
判断读寄存器是否非空(RXNE),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
TC:发送完成
我们要判断发送是否完成(TC),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_TC);
6.串口使能:
USART_Cmd(USART1, ENABLE);
7.开启串口响应中断:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState)
收到数据产生中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断
发送数据开启中断
USART_ITConfig(USART1,USART_IT_TC,ENABLE);
8.获取相应中断状态:
USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这
个函数来判断到底是否是串口发送完成中断,方法是:
USART_GetITStatus(USART1, USART_IT_TC)
串口例子
//初始化 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); //使能串口 }