- #include "main.h"
- #define Usart1_RX_TASK_PRIO 3 /* 任务优先级 */
- #define Usart1_RX_STK_SIZE 512 /* 任务堆栈大小 */
- TaskHandle_t Usart1_RXTask_Handler; /* 任务句柄 */
- void Usart1_RX_task(void *pvParameters);
- #define Usart1_TX_TASK_PRIO 4 /* 任务优先级 */
- #define Usart1_TX_STK_SIZE 512 /* 任务堆栈大小 */
- TaskHandle_t Usart1_TX_Task_Handler; /* 任务句柄 */
- void Usart1_TX_task(void *pvParameters);
- /*队列句柄*/
- QueueHandle_t RX_queue; //串口RX队列
- QueueHandle_t TX_queue; //串口RX队列
- uint16_t bufflen = 0; //接收数据长度
- void Usart1_RX_Isr_FunCb(uint8_t *data,uint16_t datalen)
- {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- bufflen = datalen;
- xQueueSendFromISR(RX_queue,&data,&xHigherPriorityTaskWoken); //将数据放入消息队列
- if(xHigherPriorityTaskWoken == pdTRUE)
- {
- portYIELD_FROM_ISR(xHigherPriorityTaskWoken); //如果需要就切换任务
- }
- }
- void Usart1_RX_task(void *pvParameters)
- {
-
- pvParameters=pvParameters;
- Usart1_RX_FunCb(Usart1_RX_Isr_FunCb);
- uint8_t res = 0;
- uint8_t * rev_data ;
- while(1)
- {
- res=xQueueReceive(RX_queue,&rev_data,portMAX_DELAY); //接收队列的数据
-
- if(res == pdPASS)
- {
- Usart1_Txdata(rev_data,bufflen);//向队列放入数据
- }
- }
- }
- void Usart1_TX_Fun(uint8_t *data,uint16_t datalen)
- {
- xQueueSend(TX_queue,&data,portMAX_DELAY); //发送队列的数据
- }
- void Usart1_TX_task(void *pvParameters)
- {
- pvParameters=pvParameters;
- uint8_t res = 0;
- uint8_t *tx_buff;
- Usart1_TX_FunCb(Usart1_TX_Fun);
- while(1)
- {
- res = xQueueReceive(TX_queue,&tx_buff,portMAX_DELAY); //接收TX队列的数据
- if(res == pdPASS)
- {
- Uart1_DMA_ENABLE(tx_buff,bufflen); //启动DMA
- }
- }
- }
- void UsartAPP_Task_Init(void)
- {
-
- RX_queue = xQueueCreate(10,sizeof(uint8_t *)); //串口RX队列,接收为一桢数据 存放地址就可以
-
- if(RX_queue != NULL)
- {
- printf("\r\n串口RX队列创建成功\r\n");
- }
- TX_queue = xQueueCreate(10,sizeof(uint8_t *)); //串口TX队列,接收为一桢数据 存放地址就可以
-
- if(TX_queue != NULL)
- {
- printf("\r\n串口TX队列创建成功\r\n");
- }
-
- /* Usart1_RX 任务 */
- xTaskCreate((TaskFunction_t )Usart1_RX_task, /* 任务函数 */
- (const char* )"Usart1_RX_task", /* 任务名称 */
- (uint16_t )Usart1_RX_STK_SIZE, /* 任务堆栈大小 */
- (void* )NULL, /* 传递给任务函数的参数 */
- (UBaseType_t )Usart1_RX_TASK_PRIO, /* 任务优先级 */
- (TaskHandle_t* )&Usart1_RX_task); /* 任务句柄 */
-
- xTaskCreate((TaskFunction_t )Usart1_TX_task, /* 任务函数 */
- (const char* )"Usart1_TX_task", /* 任务名称 */
- (uint16_t )Usart1_TX_STK_SIZE, /* 任务堆栈大小 */
- (void* )NULL, /* 传递给任务函数的参数 */
- (UBaseType_t )Usart1_TX_TASK_PRIO, /* 任务优先级 */
- (TaskHandle_t* )&Usart1_TX_task); /* 任务句柄 */
- }
usart_drv.c- #include "usart_drv.h"
- UCB uart1; //串口1控制结构体
- uint8_t Usart1_RxBuff[U1_RX_SIZE]; //串口1接收缓冲区
- uint8_t Usart1_TxBuff[U1_TX_SIZE]; //串口1发送缓冲区
- static void(*USART1_TXFun)(uint8_t *data,uint16_t data_len); //函数指针
- void Usart1_TX_FunCb(void(*pFunc)(uint8_t *data,uint16_t datalen))
- {
- USART1_TXFun = pFunc;
- }
- void Usart1_Txdata(uint8_t *data,uint32_t data_len)
- {
- if(data_len == 0) //防止发送0个数据
- {
- uart1.TxState = 0;
- uart1.TxCounter = 0;
- return ;
- }
-
- if((U1_TX_SIZE - uart1.TxCounter) >= data_len)
- {
- USART1_TXFun(data,data_len);
- }
- }
- void Uart1_DMA_ENABLE(uint8_t *data,uint32_t data_len)
- {
- HAL_UART_Transmit_DMA(&uart1.uart,data,data_len);
- }
- /*************************************************************************
- * 函 数 名: UART1_Init
- * 功能说明: 串口1初始化
- * 形 参:无
- * 返 回 值: 无
- **************************************************************************/
- void UART1_Init(uint32_t baudrate)
- {
- memset(&uart1.uart,0,sizeof(uart1.uart));
- uart1.uart.Instance = USART1;
- uart1.uart.Init.BaudRate = baudrate;
- uart1.uart.Init.WordLength =UART_WORDLENGTH_8B;
- uart1.uart.Init.StopBits=UART_STOPBITS_1;
- uart1.uart.Init.Parity=UART_PARITY_NONE;
- uart1.uart.Init.Mode=UART_MODE_TX_RX;
- uart1.uart.Init.HwFlowCtl=UART_HWCONTROL_NONE;
- HAL_UART_Init(&uart1.uart);
-
- __HAL_UART_CLEAR_IDLEFLAG(&uart1.uart);
- __HAL_UART_ENABLE_IT(&uart1.uart,UART_IT_IDLE);
- HAL_UART_Receive_DMA(&uart1.uart,Usart1_RxBuff,U1_RX_MAX);
-
- }
- uint8_t tempbuff1[256]={0};
- void Usart1_printf(char *fmt,...)
- {
- uint16_t i;
-
- va_list ap;
- va_start(ap,fmt);
- vsprintf((char *)tempbuff1,fmt,ap);
- va_end(ap);
-
- for(i=0;i<strlen((char *)tempbuff1);i++)
- {
- while(!__HAL_UART_GET_FLAG(&uart1.uart,UART_FLAG_TXE))
- {
- }
- uart1.uart.Instance->TDR = tempbuff1[i];
- }
-
- while(!__HAL_UART_GET_FLAG(&uart1.uart,UART_FLAG_TC))
- {
-
- }
- }
- void HAL_UART_MspInit(UART_HandleTypeDef *huart)
- {
- GPIO_InitTypeDef GPIO_InitTypeDefStructur;
-
- if(huart ->Instance == USART1)
- {
-
- __HAL_RCC_DMA2_CLK_ENABLE();
- __HAL_RCC_GPIOA_CLK_ENABLE();
- __HAL_RCC_USART1_CLK_ENABLE();
-
-
- GPIO_InitTypeDefStructur.Pin =GPIO_PIN_9;
- GPIO_InitTypeDefStructur.Mode = GPIO_MODE_AF_PP;
- GPIO_InitTypeDefStructur.Speed = GPIO_SPEED_FREQ_HIGH;
- GPIO_InitTypeDefStructur.Pull=GPIO_PULLUP;
- GPIO_InitTypeDefStructur.Alternate=GPIO_AF7_USART1;
-
- HAL_GPIO_Init(GPIOA,&GPIO_InitTypeDefStructur);
-
- GPIO_InitTypeDefStructur.Pin =GPIO_PIN_10;
- GPIO_InitTypeDefStructur.Alternate=GPIO_AF7_USART1;
- HAL_GPIO_Init(GPIOA,&GPIO_InitTypeDefStructur);
-
- HAL_NVIC_SetPriority(USART1_IRQn,7,0);
- HAL_NVIC_EnableIRQ(USART1_IRQn);
-
- //TX
- uart1.dmatx.Instance = DMA2_Stream7;
- uart1.dmatx.Init.Request= DMA_REQUEST_USART1_TX; /* USART1发送DMA */
- uart1.dmatx.Init.Direction = DMA_MEMORY_TO_PERIPH; /* 存储器到外设 */
- uart1.dmatx.Init.PeriphInc = DMA_PINC_DISABLE; /* 外设非增量模式 */
- uart1.dmatx.Init.MemInc = DMA_MINC_ENABLE; /* 存储器增量模式 */
- uart1.dmatx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- uart1.dmatx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- uart1.dmatx.Init.Mode = DMA_NORMAL;
- uart1.dmatx.Init.Priority=DMA_PRIORITY_MEDIUM;
- uart1.dmatx.Init.FIFOThreshold=DMA_FIFOMODE_DISABLE;
- HAL_DMA_Init(&uart1.dmatx);
-
- __HAL_LINKDMA(huart,hdmatx,uart1.dmatx); //连接DMA通道
-
- HAL_NVIC_SetPriority(DMA2_Stream7_IRQn,7,0);
- HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
-
-
- //RX
- uart1.dmarx.Instance = DMA2_Stream2; /* 数据流选择 */
- uart1.dmarx.Init.Request= DMA_REQUEST_USART1_RX; /* USART1发送DMA */
- uart1.dmarx.Init.Direction = DMA_PERIPH_TO_MEMORY;
- uart1.dmarx.Init.PeriphInc = DMA_PINC_DISABLE;
- uart1.dmarx.Init.MemInc = DMA_MINC_ENABLE;
- uart1.dmarx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- uart1.dmarx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- uart1.dmarx.Init.Mode = DMA_NORMAL;
- uart1.dmarx.Init.Priority=DMA_PRIORITY_MEDIUM;
- uart1.dmarx.Init.FIFOThreshold=DMA_FIFOMODE_DISABLE;
-
- __HAL_LINKDMA(huart,hdmarx,uart1.dmarx); //连接DMA通道
- HAL_DMA_Init(&uart1.dmarx);
- HAL_NVIC_SetPriority(DMA2_Stream2_IRQn,7,0);
- HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
- }
-
- }
- void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
- {
- if(huart ->Instance == USART1)
- {
- uart1.TxState=0;
- }
-
- }
- void Usart1_Send_Data(uint8_t *data,uint16_t datalen)
- {
- uint16_t i;
- for(i=0;i<datalen;i++)
- {
- while(!__HAL_UART_GET_FLAG(&uart1.uart,UART_FLAG_TXE));
- uart1.uart.Instance->TDR = data[i];
- }
-
- while(!__HAL_UART_GET_FLAG(&uart1.uart,UART_FLAG_TC));
- }
- static void(*USART1_RXFun)(uint8_t *data,uint16_t datalen); //函数指针
- void Usart1_RX_FunCb(void(*pFunc)(uint8_t *data,uint16_t datalen))
- {
- USART1_RXFun = pFunc;
- }
- void USART1_IRQHandler(void)
- {
- HAL_UART_IRQHandler(&uart1.uart);
- if(__HAL_UART_GET_FLAG(&uart1.uart,UART_FLAG_IDLE))
- {
-
- __HAL_UART_CLEAR_IDLEFLAG(&uart1.uart); //清除空闲中断标志
- __HAL_DMA_DISABLE_IT(&uart1.dmarx,DMA_IT_HT);//禁止DMA传输过半中断
-
- uart1.RxCounter = ((U1_RX_MAX) - __HAL_DMA_GET_COUNTER(&uart1.dmarx)); //计算本次的接收数据量
- if(USART1_RXFun != NULL)
- {
- USART1_RXFun(Usart1_RxBuff,uart1.RxCounter);
- }
-
- HAL_UART_DMAStop(&uart1.uart); //停止DMA
- HAL_UART_Receive_DMA(&uart1.uart,Usart1_RxBuff,U1_RX_MAX);
-
- }
-
- }
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- if(huart ->Instance == USART1)
- {
- if(__HAL_DMA_GET_FLAG(&uart1.dmarx, DMA_FLAG_TCIF2_6) == RESET)
- {
- __HAL_DMA_CLEAR_FLAG(&uart1.dmarx, DMA_FLAG_TCIF2_6); //清除DMA2_Steam2传输完成标志
- HAL_UART_DMAStop(&uart1.uart); //停止DMA
- HAL_UART_Receive_DMA(&uart1.uart,Usart1_RxBuff,U1_RX_MAX+1);
- }
-
- if(__HAL_DMA_GET_FLAG(&uart1.dmarx, DMA_FLAG_TCIF3_7) == RESET)
- {
- __HAL_DMA_CLEAR_FLAG(&uart1.dmarx, DMA_FLAG_TCIF3_7); //清除DMA2_Steam7传输完成标志
- }
- }
- }
- void DMA2_Stream2_IRQHandler(void)
- {
- HAL_DMA_IRQHandler(&uart1.dmarx);
- }
- void DMA2_Stream7_IRQHandler(void)
- {
- HAL_DMA_IRQHandler(&uart1.dmatx);
- }
- #if 1
- #if (__ARMCC_VERSION >= 6010050) /* 使用AC6编译器时 */
- __asm(".global __use_no_semihosting\n\t"); /* 声明不使用半主机模式 */
- __asm(".global __ARM_use_no_argv \n\t"); /* AC6下需要声明main函数为无参数格式,否则部分例程可能出现半主机模式 */
- #else
- /* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */
- #pragma import(__use_no_semihosting)
- struct __FILE
- {
- int handle;
- /* Whatever you require here. If the only file you are using is */
- /* standard output using printf() for debugging, no file handling */
- /* is required. */
- };
- #endif
- /* 不使用半主机模式,至少需要重定义_ttywrch\_sys_exit\_sys_command_string函数,以同时兼容AC6和AC5模式 */
- int _ttywrch(int ch)
- {
- ch = ch;
- return ch;
- }
- /* 定义_sys_exit()以避免使用半主机模式 */
- void _sys_exit(int x)
- {
- x = x;
- }
- char *_sys_command_string(char *cmd, int len)
- {
- return NULL;
- }
- /* FILE 在 stdio.h里面定义. */
- FILE __stdout;
- /* 重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */
- int fputc(int ch, FILE *f)
- {
- while ((uart1.uart.Instance->ISR & 0X40) == 0); /* 等待上一个字符发送完成 */
-
- uart1.uart.Instance->TDR = (uint8_t)ch; /* 将要发送的字符 ch 写入到DR寄存器 */
- return ch;
- }
- #endif
- /******************************************************************************************/
usart_drv.h- #ifndef __USART_DRV_H
- #define __USART_DRV_H
- #include "stm32h7xx_hal.h"
- #include "string.h"
- #include "signal.h"
- #include "stdarg.h"
- #include "stdio.h"
- #define U1_RX_SIZE 257
- #define U1_TX_SIZE 256
- #define U1_RX_MAX 257
- #define U1_TX_MAX 256
- typedef struct{
- uint8_t *start;
- uint8_t *end;
- }LCB;
- typedef struct{
- uint32_t RxCounter;
- uint32_t TxCounter;
- uint32_t TxState;
-
- UART_HandleTypeDef uart;
- DMA_HandleTypeDef dmatx;
- DMA_HandleTypeDef dmarx;
- }UCB;
- void UART1_Init(uint32_t baudrate);
- void Usart1_PtrInit(void);
- void Usart1_Txdata(uint8_t *data,uint32_t data_len);
- void Uart1_DMA_ENABLE(uint8_t *data,uint32_t data_len);
- void Usart1_printf(char *fmt,...);
- void Usart1_Send_Data(uint8_t *data,uint16_t datalen);
- void Usart1_RX_FunCb(void(*pFunc)(uint8_t *data,uint16_t datalen));
- void Usart1_TX_FunCb(void(*pFunc)(uint8_t *data,uint16_t datalen));
- #endif