HAL库_多串口数据收发 -学习日志{可将其他串口数据通过同一串口发出(中断接收/轮询发送)}

这篇学习日志介绍了如何在STM32单片机上实现多串口数据的中断接收和轮询发送。通过特定的宏定义和C文件配置,可以实现各串口独立收发或集中发送其他串口接收到的数据。
摘要由CSDN通过智能技术生成

学习日志

此程序使用中断接收/轮询发送,各个串口可以独立收发或将其他串口接收到的数据统一发给其中某一串口。
效果如下
将串口2和串口3的数据发送给串口1

//主函数
//包含头文件
#include "stm32f4xx_hal.h"
#include "string.h"
#include "my_usartx1.h"
#include "my_usartx2.h"
#include "my_usartx3.h"


//接收缓冲区定义
uint8_t Usart1_Rxbuffer;
uint8_t Usart2_Rxbuffer;
uint8_t Usart3_Rxbuffer;
int main(void)
{
  uint8_t txbuf_1[50];
  uint8_t txbuf_2[50];
  uint8_t txbuf_3[50];
 
  HAL_Init(); //复位所有外设,初始化Flash接口和系统滴答定时器
  SystemClock_Config();//配置系统时钟
  
  MX_USARTx1_Init();//初始化串口并配置串口中断优先级
  MX_USARTx2_Init();
  MX_USARTx3_Init();
/*
在复位后会向上位机发送所连串口信息,
如连入串口一后复位开发板,会向上位机发送“这是串口一”
*/
  memcpy(txbuf_1,"这是串口一",50);
  HAL_UART_Transmit(&husart1,txbuf_1,strlen((char *)txbuf_1),1000);
  
  memcpy(txbuf_2,"这是串口二",50);
  HAL_UART_Transmit(&husart2,txbuf_2,strlen((char *)txbuf_2),1000);
	
  memcpy(txbuf_3,"这是串口三",50);
  HAL_UART_Transmit(&husart3,txbuf_3,strlen((char *)txbuf_3),1000);
  
//串口中断接收函数
  HAL_UART_Receive_IT(&husart1,&Usart1_Rxbuffer,1);
  HAL_UART_Receive_IT(&husart2,&Usart2_Rxbuffer,1);
  HAL_UART_Receive_IT(&husart3,&Usart3_Rxbuffer,1);
  while (1)
  {    
  }
}
/*
实现串口中断接收的重点在于中断回调(HAL_UART_RxCpltCallback)
和中断处理(USARTx1_IRQHANDLER)
*/

//中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USARTx1)//USARTx1已在h文件中定义为USART1,下同
		{
			HAL_UART_Transmit_IT(&husart1,&Usart1_Rxbuffer,1);
			HAL_UART_Receive_IT(&husart1,&Usart1_Rxbuffer,1);
		}
		//句柄结构体husart1指向串口1的配置程序,下同
	if(huart->Instance==USARTx2)
		{
			HAL_UART_Transmit_IT(&husart2,&Usart2_Rxbuffer,1);
			HAL_UART_Receive_IT(&husart2,&Usart2_Rxbuffer,1);
		}
	if(huart->Instance==USARTx3)
		{
			HAL_UART_Transmit_IT(&husart3,&Usart3_Rxbuffer,1);
			HAL_UART_Receive_IT(&husart3,&Usart3_Rxbuffer,1);
		}
		/*
		例:如需将串口3接收到的数据发送给串口1,
		只需将HAL_UART_Transmit_IT(&husart3,&Usart3_Rxbuffer,1);
		改为HAL_UART_Transmit_IT(&husart1,&Usart3_Rxbuffer,1);即可
		*/
}

//中断处理函数(HAL_UART_IRQHandler)在stm32f4xx_it.c文件中
void USARTx1_IRQHANDLER(void)
{
  HAL_UART_IRQHandler(&husart1);
}
void USARTx1_IRQHANDLER(void)
{
  HAL_UART_IRQHandler(&husart2);
}
void USARTx1_IRQHANDLER(void)
{
  HAL_UART_IRQHandler(&husart3);
}

串口配置宏定义“my_usartx1.h”
(其他串口配置类似,照着抄就可以)

#ifndef __MY_USARTX1_H__
#define __MY_USARTX1_H__

//包含头文件
#include "stm32f4xx_hal.h"


//串口宏定义
#define USARTx1                                 USART1
//波特率宏定义
#define USARTx1_BAUDRATE                        115200
//串口时钟使能宏定义
#define USARTx1_RCC_CLK_ENABLE()                 __HAL_RCC_USART1_CLK_ENABLE()
//串口时钟失能宏定义
#define USARTx1_RCC_CLK_DISABLE()                __HAL_RCC_USART1_CLK_DISABLE()
//引脚时钟使能宏定义
#define USARTx1_GPIO_ClK_ENABLE()               __HAL_RCC_GPIOB_CLK_ENABLE()
//引脚宏定义
#define USARTx1_Tx_GPIO_PIN                     GPIO_PIN_6
#define USARTx1_Tx_GPIO                         GPIOB
#define USARTx1_Rx_GPIO_PIN                     GPIO_PIN_7   
#define USARTx1_Rx_GPIO                         GPIOB
//串口通道宏定义
#define USARTx1_AFx                             GPIO_AF7_USART1
//串口中断宏定义
#define USARTx1_IRQHANDLER                      USART1_IRQHandler
#define USARTx1_IRQn                            USART1_IRQn


 //变量声明——————————————————————————————————————————
extern UART_HandleTypeDef husart1;

//函数声明———————————————————————————————————————————
void MX_USARTx1_Init(void);


#endif 

串口配置c文件“my_usart.c”

//包含头文件
#include "usart1/bsp_usartx1.h"
#include "usart2/bsp_usartx2.h"
#include "usart3/bsp_usartx3.h"
//句柄结构体定义
UART_HandleTypeDef husart1;
UART_HandleTypeDef husart2;
UART_HandleTypeDef husart3;

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  
  if(huart->Instance==USARTx1)
  {
    //使能串口时钟
    USARTx1_GPIO_ClK_ENABLE();
    //GPIO配置
    GPIO_InitStruct.Pin = USARTx1_Tx_GPIO_PIN;
    HAL_GPIO_Init(USARTx1_Tx_GPIO, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = USARTx1_Rx_GPIO_PIN;
    HAL_GPIO_Init(USARTx1_Rx_GPIO, &GPIO_InitStruct);
    
    GPIO_InitStruct.Alternate = USARTx1_AFx;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  }
  
	if(huart->Instance==USARTx2)
  {
       //使能串口时钟
    USARTx2_GPIO_ClK_ENABLE();
    //GPIO配置
    GPIO_InitStruct.Pin = USARTx2_Tx_GPIO_PIN;
    HAL_GPIO_Init(USARTx2_Tx_GPIO, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = USARTx2_Rx_GPIO_PIN;
    HAL_GPIO_Init(USARTx2_Rx_GPIO, &GPIO_InitStruct);
    
    GPIO_InitStruct.Alternate = USARTx2_AFx;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  }
  
	if(huart->Instance==USARTx3)
  {
    //使能串口时钟
    USARTx3_GPIO_ClK_ENABLE();
    //GPIO配置
    GPIO_InitStruct.Pin = USARTx3_Tx_GPIO_PIN;
    HAL_GPIO_Init(USARTx3_Tx_GPIO, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = USARTx3_Rx_GPIO_PIN;
    HAL_GPIO_Init(USARTx3_Rx_GPIO, &GPIO_InitStruct);
    
    GPIO_InitStruct.Alternate = USARTx3_AFx;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  }
}
//nviv中断配置(串口2、3改数字就可以)
static void MX_NVIC_USARTx1_Init(void)
{
  /* USART1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(USARTx1_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(USARTx1_IRQn);
}

//串口1配置
//(串口、波特率、数据位、停止位、校验位、串口模式、工作流控制、过采样)
//(串口2、3改数字即可)
void MX_USARTx1_Init(void)
{
  //串口外设时钟使能
  USARTx1_RCC_CLK_ENABLE();
  
  husart1.Instance = USARTx1;
  husart1.Init.BaudRate = USARTx1_BAUDRATE;
  husart1.Init.WordLength = UART_WORDLENGTH_8B;
  husart1.Init.StopBits = UART_STOPBITS_1;
  husart1.Init.Parity = UART_PARITY_NONE;
  husart1.Init.Mode = UART_MODE_TX_RX;
  husart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  husart1.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&husart1);
  
  //配置串口中断并使能
  MX_NVIC_USARTx1_Init();
}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值