STM32的串口非常强大,它不仅支持最基本的通用串口同步、异步通讯,还具有 LIN总线功能(局域互联网)、IRDA功能(红外通讯)、SmartCard功能。usart1挂在APB2总线上,usart2和usart3挂在APB1总线上。
这里只说明串口通信如何使用,以Usart1为例,usart1用的是GPIOA_Pin_9,和GPIOA_Pin_10。Pin9为Tx,Pin10为RX。
配置uart主要有4点:
1、开启时钟:
开启GPIOA时钟和USART1的时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
2、配置GPIO_InitTypeDef结构体:
void Init_Usart1(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Pin9为Tx配置为复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//Pin10为Rx配置为浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); }
3、配置USART_InitTypeDef结构体,开启中断并使能Usart1:
void Usart1_Configuration(uint32_t BaudRate) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate =BaudRate ;//波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //位宽 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; //开启TXAndRX USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //使能中断 USART_Cmd(USART1, ENABLE); //使能usart1 }
4、配置NVIC:
void Usart1_Init_NVIC(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //MVIC配置为组2 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //主优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
这样就可以使用串口了。
如果想使用stdio.h中的printf函数需要重新实现一个fputc函数如下:
int fputc(int Data, FILE *f) { while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));//等待发送完成 USART_SendData(USART1,Data); //发送一个字节 return Data; }
中断函数:
void USART1_IRQHandler(void) { uint8_t ReceiveData; if((USART_GetITStatus(USART1,USART_IT_RXNE)))//判断是否为接收中断 { USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标志位 ReceiveData=USART_ReceiveData(USART1);//接收一个字节 printf("%c", ReceiveData); } }
固件库中你要使用的几个函数:
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);//得到状态标志位,判断是RX还是TX中断。 void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);//清除中断标志位
注意:
进入中断之后,首先判断是发送中断还是接收中断,然后清除中断标志位。之后再接收或发送数据。
这里整理了一个简单的配置函数库,usart.c, usart.h.
文件链接