Stm32F1串口实验

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 复用

  1. 通用:IO端口的输入和输出是由GPIO外设控制
  2. 复用: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);
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值