【GD32】FreeRTOS-ADC-DMA采集

2023-10-27

本文章介绍ADC多通道采集DMA进行传输,并且在任务中实时去获取数据。

一、时钟配置

分别配置GPIO、ADC、DMA时钟

static void SystemClock_Configration(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_CFGCMP);
    rcu_periph_clock_enable(RCU_PMU);
	
	rcu_periph_clock_enable(RCU_ADC);
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV2);  // 主频108M ADCCLK = PCLK2/2 = 27M
	
    rcu_periph_clock_enable(RCU_DMA);
}

二、GPIO配置

配置对应ADC通道GPIO为模拟输入模式

static void AdcGpioConfigration(void)
{
    gpio_deinit(GPIOA | GPIOB | GPIOC | GPIOD | GPIOF);
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);   
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);   
    gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0); 
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);   
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);   
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);    
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);     
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);       
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_6);   
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_7);    
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);   
    gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);       
}

三、ADC配置

static void AdcConfiguration(void)
{
    /* reset ADC */
    adc_deinit();
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_LENGTH);
    /* ADC regular channel config */
    adc_regular_channel_config(0, ADC_CHANNEL_1,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(1, ADC_CHANNEL_14, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(2, ADC_CHANNEL_8,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(3, ADC_CHANNEL_10, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(4, ADC_CHANNEL_4,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(5, ADC_CHANNEL_15, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(6, ADC_CHANNEL_5,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(7, ADC_CHANNEL_13, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(8, ADC_CHANNEL_12, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(9, ADC_CHANNEL_11, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(10, ADC_CHANNEL_6, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(11, ADC_CHANNEL_7, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(12, ADC_CHANNEL_2, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(13, ADC_CHANNEL_3, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(14, ADC_CHANNEL_9, ADC_SAMPLETIME_71POINT5);
    /* ADC external trigger enable */
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
    /* ADC external trigger source config */
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
    /* ADC SCAN & CONTINUOUS function enable */
    adc_special_function_config(ADC_SCAN_MODE, ENABLE);
    //  adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);       //auto repeat sample
    /* ADC DMA function enable */
    adc_dma_mode_enable();
    /* enable ADC interface */
    adc_enable();
    /* ADC calibration and reset calibration */
    adc_calibration_enable(); 
		/* enable ADC software trigger */
	adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
}

四、DMA配置

static void AdcDmaConfiguration(void)
{
    dma_parameter_struct dma_init_struct;
    /* initialize DMA channel0 */
    dma_deinit(DMA_CH0);
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr  = (uint32_t )adc_dma;//此处为我们定义的数组地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = ADC_LENGTH;
    dma_init_struct.periph_addr  = (uint32_t) & (ADC_RDATA);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH0, &dma_init_struct);
    /* clear DMA a channel flag */
    dma_interrupt_flag_clear(DMA_CH0, DMA_INT_FTF);
    /* channel transfer finish interrupt */
    dma_interrupt_enable(DMA_CH0, DMA_INT_FTF);
    /* configure DMA mode */
    dma_circulation_enable(DMA_CH0);//循环模式
    dma_memory_to_memory_disable(DMA_CH0);
    /* enable DMA channel0 */
    dma_channel_enable(DMA_CH0);
}
static void AdcNvicConfiguration(void) //中断等级配置
{
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
	nvic_irq_enable(DMA_Channel0_IRQn, 5, 0);
}
void DMA_Channel0_IRQHandler()
{
    if(dma_interrupt_flag_get(DMA_CH0, DMA_INT_FTF) != RESET)
    {
        dma_interrupt_flag_clear(DMA_CH0, DMA_INT_FTF);
		AdcStartSampling(); //每次传输完成后立马又软件触发采集
    }
}

五、主函数代码

#define ADC_LENGTH 15 //ADC通道数量
static uint16_t adc_dma[ADC_LENGTH];

uint16_t GetAdcValue(uint8_t channel)//获取对应通道ADC值
{
	return adc_dma[channel];
}
void AdcInitialize(void) //初始化所有ADC相关配置
{
	 SystemClock_Configration();
	 AdcGpioConfigration();
	 AdcConfiguration();
 	 AdcDmaConfiguration();
	 AdcNvicConfiguration();
}
int main(void)
{
    AdcInitialize();
	taskENTER_CRITICAL();          
	xTaskCreate(AdcDebugTask1,"AdcDebugTask1",128,NULL,1,NULL);
    taskEXIT_CRITICAL();  
    while(1)
	{    
	}
}
void AdcDebugTask1(void * pvParameters)
{
	while(1)
	{
		for(int i = 0;i < 15;i++)
		{
			arr_adc[i] = GetAdcValue(i);
		}	
	}
}

六、仿真验证

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【GD32】FreeRTOS-ADC-DMA采集 的相关文章

  • [antdv: FormModel] model is required for resetFields to work

    今天在用Vue ant的UI框架进行表单绑定的时候出现报错 Warning antdv FormModel model is required for resetFields to work 通过不断测试才发现是因为没有在表头使用 mode
  • QT ----Canvas绘图

    在使用qtwidget进行界面设计的时候 可以进直接使用gui模块内的控件或者使用QPainter自行绘制组件 但是在qml中QT只给我们提供了一个形状组件 rectangle 可以通过设置它的radius构成圆角矩形 但是 如果我们需要进

随机推荐

  • Tauri 打包

    1 第一次打包运行命令 npm run tauri build 2 可能会出现下面问题 我们需要在tauri conf json里面查找identifier这个名称 原来是com tauri dev 随便改下名字 我这里改成build了 3
  • python精彩编程200例-200G的Python初高级教程+项目实战案例源码,让你做有钱途的人才...

    2018年1月16日上午 教育部正式将人工智能 物联网 大数据处理正式划入高中新课标 这就意味着现在的学生16岁就要开始学习编程了 据统计 在所有专业级别的 39000 名开发人员中 有超过四分之一的开发人员在他们 16 岁之前就写了第一个
  • 面试官: Async是如何被JavaScript实现的

    太久没和大家见面了 因为最近业务上接了新的项目所以写文的时间被严重挤压 这篇 Async 是如何被实现的 其实断断续续已经在草稿箱里躺了很久了 终于在一个夜黑风高的周六晚上可以给他画上一个句号 引言 无论是面试过程还是日常业务开发 相信大多
  • Python 中常见的魔法方法

    什么是Python魔法方法 魔法方法是在Python的类中被双下划线前后包围的方法 如常见的 init new del 等 这些方法在类或对象进行特定的操作时会自动被调用 我们可以使用或重写这些魔法方法 给自定义的类添加各种特殊的功能来满足
  • 内网穿透代理(NPS)搭建以及使用

    与公众号同步更新公众号文章链接 内网穿透代理 NPS 搭建以及使用 部署前提需要一台公网服务器 各大云piao 获取到服务器后需要放行服务器端口 建议所有端口 ALL 新建一个NPS文件夹 mkdir NPS 进入NPS文件夹 cd NPS
  • Go语言面试题--基础语法(11)

    文章目录 1 定义一个包内 全局 字符串变量 下面语法正确的是 2 下面这段代码输出什么 3 下面这段代码输出什么 1 定义一个包内 全局 字符串变量 下面语法正确的是 A var str string B str C str D var
  • 彻底搞懂Vue中的Mixin混入(保姆级教程)

    彻底搞懂Vue中的Mixin混入 保姆级教程
  • 【IC设计】EDA palyground使用

    有时候我们在外地无法使用vivado等工具来进行Verilog编程 可以使用这个在线网站www edaplayground com 这个笔记记录一些需要注意的点 它会自动帮我们建立一个testbench sv 里面写入testbench 需
  • HTML5-画布使用教程

    1 简介画面的基本使用教程 CSS绘图和数据存储原理 橘猫吃不胖 的博客 CSDN博客
  • Python 读取txt文件每一行数据生成列表

    本意是将数据 改为如下形式 push lea push mov call mov mov pop retn mov jmp push mov mov call test jz push call add mov pop retn mov m
  • .PersistenceException: ### Error querying database.Cause: java.lang.NullPointerException

    错误 org apache ibatis io ResolverUtil Checking to see if class com wei mapper UserMapper matches criteria is assignable t
  • c++ protobuf 可能会遇到的坑

    1 发现存在内存泄露 程序退出时记得调用 google protobuf ShutdownProtobufLibrary 这里一定是在程序退出时调用 如果调用后又使用了 protobuf 会出现异常 因为protobuf 中使用构造 会有创
  • Mysql undo log

    一 基本概念 undo log有两个作用 1 为事务提供回滚 2 多版本并发控制 MVCC undo log和redo log记录物理日志不一样 它是逻辑日志 可以认为 当delete操作时 undo log记录的是insert记录 反之亦
  • 【Leetcode】1684. Count the Number of Consistent Strings

    题目地址 https leetcode com problems count the number of consistent strings 给定一个字符串 a a a和一个字符串数组 A A A 问
  • 单链表学习笔记(C语言)

    单链表学习笔记 C语言 一 说明 1 链表 所谓链表 就是用一组任意的存储单元存储线性表元素的一种数据结构 2 结构 链表的每个数据的存储都由两部分组成 1 数据元素本身 其所在的区域称为数据域 2 指向直接后继元素的指针 所在的区域称为指
  • RocketMQ消费者设置了instanceName属性后消息竟不翼而飞

    文章目录 背景 问题重现 生产者代码 消费者代码 紊乱的消费结果 原因分析 消费负载均衡 clientId怎么生成 为什么会生成相同的clientId 解决方案 方案一 不设置instanceName属性 方案二 两个消费者设置不同的ins
  • 踩坑:Python找不到指定路径的文件 最全解决方法

    数据集为ucr时间序列数据集 其中 Adiac文件夹中的文件可以通过下面的代码打开 其他文件格式与Adiac相同 且在同一个目录文件下 跑其他的文件 会出现某某文件不存在的问题 网上找了各种解决方法都尝试了 依然还是会报文件找不到错误 最后
  • 程序媛菜鸡算法题流水账之ZJU机试题

    最近考研分数线还没有正式公布 感觉自己处在危殆边缘 于是分岔路口之多令我眼花缭乱 将近八个月没有碰过IDE 机试路漫漫 且行且记忆 ZJU机试题 from NewCoder 做题顺序为通过率递减 同时推荐用C 用时真的少很多 虽然我选修过但
  • Llama-2大模型本地部署研究与应用测试

    最近在研究自然语言处理过程中 正好接触到大模型 特别是在年初chatgpt引来的一大波AIGC热潮以来 一直都想着如何利用大模型帮助企业的各项业务工作 比如智能检索 方案设计 智能推荐 智能客服 代码设计等等 总得感觉相比传统的搜索和智能化
  • 【GD32】FreeRTOS-ADC-DMA采集

    本文章介绍ADC多通道采集DMA进行传输 并且在任务中实时去获取数据 一 时钟配置 分别配置GPIO ADC DMA时钟 static void SystemClock Configration void rcu periph clock