串口简介
? 串口最基本的设置,就是波特率的设置。首先要开启时钟,并设置相应的IO口模式,然后配置一下波特率,数据位长度,奇偶校验位等信息就可以用了。
1.串口时钟使能
? 串口作为STM32的一个外设,其时钟由外设时钟使能寄存器控制,在stm32f103中串口1是在APB2ENR寄存器的第14位,除了串口 1 的时钟使能在 APB2ENR 寄存器,其他串口的时钟使能位都在 APB1ENR 寄存器,而 APB2(72M)的频率一般是 APB1(36M)的一倍。
2.串口复位
? 当外设出现异常的时候可以通过复位寄存器里面的相应位设置,实现外设的复位。然后重新配置这个外设达到重新工作的目的。串口的复位是通过APB2RSTR寄存器的第14位来实现的,该寄存器的各位描述如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RivCI9DO-1628243635775)(C:\Users\zkhy\AppData\Roaming\Typora\typora-user-images\image-20210805112946240.png)]
3.波特率设置,每个串口都有一个自己独立的波特率寄存器USART_BRR,通过该寄存器就可以达到配置不同波特率的目的。
4.串口控制。STM32的每个串口都有3个控制寄存器USART_CR 1~3,串口的很多配置都是通过这3个寄存器来设置的。
串口的设置一般步骤如下:
1)串口时钟使能,GPIO时钟使能。
2)设置引脚复用器映射:调用GPIO_PinAFConfig函数
3)GPIO初始化设置:设置模式为复用功能
4)串口参数初始化:设置波特率,字长,奇偶校验等参数
5)开启中断并且初始化NVIC,使能中断(如果需要开启中断才需要这样设置)
6)使能串口。
7)编写中断处理函数:函数名格式为USARTxIRQHandler(x,对应串口号)
1.串口参数初始化
? 我使用的MCU为STM32L073Rz
? 串口是STM32的一个外设,HAL库有配置有完整的初始化函数,我使用的是STM32cubemx自动配置生成的代码。初始化函数如下:
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
入口参数为huart1,为UART_HandleTypeDef结构体指针类型,也就是串口句柄,结构体成员变量如下:
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance;
UART_InitTypeDef Init;
UART_AdvFeatureInitTypeDef AdvancedInit;
uint8_t *pTxBuffPtr;
uint16_t TxXferSize;
__IO uint16_t TxXferCount;
uint8_t *pRxBuffPtr;
uint16_t RxXferSize;
__IO uint16_t RxXferCount;
uint16_t Mask;
__IO HAL_UART_RxTypeTypeDef ReceptionType;
void (*RxISR)(struct __UART_HandleTypeDef *huart);
void (*TxISR)(struct __UART_HandleTypeDef *huart);
DMA_HandleTypeDef *hdmatx;
DMA_HandleTypeDef *hdmarx;
HAL_LockTypeDef Lock;
__IO HAL_UART_StateTypeDef gState;
__IO HAL_UART_StateTypeDef RxState;
__IO uint32_t ErrorCode;
} UART_HandleTypeDef;
这些结构体成员变量非常多,一般配置的时候采用定义一个结构体变量来进行初始化,代码如下:
UART_HandleTypeDef huart1;
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
2.使能串口和GPIO时钟
? 要使用串口,一定要使能串口和GPIO的时钟,不然不会工作。
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
3.GPIO口的初始化设置
我这里的是PB6和PB7分别为RX和TX口。
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
3.开启串口相关中断,配置串口中断优先级
这个我的是在cubemx里面配置好自动生成的,也就是上面函数的最后两行,中断优先级为0,设置的最高
4.编写中断服务函数
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
未完待续。。。。。。
|