STM32初练总结(UART)
UART管脚配置
STM32中可以配置多个UART接口,管脚由用户自己定义到GPIO上,复用时需要打开AFIO重映射功能。
比如使用GPIOA中的9、10脚来实现UART的TX、RX管脚,需要初始化管脚:
void UART_PIN_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //??GPIOA??
/* GPIO_Mode */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //for TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* USART1_Pin_Tx */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIO_Mode */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //for RX
/* USART1_Pin_Rx */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
UART时钟配置
使用UART功能时首先要打开UART的时钟,这个时钟时外设时钟,从datasheet中找到对应的时钟,比如使用的UART1的时钟是由APB2总线时钟提供的,所以初始化的时候需要打开RCC_APB2Periph_USART1;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
UART控制寄存器配置
UART的控制寄存器在库里面已经打包好了,由一个structure来控制的,包含了串口波特率、传输位宽、停止位、输入输出模式等,一般用户需要修改的是波特率,其他可以使用默认配置,特别需要自定义的属性除外。
/* USART1_Config */
USART1_InitStruct.USART_BaudRate = BAUDRATE;
USART1_InitStruct.USART_WordLength = USART_WordLength_8b;
USART1_InitStruct.USART_StopBits = USART_StopBits_1;
USART1_InitStruct.USART_Parity = USART_Parity_No ;
USART1_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART1_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
配置完成后需要调用UART初始化函数对UART接口进行初始化:
USART_Init(USART1, &USART1_InitStruct);
然后再调用使能函数开启UART接口:
USART_Cmd(USART1, ENABLE);
这样,UART的配置就完成了,剩下的就是编写发送和接收程序,需要中断的话就初始化中断控制NVIC组件,并完成相关的配置,编写对应的中断相应函数。
这里简单写了一个发送函数,发送一个byte的数据试试:
void Usart_SendByte(USART_TypeDef* USARTx, unsigned char ch)
{
USART_SendData(USARTx , ch);
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
}
UART调试
再main函数中调用上述发送函数,仿真时把UART->DR寄存器添加到watch窗口,奇怪的是,寄存器查看到的DR中数据一直为零,单步调试和断点调试都能跑过,但是DR中的数据始终为0,百思不得其解,后来查看datasheet,发现DR这个寄存器很特别,它是一个读写一体的寄存器,既是发送的缓冲寄存器,也是接收的缓冲寄存器,既然是缓冲寄存器,也就是说,在发送数据时,写到DR里面的数据只是缓冲你一下,然后立马就转移到发送移位寄存器中去了,然后就空了,所以在监视器上看到的DR始终为0,为了证明这一推断,我把TE寄存器关掉了,这样数据就没法发送出去,仿真了一下,发现程序在写DR寄存器这里卡住了,并且从watch窗口中看到CR1->DR这个寄存器一直在闪烁,在0和no in scope之间来回跳转,从侧面反应了这个DR中的数据是暂时的,写入的数据只能转给移位寄存器,因此从监视器中是不可读到的,所以只有等转移完以后才能读,这时候DR已经变为0了。
如果有板子的可以接到示波器或者电脑串口上看一下,应该有数据发送出去。