GD32F103串口DMA收发(空闲中断 + DMA)
GD32F103串口DMA收发(空闲中断 + DMA)
此前写了一篇DMA串口收发的文章,参照的是GD官方例程,虽然实现了串口数据的传输,后面在实际项目应用时发现还是有点问题,不能完全按照预想的方式进行数据传输和处理,经过不断的调试,现更新如下,特此记录。
GD32F103串口DMA收发(空闲中断 + DMA)
1. 串口IO初始化
这次使用的是GD32F103CBT6串口2,对应Pin脚PB10、PB11。
代码如下:
uint8_t rxbuffer[84];
uint8_t txbuffer[84] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};#define USART0_DATA_ADDRESS ((uint32_t)&USART_DATA(USART0))
#define USART2_DATA_ADDRESS ((uint32_t)&USART_DATA(USART2))static void usart_config(uint32_t baudval)
{//USART0rcu_periph_clock_enable(RCU_GPIOA); //enable GPIO clock, PA9/PA10rcu_periph_clock_enable(RCU_AF);rcu_periph_clock_enable(RCU_USART0); //enable USART clockgpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); //PA9--TX0gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10); //PA10--RX0usart_deinit(USART0);usart_baudrate_set(USART0, baudval);usart_word_length_set(USART0, USART_WL_8BIT);usart_stop_bit_set(USART0, USART_STB_1BIT);usart_parity_config(USART0, USART_PM_NONE);usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);usart_receive_config(USART0, USART_RECEIVE_ENABLE);usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);usart_enable(USART0);//USART2rcu_periph_clock_enable(RCU_GPIOB); //enable GPIO clock, PB10/PA11rcu_periph_clock_enable(RCU_AF);rcu_periph_clock_enable(RCU_USART2); //enable USART2 clockgpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);//USART2_TXgpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);//USART2_RXusart_deinit(USART2);usart_baudrate_set(USART2, baudval);usart_word_length_set(USART2, USART_WL_8BIT);usart_stop_bit_set(USART2, USART_STB_1BIT);usart_parity_config(USART2, USART_PM_NONE);usart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE);usart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE);usart_receive_config(USART2, USART_RECEIVE_ENABLE);usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);usart_enable(USART2);
}
2. DMA初始化
代码如下:
static void usart_dma_config(void)
{dma_parameter_struct dma_init_struct;/* enable DMA0 clock */rcu_periph_clock_enable(RCU_DMA0);/* deinitialize DMA channel1(USART2 tx) */dma_deinit(DMA0, DMA_CH1);dma_struct_para_init(&dma_init_struct);dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;dma_init_struct.memory_addr = NULL;dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;dma_init_struct.number = ARRAYNUM(txbuffer);dma_init_struct.periph_addr = USART2_DATA_ADDRESS;dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;dma_init(DMA0, DMA_CH1, &dma_init_struct);/* deinitialize DMA channel2 (USART2 rx) */dma_deinit(DMA0, DMA_CH2);dma_struct_para_init(&dma_init_struct);dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;dma_init_struct.memory_addr = (uint32_t)rxbuffer;dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;dma_init_struct.number = ARRAYNUM(rxbuffer); dma_init_struct.periph_addr = USART2_DATA_ADDRESS;dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;dma_init_struct.memory_width = DMA_PERIPHERAL_WIDTH_8BIT;dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;dma_init(DMA0, DMA_CH2, &dma_init_struct);/* configure DMA mode */dma_circulation_disable(DMA0, DMA_CH1);dma_memory_to_memory_disable(DMA0, DMA_CH1);
// dma_circulation_enable(DMA0, DMA_CH2); // 使用接收空闲中断,是否循环没有关系dma_circulation_disable(DMA0, DMA_CH2);dma_memory_to_memory_disable(DMA0, DMA_CH2);/* USART DMA0 enable for reception */usart_dma_receive_config(USART2, USART_DENR_ENABLE);/* enable DMA0 channel2 transfer complete interrupt */dma_interrupt_enable(DMA0, DMA_CH2, DMA_INT_FTF);/* enable DMA0 channel2 */dma_channel_enable(DMA0, DMA_CH2);/* USART DMA0 enable for transmission */usart_dma_transmit_config(USART0, USART_DENT_ENABLE);/* enable DMA0 channel1 transfer complete interrupt */
// dma_interrupt_enable(DMA0, DMA_CH3, DMA_INT_FTF);
// /* disable DMA0 channel1 */dma_channel_disable(DMA0, DMA_CH1);
}
3. 中断配置
代码如下:
static void nvic_config(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE3_SUB1);
// nvic_irq_enable(DMA0_Channel1_IRQn, 0, 0);nvic_irq_enable(USART2_IRQn,1,0);usart_interrupt_enable(USART2, USART_INT_FLAG_IDLE);
// nvic_irq_enable(DMA0_Channel2_IRQn, 0, 1);
}
4. 串口初始化
代码如下:
void bsp_usart_init()
{ memset(rxbuffer,0xff,sizeof(rxbuffer));usart_config(BAUDRATE);nvic_config();usart_dma_config();
}
5. 串口发送函数和printf支持实现
代码如下:
void usart2_dma_send(uint8_t *buffer,uint16_t len)
{dma_channel_disable(DMA0, DMA_CH1);dma_memory_address_config(DMA0, DMA_CH1,(uint32_t)buffer);//设置要发送数据的内存地址dma_transfer_number_config(DMA0, DMA_CH1, len);//一共发送多少个数据dma_channel_enable(DMA0, DMA_CH1);
}int fputc(int ch, FILE *f)
{usart_data_transmit(USART2, (uint8_t)ch);while(RESET == usart_flag_get(USART2, USART_FLAG_TBE));return ch;
}
6. 头文件中的宏定义和函数声明如下
代码如下:
#define BAUDRATE 115200U
#define ARRAYNUM(arr_name) (uint32_t)(sizeof(arr_name) / sizeof(*(arr_name)))void bsp_usart_init(void);
void usart2_dma_send(uint8_t *buffer,uint16_t len);
int fputc(int ch, FILE *f);
7. 中断处理
代码如下:
void USART2_IRQHandler(void)
{if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){usart_data_receive(USART2); dma_channel_disable(DMA0, DMA_CH2);/************************接收数据处理函数************************/ dma_transfer_number_config(DMA0, DMA_CH2, 84);dma_channel_enable(DMA0, DMA_CH2);}
}
总结
GD32F103串口DMA收发(空闲中断 + DMA)
GD32F103串口DMA收发(空闲中断 + DMA)相关推荐
- stm32的rxne和idle中断_STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA
历程详解 详解包括: 中断原理讲解 例程流程详解 库函数分析详解 对应寄存器介绍 对应函数介绍 对应注释详解 本篇文章提供两种方法: 一种是 :IDLE 接收空闲中断+DMA 一种是: IDLE 接收 ...
- STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA
关于DMA原理部分讲解,及CubeMx配置部分,请参考该文章 [STM32]HAL库 STM32CubeMX教程十一-DMA (串口DMA发送接收) 本篇文章我们仅针对例程进行详解剖析 历程详解 详解 ...
- 华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑
华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑 华大HC32F460串口空闲中断+DMA收发配置,记录一下自己遇到的坑 注:个人笔记,如有错误,还望谅解. STM32 在STM ...
- 【无标题】STM32F767串口空闲中断+DMA实现不定帧长度的接收
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.配置串口与DMA 二.空闲中断服务函数 二.串口+DMA发送 三.主函数 总结 前言 提示:这里可以添加本文要记录 ...
- STM32CubeMX—串口空闲中断+DMA接收
一.串口中断通信 串口中断方式的特点 发送数据时,将一字节数据放入数据寄存器DR:接收数据时,将DR的内容存放到用户存储区: 中断方式不必等待数据的传输过程,只需要在每字节数据收发完成后,由中断标志位 ...
- STM32单片机串口空闲中断+DMA接收不定长数据
在上一篇文章STM32单片机串口空闲中断接收不定长数据中介绍了利用串口空闲中断接收不定长数据,这种方式有一个问题就是串口每接收到一个字节就会进入一次中断,如果发送的数据比较频繁,那么串口中断就会不停打 ...
- stm32LL库串口空闲中断+DMA接收
stm32LL库串口空闲中断+DMA接收 俺用的STM32F407VGT6,cubemx生成的代码. cubemx的串口配置 这里就按默认参数配就行,主要是要打开后面的DMA 在这里点添加就完事了,如 ...
- GD32F303RET6 串口空闲中断+DMA数据发送接收+环形缓冲区方式保存数据
GD32F303RET6 DMA 通道映射关系 串口 源文件 #include "uart.h" #include "stdio.h" #include &qu ...
- MM32F3277空闲中断+DMA接收不定长数据
摘要:在实际项目中经常用到串口接收一些不定长的数据,怎么判断这一帧数据接收完成了呢?通常使用UART非空中断配合简单的数据协议,在数据中加入帧头.帧尾,在程序中判断是否接收到帧尾来确定数据接收完毕,对 ...
- GD32F303调试小记(一)之USART(接收中断、接收空闲中断+DMA、发送DMA)
前言 之前写了GD32F103调试小记(二)之USART(接收中断.接收空闲中断+DMA.发送DMA)一文.这次我们来看看GD32F303的USART是如何配置的,结合这两篇文章,相信大家GD32的U ...
最新文章
- Xcode代码文件模板
- Linux内核探讨-- 第六章
- hdu1561 树形dp
- iOS 汉字转拼音 PinYin4Objc
- 如何修改CSDN博客的标题?
- 百万数据报表导出:需求以及思路分析
- C++11 for区间遍历:vector几种遍历方式
- flutter 返回指定界面_Flutter页面路由导航及传参
- 打印并输出 log/日志到文件(C++)
- android开发自定义选择器,创建自定义android选择器
- 深入浅出学Spring Data JPA
- 【2020.11.16】堆栈传参、堆栈平衡
- web版ppt制作插件impress.js源码注释翻译
- 批量重命名文件夹中的文件(python)
- 某互联网大厂亿级大数据服务平台的建设和实践
- 交换字符使得字符串相同
- python自带库zlib_python中的zlib解压
- 计算机excel怎么添加实线边框,excel中单元格输入内容怎么设置自动加上实线边框...
- # 我的家乡--永平风景
- 和亚马逊Amazon进行跨境电商业务,需要接入EDI吗?