完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
目标环境:
MCU:stm32f103C8T6 stm32 library:standard library V3.5.0 RTOS:FreeRTOS 实现功能: a. 接收DMA和串口IDLE中断配合接收不定长数据 b. 使用DMA发送数据 一. 初始化 #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_usart.h" #include "stm32f10x_gpio.h" #include "stm32f10x_dma.h" #include "freertos.h" #include "semphr.h" #define UART_RECV_BUF_SIZE (128) /*DMA接收缓存大小*/ #define UART_SEND_BUF_SIZE (128) /*DMA发送缓存大小*/ #define USART2_RX_IDLE_PRIORITY (0x0b) /*串口IDLE中断优先级*/ #define USART2_DMA_TX_PRIORITY (0x0c) /*DMA发送中断优先级*/ static u8 s_Uart_2_Recv_Buf[UART_RECV_BUF_SIZE] = {0}; /*存储DMA接收的数据*/ static u8 s_Uart_2_Send_Buf[UART_SEND_BUF_SIZE] = {0}; /*DMA发送缓存*/ static SemaphoreHandle_t s_Uart_2_Send_Lock; /*串口使用Lock,保证通过串口发送的数据完整性*/ static QueueHandle_t s_Uart_Recv_Queue; /*与任务通信的消息队列*/ /***************************************************************************** **函 数 名: __Uart_Send_Lock_Init **输入参数: void **输出参数: 无 **返 回 值: 无 **功能描述: 初始化锁和消息队列 **作 者: sdc *****************************************************************************/ static void __Uart_Send_Lock_Init(void) { s_Uart_2_Send_Lock = xSemaphoreCreateBinary(); if(NULL == s_Uart_2_Send_Lock) { printf("lock create failn"); } xSemaphoreGive(s_Uart_2_Send_Lock); /*保证第一次能够发送成功*/ s_Uart_Recv_Queue = xQueueCreate(10, sizeof(UART_DATA *)); /*消息队列,与任务实现通信*/ } /***************************************************************************** **函 数 名: __Uart_2_Init **输入参数: u32 baudrate:波特率 **输出参数: 无 **返 回 值: 无 **功能描述: 初始化串口2和DMA **作 者: sdc *****************************************************************************/ static void __Uart_2_Init(u32 baudrate) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; DMA_InitTypeDef DMA_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /*初始化使用USART2使用的引脚, PA2为复用推挽输出,PA3为浮空输入*/ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); USART_DeInit(USART2); USART_InitStruct.USART_BaudRate = baudrate; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStruct); NVIC_SetPriority(USART2_IRQn, USART2_RX_IDLE_PRIORITY); USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); NVIC_EnableIRQ(USART2_IRQn); DMA_DeInit(DMA1_Channel7); DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&(USART2->DR)); DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStruct.DMA_BufferSize = 1; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel7, &DMA_InitStruct); /*使能DMA发送中断*/ NVIC_SetPriority(DMA1_Channel7_IRQn, USART2_DMA_TX_PRIORITY); NVIC_EnableIRQ(DMA1_Channel7_IRQn); DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE); USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); /*USART2 recv DMA config*/ DMA_DeInit(DMA1_Channel6); DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&(USART2->DR)); DMA_InitStruct.DMA_MemoryBaseAddr = (u32)s_Uart_2_Recv_Buf; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStruct.DMA_BufferSize = UART_RECV_BUF_SIZE; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel6, &DMA_InitStruct); DMA_Cmd(DMA1_Channel6, ENABLE); USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); USART_Cmd(USART2, ENABLE); } 二. 串口发送 /***************************************************************************** **函 数 名: Uart_Send **输入参数: u8 *buff:数据缓存 u32 len:数据长度 **输出参数: 无 **返 回 值: **功能描述: 使用串口发送数据 **作 者: sdc *****************************************************************************/ void Uart_Send(u8 *buff, u32 len) { xSemaphoreTake(s_Uart_2_Send_Lock, portMAX_DELAY); memcpy(s_Uart_2_Send_Buf, buff, len); DMA_Cmd(DMA1_Channel7, DISABLE); DMA1_Channel7->CMAR = (u32)s_Uart_2_Send_Buf; DMA_SetCurrDataCounter(DMA1_Channel7, len); DMA_Cmd(DMA1_Channel7, ENABLE); } 三. DMA中断和串口中断处理 void DMAChannel7_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC7)) { DMA_ClearITPendingBit(DMA1_IT_TC7); xSemaphoreGiveFromISR(s_Uart_2_Send_Lock, &xHigherPriorityTaskWoken); if(pdFALSE != xHigherPriorityTaskWoken) { /*can force a contex switch*/ } } } void USART2_IRQHandler(void) { if(RESET != USART_GetITStatus(USART2, USART_IT_IDLE)) { USART_ReceiveData(USART2);//读取数据注意:这句必须要,否则不能够清除中断标志位。 USART_ClearITPendingBit(USART2,USART_IT_IDLE); DMA_Cmd(DMA1_Channel6, DISABLE); data_len = UART_RECV_BUF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel6); DMA_SetCurrDataCounter(DMA1_Channel6, UART_RECV_BUF_SIZE); data = pvPortMalloc(data_len + sizeof(UART_DATA)); if(NULL != data) { data->sender = uart_index; data->size = data_len; memcpy(data->recv_buf, dma_recv_buff, data_len); if(pdPASS != xQueueSendFromISR(s_Uart_Recv_Queue, &data, NULL)) { /*注意错误情况的处理*/ } } DMA_Cmd(DMA1_Channel6, ENABLE); } } 其他: 如果需要使用3个串口,并且都使用DMA发送和接收,初始化和中断处理函数的重复性太大,应将相同的部分提取出来组成新的函数,以传参的方式进行处理。目前没想到很好的处理方法。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 01:19 , Processed in 0.744287 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号