当前位置: 首页 > news >正文

GD32E103CBT8-空闲中断DMA接收

1)完成GD32E103CBT8的usart0和usart1的串口空闲中断+DMA接收,并验证
代码如下:

#include "gd32e10x.h"
#include <string.h>
#include "systick.h"// 定义接收缓冲区大小
#define RX_BUFFER_SIZE  128// 接收缓冲区和相关标志
uint8_t rx_buffer[RX_BUFFER_SIZE];
uint8_t rx_data_length = 0;
uint8_t rx_complete_flag = 0;// 初始化GPIO
void gpio_config(void)
{// 使能GPIOA时钟rcu_periph_clock_enable(RCU_GPIOA);// 配置PA2为USART1_TX (复用推挽输出)gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);// 配置PA3为USART1_RX (浮空输入)gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
}// 初始化USART1
void usart_config(void)
{// 使能USART1时钟rcu_periph_clock_enable(RCU_USART1);// 配置USART1: 115200 8N1usart_deinit(USART1);usart_baudrate_set(USART1, 115200U);usart_word_length_set(USART1, USART_WL_8BIT);usart_stop_bit_set(USART1, USART_STB_1BIT);usart_parity_config(USART1, USART_PM_NONE);usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);usart_receive_config(USART1, USART_RECEIVE_ENABLE);usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);// 使能USART1空闲中断usart_interrupt_enable(USART1, USART_INT_IDLE);// 使能USART1usart_enable(USART1);
}// 初始化DMA用于USART1接收
void dma_config(void)
{// 使能DMA0时钟rcu_periph_clock_enable(RCU_DMA0);// 配置DMA0通道5 (USART1_RX)dma_deinit(DMA0, DMA_CH5);dma_parameter_struct dma_init_struct;dma_struct_para_init(&dma_init_struct);dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;  // 外设到内存dma_init_struct.memory_addr = (uint32_t)rx_buffer;     // 内存地址dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;// 内存地址自增dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;  // 内存数据宽度8位dma_init_struct.number = RX_BUFFER_SIZE;               // 传输数量dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART1); // 外设地址(USART1数据寄存器)dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;// 外设地址不自增dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;// 外设数据宽度8位dma_init_struct.priority = DMA_PRIORITY_MEDIUM;        // 中等优先级dma_init(DMA0, DMA_CH5, &dma_init_struct);// 使能DMA0通道5dma_channel_enable(DMA0, DMA_CH5);// 使能USART1 DMA接收usart_dma_receive_config(USART1, USART_DENR_ENABLE);
}// 初始化NVIC中断
void nvic_config(void)
{nvic_irq_enable(USART1_IRQn, 0, 0);  // USART1中断,优先级0
}// 初始化USART1及DMA
void usart1_dma_init(void)
{gpio_config();usart_config();dma_config();nvic_config();
}// 定义USART0接收缓冲区大小
#define USART0_RX_BUFFER_SIZE  256// USART0接收缓冲区和长度变量
uint8_t usart0_rx_buffer[USART0_RX_BUFFER_SIZE];
uint16_t usart0_rx_len = 0;
uint8_t usart0_rx_complete = 0;  // 接收完成标志
// GPIO配置
void uart0_gpio_config(void)
{rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_USART0);gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); // 将PA9初始化为:复用推挽输出、IO速率最高50MHzgpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // 将PA10初始化为:浮空输入、IO速率最高50MHz
}
// USART配置
void uart0_usart_config(void)
{// 配置USART0参数usart_deinit(USART0);usart_baudrate_set(USART0, 115200U);  // 波特率115200usart_word_length_set(USART0, USART_WL_8BIT);  // 8位数据位usart_stop_bit_set(USART0, USART_STB_1BIT);  // 1位停止位usart_parity_config(USART0, USART_PM_NONE);  // 无奇偶校验usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); // 串口0 配置为 不使能RTSusart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); // 串口0 配置为 不使能CTS	usart_receive_config(USART0, USART_RECEIVE_ENABLE);  // 使能接收usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);  // 使能发送// 使能USART0空闲中断usart_interrupt_enable(USART0, USART_INT_IDLE);// 使能USART0usart_enable(USART0);
}// DMA配置
void uart0_dma_config(void)
{rcu_periph_clock_enable(RCU_DMA0); //使能DMA0时钟dma_deinit(DMA0, DMA_CH4);    //复位DMA0通道4// 配置DMA0通道4dma_parameter_struct dma_init_struct;dma_struct_para_init(&dma_init_struct);dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;  // 外设到内存dma_init_struct.memory_addr = (uint32_t)usart0_rx_buffer;  // 内存地址dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;  // 内存地址自增dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;  // 内存数据宽度8位dma_init_struct.number = USART0_RX_BUFFER_SIZE;  // 传输数据量dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART0); // 外设地址(USART0数据寄存器)dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;  // 外设地址不自增dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;  // 外设数据宽度8位dma_init_struct.priority = DMA_PRIORITY_MEDIUM;  // 中等优先级dma_init(DMA0, DMA_CH4, &dma_init_struct);// 使能DMA0通道4传输完成中断dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF);// 使能DMA0通道4dma_channel_enable(DMA0, DMA_CH4);// 关联USART0_RX到DMA0通道4usart_dma_receive_config(USART0, USART_DENR_ENABLE);
}// 发送数据函数
void usart0_send_data(uint8_t *data, uint16_t len)
{for(uint16_t i = 0; i < len; i++){// 等待发送缓冲区为空while(usart_flag_get(USART0, USART_FLAG_TBE) == RESET);usart_data_transmit(USART0, data[i]);}// 等待发送完成while(usart_flag_get(USART0, USART_FLAG_TC) == RESET);
}// 初始化NVIC中断
void uart0_nvic_config(void)
{// 配置USART0中断nvic_irq_enable(USART0_IRQn, 1, 0);  // USART0中断,优先级0// 配置DMA0通道4中断nvic_irq_enable(DMA0_Channel4_IRQn, 2, 0);  
}// 初始化USART0及DMA
void usart0_dma_init(void)
{uart0_gpio_config();uart0_usart_config();uart0_dma_config();uart0_nvic_config();
}// 发送一个字节
void usart_send_byte(uint8_t data)
{while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));usart_data_transmit(USART1, data);
}// 发送字符串
void usart_send_string(uint8_t *str)
{while(*str != '\0'){usart_send_byte(*str++);}
}#include "stdio.h"// 发送指定长度的数据
void usart_send_data(uint8_t *data, uint16_t length)
{//printf("rx_data_length is %d\r\n",rx_data_length);for(uint16_t i = 0; i < length; i++){usart_send_byte(data[i]);}
}// USART0中断服务函数
void USART0_IRQHandler(void)
{// 检查空闲中断标志if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)){// 清除空闲中断标志usart_data_receive(USART0);  // 读数据寄存器清除标志usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);// 禁用DMAdma_channel_disable(DMA0, DMA_CH4);// 计算接收到的数据长度usart0_rx_len = USART0_RX_BUFFER_SIZE - dma_transfer_number_get(DMA0, DMA_CH4);// 设置接收完成标志usart0_rx_complete = 1;// 重新配置DMA,准备下一次接收dma_transfer_number_config(DMA0, DMA_CH4, USART0_RX_BUFFER_SIZE);dma_channel_enable(DMA0, DMA_CH4);}
}// USART1中断服务函数
void USART1_IRQHandler(void)
{if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_IDLE)){// 清除空闲中断标志usart_data_receive(USART1);  // 读数据寄存器清除标志usart_interrupt_flag_clear(USART1, USART_INT_FLAG_IDLE);// 关闭DMA,防止干扰dma_channel_disable(DMA0, DMA_CH5);// 计算接收到的数据长度rx_data_length = RX_BUFFER_SIZE - dma_transfer_number_get(DMA0, DMA_CH5);// 设置接收完成标志rx_complete_flag = 1;// 重新配置DMA,准备下一次接收dma_transfer_number_config(DMA0, DMA_CH5, RX_BUFFER_SIZE);dma_channel_enable(DMA0, DMA_CH5);}
}// 处理UART1接收到的数据
void process_rxcvUart1_data(void)
{if(rx_complete_flag){usart_send_data(rx_buffer, rx_data_length);// 清除标志和缓冲区memset(rx_buffer, 0, RX_BUFFER_SIZE);rx_data_length = 0;rx_complete_flag = 0;}
}// 处理UART0接收到的数据
void process_rxcvUart0_data(void)
{// 检查是否有数据接收完成if(usart0_rx_complete){// 回显接收到的数据usart0_send_data(usart0_rx_buffer, usart0_rx_len);// 清除标志,重新开始接收usart0_rx_complete = 0;usart0_rx_len = 0;}
}// DMA0通道4中断服务函数
void DMA0_Channel4_IRQHandler(void)
{// 检查DMA传输完成标志if(dma_interrupt_flag_get(DMA0, DMA_CH4, DMA_INT_FLAG_FTF) != RESET){// 清除传输完成标志dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FLAG_FTF);// 禁用DMAdma_channel_disable(DMA0, DMA_CH4);// 接收到的数据长度等于缓冲区大小usart0_rx_len = USART0_RX_BUFFER_SIZE;// 设置接收完成标志usart0_rx_complete = 1;}
}int fputc(int ch, FILE *f) // 补充stdio.h文件中fputc的具体实现方式
{usart_data_transmit(USART1, (uint8_t)ch);while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));return ch;
}int main(void)
{// 初始化USART1及DMAnvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0); //配置中断向量等级为组别4usart0_dma_init();usart1_dma_init();while(1){// 处理接收到的数据process_rxcvUart0_data();process_rxcvUart1_data();}
}

测试如下
在这里插入图片描述

http://www.dtcms.com/a/404064.html

相关文章:

  • 网站在正在建设中网站建设销售秘籍
  • 建设银行 网站设置密码网站开发前端的工作内容是什么
  • 接口幂等性与限流(二)
  • Cherry Studio配置MCP服务全流程解析:让AI自动调用工具处理任务
  • clo3d代做网站电商类网站建设需要多少钱
  • 湖南省邵阳市建设局网站wordpress主题开发视频课程
  • Windows设置默认的两种实现方式:ShellExecuteEx 提权与外部进程调用对比分析
  • 班级网站建设模板下载海口专注海南网站建设
  • Linux:基本指令(一)
  • LeetCode 387 字符串中的第一个唯一字符 Swift 题解:用哈希表快速定位不重复字符
  • 面试复习题---加固技术原理
  • 小蜜蜂网站建设免费摄影网站推荐
  • 青岛网站推广哪家效果好朝阳网站
  • Linux安全机制--网络层安全机制
  • pc端与手机端网站开发的区别国内设计师个人网站欣赏
  • 抽奖机网站怎么做的不用付费的正能量软件
  • Excel——常用函数二
  • 3- 十大排序算法(基数排序、归并排序、快速排序、堆排序)
  • 数码设备存储新搭档 金士顿Select Plus存储卡
  • 好的设计师网站有哪些什么是seo营销
  • pytorch 线性回归
  • 推荐做问卷的网站产品设计方案3000字
  • 商务网站规划建设与管理试卷公众号开发信息什么意思
  • ACE无法启动,腾讯游戏反作弊器无法启动,ACE无法运行,软件无法运行,本次操作由于计算机限制而被取消、请与系统管理员联系
  • golang基础语法(四) 数组
  • 开源手机网站模板刚做的网站为什么百度搜不到
  • 云锁客户端连不上服务器处理
  • 网站建设优化服务熊掌号网站怎么显示百度名片
  • LNMP架构(分离部署)PHP与数据库交互示例
  • Git----常用指令入门