串口实验
USART/UART异步通信配置步骤(掌握)
1,配置串口工作参数:HAL_UART_Init()
2,串口底层初始化 : HAL_UART_MspInit() 配置GPIO、NVIC、CLOCK等
3,开启串口异步接收中断 :HAL_UART_Receive_IT()
4,设置优先级,使能中断: HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
5,编写中断服务函数: USARTx_IRQHandler()、 UARTx_IRQHandler()
6,串口数据发送 :USART_DR, HAL_UART_Transmit()
HAL_UART_Init(UART_HandleTypeDef *huart)
HAL_UART_Init(UART_HandleTypeDef *huart)//在stm32xx_hal_uart.c中
typedef struct __UART_HandleTypeDef//在stm32xx_hal_uart.h中
{
USART_TypeDef *Instance; /*存放usart寄存器的结构体 */
UART_InitTypeDef Init; /*!< UART communication parameters */
.......//中间还有其他成员
} UART_HandleTypeDef;
typedef struct
{
__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */
__IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */
__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef; //在stm32f103xe.h中。关于寄存器的结构体都放在这个文件中
typedef struct
{
uint32_t BaudRate; /*波特率 */
uint32_t WordLength; /*字长 */
uint32_t StopBits; /*停止位*/
uint32_t Parity; /*奇偶校验位*/
uint32_t Mode; /*UART模式*/
uint32_t HwFlowCtl; /*硬件流设置 */
uint32_t OverSampling; /*过采样设置 */
} UART_InitTypeDef;//在stm32xx_hal_uart.h中
/* 窗口初始化函数。在usart.c中 */
void usart_init(uint32_t baudrate)
{
g_uart1_handle.Instance = USART1;
g_uart1_handle.Init.BaudRate = baudrate;
g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
g_uart1_handle.Init.StopBits = UART_STOPBITS_1;//ֹͣλΪ1λ
g_uart1_handle.Init.Parity = UART_PARITY_NONE; //УÑéλΪÎÞ
g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;¡//ûÓÐÓ²¼þÁ÷¿Ø
g_uart1_handle.Init.Mode = UART_MODE_TX_RX;//ÊÕ·¢
HAL_UART_Init(&g_uart1_handle);
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
使能以中断的方式接收数据。
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
以阻塞的方式发生指定字节的数据。
HAL库外设回调机制
GPIO 复用
- 通用:IO端口的输入和输出是由GPIO外设控制
- 复用:IO端口的输入和输出是由其它非GPIO外设控制
GPIO复用寄存器
复用器特点:
1、每个 IO 引脚都有一个复用器
2、复用器采用 16 路复用功能输入(AF0 到 AF15)
3、复用器一次仅允许一个外设的复用功能 (AF) 连接到 IO 引脚
4、通过GPIOx_AFRL和GPIOx_AFRH寄存器进行配置后面的数字表示GPIOx(x属于A,B,C等)端口第几位的设置。
AFRL,AFRH
这里的端口指的是PA,PB,PC等端口。
CH340 USB转串口原理图(战舰)
使用串口接收或发送一个字符
usart.c中的内容
uint8_t g_rx_buffer[1]; /* HAL¿âʹÓõĴ®¿Ú½ÓÊÕÊý¾Ý»º³åÇø */
uint8_t g_usart1_rx_flag = 0; /* ´®¿Ú½ÓÊÕµ½Êý¾Ý±êÖ¾ */
UART_HandleTypeDef g_uart1_handle; /* UART¾ä±ú */
/* ´®¿Ú1³õʼ»¯º¯Êý */
void usart_init(uint32_t baudrate)
{
g_uart1_handle.Instance = USART1;
g_uart1_handle.Init.BaudRate = baudrate;
g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
g_uart1_handle.Init.StopBits = UART_STOPBITS_1;//停止位为1位
g_uart1_handle.Init.Parity = UART_PARITY_NONE; //校验位为无
g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;¡//无硬件流控制
g_uart1_handle.Init.Mode = UART_MODE_TX_RX;//串口具有收发功能
HAL_UART_Init(&g_uart1_handle);
//开启串口异步接受中断,接受到的数据会存放在g_rx_buffer中。
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}
/* 串口MSP回调函数。在HAL_UART_Init函数中调用,设置GPIO口,NVIC,和时钟等*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef gpio_init_struct;
if(huart->Instance == USART1) /* 如果是串口1, */
{
__HAL_RCC_USART1_CLK_ENABLE();/,
__HAL_RCC_GPIOA_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_9;
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽式复用输出 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速*/
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的TX引脚 */
gpio_init_struct.Pin = GPIO_PIN_10;
gpio_init_struct.Mode = GPIO_MODE_AF_INPUT; /* 输入 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉*/
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的RX引脚 */
//设置中断
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
//使能中断
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
/*串口1中断服务函数*/
void USART1_IRQHandler(void)
{
//这个函数会失能串口异步接受中断,HAL库中断处理公用函数
HAL_UART_IRQHandler(&g_uart1_handle);
//在中断触发后还需使能中断
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}
/* 接受中断调用回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
g_usart1_rx_flag = 1;
}
}
main.c
int main(void)
{
HAL_Init(); /* */
sys_stm32_clock_init(RCC_PLL_MUL9); /* */
delay_init(72); /* */
led_init(); /* */
usart_init(115200); /* */
while(1)
{
if(g_usart1_rx_flag == 1)
{
HAL_UART_Transmit(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1, 1000);
while(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_TC) != 1);¡//查看是否发送完成
printf("\r\n");
g_usart1_rx_flag = 0;
}
else
{
delay_ms(10);
}
}
}