1、综述
(1)STM32F407ZGT6最多可提供6路串口。
(2)对于复用功能的IO口,我们首先要使能GPIO时钟,然后使能相应的外设时钟,同时,在初始化IO口的函数里,要把GPIO模式设置为复用。
2、串口设置的一般步骤
(1)串口时钟使能,GPIO时钟使能。
<1>串口是挂在APB2总线下的外设,使能函数为:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE)
<2>GPIO时钟的使能,只要找到要用的串口对应的芯片引脚就好,比如串口1对应着芯片引脚PA9,PA10,那么,使能GPIOA的时钟就行:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE)
(2)设置引脚复用映射,调用GPIO_PinAFConfig函数。
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
(3)GPIO初始化设置,要设置模式为复用功能。
(4)串口参数初始化:设置波特率、字长、奇偶校验等参数。
(5)开启中断,并且初始化NVIC,使能中断(可选,取决于你是否需要使用中断)
通过调用函数NVIC_Init(),来配置。后续会作为补充讲解。
(6)使能串口,调用函数USART_Cmd。
USART_Cmd(USART1,ENABLE);
(7)串口数据发送与接收,或编写中断函数。
STM32F4中,串口数据的发送与接收是通过数据寄存器USART_DR来实现的。这是一个双寄存器,包含了TDR和RDR。当向该寄存器写数据的时候,串口就会自动发送;当收到数据的时候,也是存在该寄存器内。
<1>使用库函数操作USART_DR寄存器,发送数据:
USART_SendData(USART_TypeDef\* USARTx,uint16_t Data);
通过该函数向串口寄存器USART_DR写入一个数据;
<2>接收数据:
uint16_t USART_ReceiveData(USART_TypeDef\* USARTx);
通过该函数可以读取串口接收到的数据。
(8)串口状态的获取。
串口的状态可以通过状态寄存器USART_SR读取。在这个寄存器内,我们主要关注如下两个位:
<1>RXNE(读数据寄存器非空)。当该位被置1的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候,我们就要去读取USART_DR数据寄存器,通过读取USART_DR可以将该位清零。也可以直接操作寄存器,向该位写0,直接清除。
<2>TC(发送完成)。当该位被置位的时候,表示USART_DR里面的数据已经被发送完成了。它也有两种清零方式:一是读USART_SR,或者写USART_DR;二是直接向该位写0。
使用STM32F4固件库函数,读取串口状态的函数是:
FlagStatus USART_GetFlagStatus(USART_TypeDef\* USARTx,uint16_t USART_FLAG);
函数第二个参数,决定了我们要查看串口的哪个状态,是要判断USART_DR寄存器非空(RXNE),还是是否发送完成(TC)。调用形式分别为:
USART_GetFlagStatus( USART1,USART_Flag_RXNE);
USART_GetFlagStatus( USART1,USART_Flag_TC);
3、补充 - 串口配置过程中的中断设置
(1)开启中断,并且初始化NVIC,使能相应中断。
通过调用函数NVIC_Init(),配置抢占优先级、响应优先级、IRQ通道使能。
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);//根据指定的参数初始化VIC寄存器
通过调用函数USART_ITConfig函数,使能相应的中断。
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启串口1中断,接收到数据产生中断
USART_ITConfig(USART1,USART_IT_TC,ENABLE);//开启串口1中断,发送数据结束时产生中断
特别注意,如果使用了中断,那么,在系统初始化的时候,需要先设置系统的中断优先级分组,可以在main函数开头这样设置(举例):
NVIC_PriorityGroupConfig(NVIC_PriorityGroup2);//设置系统中断优先级分组2
(2)获取响应的中断状态。
当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。通常,我们是在中断服务函数里面,判断是哪种中断发生了,使用函数
ITStatus USART_GetITStatus(USART_TypeDef* USARTx,uint16_t USART_IT);
比如,如果我们在之前的(1)中使能了串口发送完成中断,那么,当中断发生了,我们便可以在中断服务函数里面调用这个函数,来判断到底是否是串口发送完成中断:
USART_GetITStatus(USART1,USART_IT_TC);
返回值是SET,说明串口发送完成中断发生。
(3)中断服务函数。
void USART1_IRQHandler(void);
当中断发生的时候,程序就会执行中断服务函数。然后我们在中断服务函数里面编写相应的逻辑代码就行。