STM32
直播中

任凭风吹

9年用户 1012经验值
擅长:可编程逻辑 电源/新能源 MEMS/传感技术 制造/封装 模拟技术
私信 关注
[问答]

如何去完成基于STM32f429 HAL库的串口通信接收实验呢

如何去完成基于STM32f429 HAL库的串口通信接收实验呢?其配置步骤有哪些?

回帖(1)

陈超

2021-11-17 09:29:46
  STM32f429串口通信接收-基于HAL库
  串口接收
  配置步骤
  1.调用函数 HAL_UART_Init(UART_HandleTypeDef *huart) 。
  通过定义结构体类型句柄 UART_HandleTypeDef 并初始化相关参数来配置串口通信的选用串口、字长、波特率、停止位、奇偶校验位、硬件流控、收发模式、DMA等。
  UART_HandleTypeDef usart1_handler; //UART句柄
  结构体UART_HandleTypeDef 定义如下
  typedef struct
  {
  USART_TypeDef *Instance; /*!《 UART registers base address */
  UART_InitTypeDef Init; /*!《 UART communication parameters */
  uint8_t *pTxBuffPtr; /*!《 Pointer to UART Tx transfer Buffer */
  uint16_t TxXferSize; /*!《 UART Tx Transfer size */
  uint16_t TxXferCount; /*!《 UART Tx Transfer Counter */
  uint8_t *pRxBuffPtr; /*!《 Pointer to UART Rx transfer Buffer */
  uint16_t RxXferSize; /*!《 UART Rx Transfer size */
  uint16_t RxXferCount; /*!《 UART Rx Transfer Counter */
  DMA_HandleTypeDef *hdmatx; /*!《 UART Tx DMA Handle parameters */
  DMA_HandleTypeDef *hdmarx; /*!《 UART Rx DMA Handle parameters */
  HAL_LockTypeDef Lock; /*!《 Locking object */
  __IO HAL_UART_StateTypeDef State; /*!《 UART communication state */
  __IO uint32_t ErrorCode; /*!《 UART Error code */
  }UART_HandleTypeDef;
  初始化相关参数
  usart1_handler.Instance=USART1; //USART1
  usart1_handler.Init.BaudRate=115200; //波特率
  usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
  usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
  usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
  usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
  usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
  HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
  HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//开启接收中断
  调用函数 HAL_UART_Init(UART_HandleTypeDef *huart) 后会使能相应的串口(此处为UART1),就不用再使能相应的串口了,同时在函数内部会调用回调函数 。同时开启了接收中断。
  以上两步可以封装在同一个函数下。
  2. void HAL_UART_MspInit(UART_HandleTypeDef *huart),它是一个弱函数需要自己定义
  void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  {
  GPIO_InitTypeDef GPIO_Initure;
  if(huart-》Instance==USART1)//如果是串口1,进行串口1 MSP初始化
  {
  __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
  __HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
  GPIO_Initure.Pin=GPIO_PIN_9; //PA9
  GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
  GPIO_Initure.Pull=GPIO_PULLUP; //上拉
  GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
  GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
  HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
  GPIO_Initure.Pin=GPIO_PIN_10; //PA10
  HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
  HAL_NVIC_EnableIRQ(USART1_IRQn);//使能usart1中断通道
  HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);//抢占优先级3,子优先级3
  }
  }
  在调用HAL_UART_Init(UART_HandleTypeDef *huart) 时在函数内部会调用一个相同的回调函数 HAL_UART_MspInit(UART_HandleTypeDef *huart),所以编写回调函数时需要约束判断条件,究竟是哪个串口的回调函数。
  串口接收中断优先级配置和使能:
  HAL_NVIC_EnableIRQ(USART1_IRQn);
  HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
  当我们开启了串口接收中断后,每收到一个字符就会产生一次中断,,进入中断服务函数USART1_IRQHandler,
  DCD I2C1_EV_IRQHandler ; I2C1 Event
  DCD I2C1_ER_IRQHandler ; I2C1 Error
  DCD I2C2_EV_IRQHandler ; I2C2 Event
  DCD I2C2_ER_IRQHandler ; I2C2 Error
  DCD SPI1_IRQHandler ; SPI1
  DCD SPI2_IRQHandler ; SPI2
  DCD USART1_IRQHandler ; USART1
  DCD USART2_IRQHandler ; USART2
  DCD USART3_IRQHandler ; USART3
  这个函数需要自己编写,并在这个函数里面调用HAL库的中断处理函数(该函数会对相应的中断来源进行分析,调用相应函数)。
  void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
  即每收到一个字符就调用一次中断服务函数USART1_IRQHandler,当收到的数据满足了设置的大小时
  HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
  就会将相应的串口接收中断取消使能,所以在中断服务函数USART1_IRQHandler中除了调用HAL库的中断处理函数还要加上一个使能串口接收中断函数(因为此代码实现的功能是每接收一个字符就发送出去,所以设置的结束数据长度是一)。
  HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  void USART1_IRQHandler(void)
  {
  HAL_UART_IRQHandler(&usart1_handler);
  HAL_UART_Receive_IT(&usart1_handler, (u8 *)buff, 1);
  }
  当全部数据接收完成后HAL_UART_IRQHandler函数会调用相应的回调函数
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  不管是处理完什么类型的中断,HAL_UART_IRQHandler函数会调用同一个回调函数,所以回调函数也需要判断条件是哪个类型的中断回调的
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  {
  if(huart-》Instance==USART1)//如果是串口1
  {
  u8 rdata;
  rdata=*(--(huart-》pRxBuffPtr));
  HAL_UART_Transmit(&usart1_handler, &rdata, 1, 1000);
  }
  }
  在最终的中断处理函数里写入想执行的操作
  
  
举报

更多回帖

发帖
×
20
完善资料,
赚取积分