//**********************************************************
//结构体实例初始化
//**********************************************************
T_COMOptr COM1 ={
.isReFinish = FALSE,
.renum = 0,
.ComInit = uart1_init,
.SendByte = uart1_send,
.SendBuf = uart1_sendbuf,
};
T_COMOptr COM2 ={
.isReFinish = FALSE,
.renum = 0,
.ComInit = uart2_init,
.SendByte = uart2_send,
.SendBuf = uart2_sendbuf,
};
T_COMOptr COM3 ={
.isReFinish = FALSE,
.renum = 0,
.ComInit = uart3_init,
.SendByte = uart3_send,
.SendBuf = uart3_sendbuf,
};
T_COMOptr COM4 ={
.isReFinish = FALSE,
.renum = 0,
.ComInit = uart4_init,
.SendByte = uart4_send,
.SendBuf = uart4_sendbuf,
};
//**********************************************************
//UART句柄
//**********************************************************
UART_HandleTypeDef UART1_Handler; //UART句柄
DMA_HandleTypeDef hdma_usart1_rx;
UART_HandleTypeDef UART2_Handler; //UART句柄
DMA_HandleTypeDef hdma_usart2_rx;
UART_HandleTypeDef UART3_Handler; //UART句柄
DMA_HandleTypeDef hdma_usart3_rx;
UART_HandleTypeDef UART4_Handler; //UART4句柄
DMA_HandleTypeDef hdma_uart4_rx;
//**********************************************************
//支持printf函数,而不需要选择use MicroLIB
//**********************************************************
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
USART3->DR = (u8) ch;
return ch;
}
#endif
//**********************************************************
//名称:uart1_send函数
//功能:串口1发送
//**********************************************************
static void uart1_send(u8 dat)
{
USART1->DR = dat;
while((USART1->SR&0X40)==0);
}
//**********************************************************
//名称:uart1_sendbuf函数
//功能:串口1发送
//**********************************************************
static void uart1_sendbuf(u8 *pdata,u8 num)
{
u8 i;
for(i = 0;i < num;i++)
{
uart1_send(*(pdata+i));
}
}
//**********************************************************
//名称:uart2_send函数
//功能:串口2发送
//**********************************************************
static void uart2_send(u8 dat)
{
USART2->DR = dat;
while((USART2->SR&0X40)==0);
}
//**********************************************************
//名称:uart2_sendbuf函数
//功能:串口2发送
//**********************************************************
static void uart2_sendbuf(u8 *pdata,u8 num)
{
u8 i;
for(i = 0;i < num;i++)
{
uart2_send(*(pdata+i));
}
}
//**********************************************************
//名称:uart3_send函数
//功能:串口1发送
//**********************************************************
static void uart3_send(u8 dat)
{
while((USART3->SR&0X40)==0);
USART3->DR = dat;
}
//**********************************************************
//名称:uart3_sendbuf函数
//功能:串口1发送
//**********************************************************
static void uart3_sendbuf(u8 *pdata,u8 num)
{
u8 i;
for(i = 0;i < num;i++)
{
uart3_send(*(pdata+i));
}
}
/************************************************
名 称: uart4_send
功 能: 串口4单字节发送函数
************************************************/
static void uart4_send(u8 dat)
{
while((UART4->SR&0X40)==0);//循环发送,直到发送完毕
UART4->DR = dat;
}
/************************************************
名 称: uart4_sendbuf
功 能: 串口4多字节发送函数
************************************************/
static void uart4_sendbuf(u8 *pdata,u8 num)
{
u8 i;
for(i = 0;i < num;i++)
{
uart4_send(*(pdata+i));
}
}
//**********************************************************
//名称:uart1_init函数
//功能:用于串口1的初始化,bound:波特率
//**********************************************************
static void uart1_init(u32 bound)
{
//UART 初始化设置
UART1_Handler.Instance=USART1; //USART1
UART1_Handler.Init.BaudRate=bound; //波特率
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
UART1_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
UART1_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
UART1_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()会使能UART1
HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&UART1_Handler.Instance->DR, (uint32_t)(COM1.rxbuf), UART_MAX_LEN);
SET_BIT(UART1_Handler.Instance->CR3, USART_CR3_DMAR);
}
//**********************************************************
//名称:uart2_init函数
//功能:用于串口2的初始化,bound:波特率
//**********************************************************
static void uart2_init(u32 bound)
{
//UART 初始化设置
UART2_Handler.Instance=USART2; //USART2
UART2_Handler.Init.BaudRate=bound; //波特率
UART2_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
UART2_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
UART2_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
UART2_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
UART2_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&UART2_Handler); //HAL_UART_Init()会使能UART2
HAL_DMA_Start_IT(&hdma_usart2_rx, (uint32_t)&UART2_Handler.Instance->DR, (uint32_t)(COM2.rxbuf), UART_MAX_LEN);
SET_BIT(UART2_Handler.Instance->CR3, USART_CR3_DMAR);
}
/************************************************
名 称: uart3_init
功 能: 串口3初始化函数
输入参数: bound--无符号32位整型指针 波特率
输出参数: 无
返回值: void
************************************************/
static void uart3_init(u32 bound)
{
//UART 初始化设置
UART3_Handler.Instance=USART3; //USART3
UART3_Handler.Init.BaudRate=bound; //波特率
UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
UART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
UART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
UART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&UART3_Handler); //HAL_UART_Init()会使能USART1
HAL_DMA_Start_IT(&hdma_usart3_rx, (uint32_t)&UART3_Handler.Instance->DR, (uint32_t)(COM3.rxbuf), UART_MAX_LEN);
SET_BIT(UART3_Handler.Instance->CR3, USART_CR3_DMAR);
}
/************************************************
名 称: uart4_init
功 能: 串口4初始化函数
输入参数: bound--无符号32位整型指针 波特率
输出参数: 无
返回值: void
************************************************/
static void uart4_init(u32 bound)
{
//UART 初始化设置
UART4_Handler.Instance=UART4; //UART4
UART4_Handler.Init.BaudRate=bound; //波特率
UART4_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
UART4_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
UART4_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
UART4_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
UART4_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&UART4_Handler); //HAL_UART_Init()会使能USART1
HAL_DMA_Start_IT(&hdma_uart4_rx, (uint32_t)&UART4_Handler.Instance->DR, (uint32_t)(COM4.rxbuf), UART_MAX_LEN);
SET_BIT(UART4_Handler.Instance->CR3, USART_CR3_DMAR);
}
//**********************************************************
//名称:HAL_UART_MspInit函数
//功能:UART底层初始化,时钟使能,引脚配置,中断配置
// 此函数会被HAL_UART_Init()调用。huart:串口句柄
//**********************************************************
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_Initure;
/**********************串口1*************************/
if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
{
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
__HAL_RCC_DMA1_CLK_ENABLE();
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;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
GPIO_Initure.Pin=GPIO_PIN_10;
GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_usart1_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(USART1_IRQn,2,1); //抢占优先级2,子优先级1
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); //使能空闲中断
}
/**********************串口2*************************/
if(huart->Instance==USART2)//如果是串口2,进行串口2 MSP初始化
{
__HAL_RCC_USART2_CLK_ENABLE(); //使能USART2时钟
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_2; //PA2
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA2
GPIO_Initure.Pin=GPIO_PIN_3;
GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA3
hdma_usart2_rx.Instance = DMA1_Channel6;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_usart2_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
HAL_NVIC_EnableIRQ(USART2_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(USART2_IRQn,2,2); //抢占优先级2,子优先级1
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); //使能空闲中断
}
/**********************串口3*************************/
if(huart->Instance==USART3)//如果是串口3,进行串口3 MSP初始化
{
__HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_10;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化PB10
GPIO_Initure.Pin=GPIO_PIN_11;
GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化PB11
hdma_usart3_rx.Instance = DMA1_Channel3;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_usart3_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_usart3_rx);
HAL_NVIC_EnableIRQ(USART3_IRQn);
HAL_NVIC_SetPriority(USART3_IRQn,3,1);
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
}
/**********************串口4*************************/
if(huart->Instance==UART4)
{
__HAL_RCC_UART4_CLK_ENABLE(); //使能USART4时钟
__HAL_RCC_DMA2_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_10;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOC,&GPIO_Initure); //初始化PC10
GPIO_Initure.Pin=GPIO_PIN_11;
GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;
HAL_GPIO_Init(GPIOC,&GPIO_Initure); //初始化PC11
hdma_uart4_rx.Instance = DMA2_Channel3;
hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart4_rx.Init.Mode = DMA_CIRCULAR;
hdma_uart4_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_uart4_rx);
__HAL_LINKDMA(huart,hdmarx,hdma_uart4_rx);
HAL_NVIC_EnableIRQ(UART4_IRQn); //使能UART4断通道
HAL_NVIC_SetPriority(UART4_IRQn,2,0); //抢占优先级3,子优先级1
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
}
}
//**********************************************************
//名称:USART1_IRQHandler函数
//功能:串口1中断处理函数
//**********************************************************
void USART1_IRQHandler(void)
{
u8 re_dat = 0;
re_dat = re_dat; //消除警告
#if SYSTEM_SUPPORT_OS //使用OS
OSIntEnter();
#endif
if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE)!=RESET))
{
//__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
re_dat = USART1->SR;
re_dat = USART1->DR;
COM1.renum = UART_MAX_LEN - hdma_usart1_rx.Instance->CNDTR;
COM1.isReFinish = TRUE;
__HAL_UNLOCK(&hdma_usart1_rx);
HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&UART1_Handler.Instance->DR, (uint32_t)(COM1.rxbuf), UART_MAX_LEN);
COM1_Data_Rev();
}
#if SYSTEM_SUPPORT_OS //使用OS
OSIntExit();
#endif
}
//**********************************************************
//名称:USART2_IRQHandler函数
//功能:串口1中断处理函数
//FPGA通信
//**********************************************************
void USART2_IRQHandler(void)
{
u8 re_dat = 0;
re_dat = re_dat; //消除警告
#if SYSTEM_SUPPORT_OS //使用OS
OSIntEnter();
#endif
if((__HAL_UART_GET_FLAG(&UART2_Handler,UART_FLAG_IDLE)!=RESET))
{
re_dat = USART2->SR;
re_dat = USART2->DR;
COM2.renum = UART_MAX_LEN - hdma_usart2_rx.Instance->CNDTR;
COM2.isReFinish = TRUE;
__HAL_UNLOCK(&hdma_usart2_rx);
HAL_DMA_Start_IT(&hdma_usart2_rx, (uint32_t)&UART2_Handler.Instance->DR, (uint32_t)(COM2.rxbuf), UART_MAX_LEN);
COM2_Data_Rev();
}
#if SYSTEM_SUPPORT_OS //使用OS
OSIntExit();
#endif
}
//**********************************************************
//名称:USART3_IRQHandler函数
//功能:串口3中断处理函数
//TEST
//**********************************************************
void USART3_IRQHandler(void)
{
u8 re_dat = 0;
re_dat = re_dat; //消除警告
#if SYSTEM_SUPPORT_OS //使用OS
OSIntEnter();
#endif
if((__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_IDLE)!=RESET))
{
re_dat = USART3->SR;
re_dat = USART3->DR;
COM3.renum = UART_MAX_LEN - hdma_usart3_rx.Instance->CNDTR;
COM3.isReFinish = TRUE;
__HAL_UNLOCK(&hdma_usart3_rx);
HAL_DMA_Start_IT(&hdma_usart3_rx, (uint32_t)&UART3_Handler.Instance->DR, (uint32_t)(COM3.rxbuf), UART_MAX_LEN);
COM3_Data_Rev();
}
#if SYSTEM_SUPPORT_OS //使用OS
OSIntExit();
#endif
}
//**********************************************************
//名称:USART4_IRQHandler函数
//功能:串口4中断处理函数
//WIFI
//**********************************************************
void UART4_IRQHandler(void)
{
u8 re_dat = 0;
re_dat = re_dat; //消除警告
#if SYSTEM_SUPPORT_OS //使用OS
OSIntEnter();
#endif
if((__HAL_UART_GET_FLAG(&UART4_Handler,UART_FLAG_IDLE)!=RESET))
{
re_dat = UART4->SR;
re_dat = UART4->DR;
COM4.renum = UART_MAX_LEN - hdma_uart4_rx.Instance->CNDTR;
COM4.isReFinish = TRUE;
__HAL_UNLOCK(&hdma_uart4_rx);
HAL_DMA_Start_IT(&hdma_uart4_rx, (uint32_t)&UART4_Handler.Instance->DR, (uint32_t)(COM4.rxbuf), UART_MAX_LEN);
COM4_Data_Rev();
}
#if SYSTEM_SUPPORT_OS //使用OS
OSIntExit();
#endif
}
STM32串口空闲中断DMA的实现
于 2021-01-27 17:30:52 首次发布