扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

GD32 ADC应用——DMA传输,定时器触发使用方法

2025/11/13
3458
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前言:一般在使用ADC的时候都是采用软件启动转换,软件查询转换结果的方式,本文聊聊使用外部信号触发转换,转换完成后DMA搬运数据到内存,软件在需要的地方,仅需从内存中读取转换结果的方式来实现ADC转换。

1、引脚

硬件设计上必须按照手册要求,外部通道为标有ADCx_INxx的引脚可用于采样。

void adc_pin_init(void)    {     rcu_periph_clock_enable(RCU_GPIOA); gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);  rcu_periph_clock_enable(RCU_GPIOB);   gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0); }

2、ADC外设初始化

void gd32_adc_init(void) {    /* 时钟配置 */    rcu_periph_clock_enable(RCU_ADC0);    /* 重置ADC */    adc_deinit();    /* 时钟配置 */    adc_clock_config(ADC_ADCCK_PCLK2_DIV4);//最大40M    /* ADC模式配置 */    adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);    /* ADC连续转换功能配置 */    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);    /* ADC扫描模式配置 */    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);    /* ADC数据对齐配置 */    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);    /* ADC数据对齐配置 */    adc_resolution_config(ADC0, ADC_RESOLUTION_12B);    /* 使能17通道 */    adc_channel_16_to_18(ADC_TEMP_VREF_CHANNEL_SWITCH, ENABLE);    /* ADC通道长度配置 */    adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, 5);/* ADC通道组配置 */adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_6, ADC_SAMPLETIME_56);    adc_routine_channel_config(ADC0, 1, ADC_CHANNEL_8, ADC_SAMPLETIME_56);    adc_routine_channel_config(ADC0, 2, ADC_CHANNEL_4, ADC_SAMPLETIME_56);    adc_routine_channel_config(ADC0, 3, ADC_CHANNEL_5, ADC_SAMPLETIME_56);    adc_routine_channel_config(ADC0, 4, ADC_CHANNEL_17, ADC_SAMPLETIME_56);    /* ADC外部触发配置 */adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T1_TRGO);//触发源选择定时器1的TRGO信号    adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_RISING);/* ADC DMA使能*/    adc_dma_mode_enable(ADC0);    adc_dma_request_after_last_enable(ADC_DEV);  //关键    /* 使能ADC接口 */    adc_enable(ADC0);    /* 短暂延时,确保ADC稳定 */    gd32_delay_ms(20);    /* ADC校准 */    adc_calibration_enable(ADC0);}

 3、DMA请求与配置

void gd32_adc_dma_init(void) {    dma_single_data_parameter_struct dma_init_struct;    rcu_periph_clock_enable(RCU_DMA1);    dma_deinit(DMA1, DMA_CH4);    dma_init_struct.direction           = DMA_PERIPH_TO_MEMORY;    dma_init_struct.memory0_addr        = (uint32_t)ntc_val;    dma_init_struct.memory_inc          = DMA_MEMORY_INCREASE_ENABLE;    dma_init_struct.number              = 5 * sizeof(uint16_t);    dma_init_struct.periph_addr         = (uint32_t)(&ADC_RDATA(ADC_DEV));    dma_init_struct.periph_inc          = DMA_PERIPH_INCREASE_DISABLE;    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;    dma_init_struct.priority            = DMA_PRIORITY_ULTRA_HIGH;    dma_init_struct.circular_mode       = DMA_CIRCULAR_MODE_ENABLE;    dma_single_data_mode_init(DMA1, DMA_CH4, &dma_init_struct);    dma_channel_subperipheral_select(DMA1, DMA_CH4, DMA_SUBPERI0);    dma_channel_enable(DMA1, DMA_CH4);}

代码中选择DMA1的外设0、通道4来转运ADC转换结构,转运方向为从寄存器到内存。

4、外部触发信号

void gd32_time_init(void){    timer_parameter_struct para;    rcu_periph_clock_enable(RCU_TIMER1);    timer_deinit(TIMER1);    /* 参数 */    timer_struct_para_init(&para);    para.alignedmode       = TIMER_COUNTER_EDGE;    para.counterdirection  = TIMER_COUNTER_UP;    para.clockdivision     = TIMER_CKDIV_DIV1;    para.repetitioncounter = 0U;    para.prescaler         = (1200 - 1) & 0x0ffff;    para.period            = (100 - 1) & 0x0ffff;  //定时器频率120M/(1200*100)=1KHZ    /* 配置 */    timer_init(TIMER1, &para);    timer_update_event_enable(TIMER1);    timer_auto_reload_shadow_enable(TIMER1);    timer_master_output_trigger_source_select(TIMER1, TIMER_TRI_OUT_SRC_UPDATE);  //关键,产生TRGO信号    timer_enable(TIMER1);}

代码中选择使用定时器1的TRGO信号触发,ADC转换。

5、应用程序中循环读取结果

void adc_volt(void){    float vref=1.2f;    float volt=0;    vref = 1.2f * 4096.0f / adc_val[4];//使用17通道校准外部参考电压    for (uint8_t i = 0; i < 4; i++) {	volt = adc_val[i] * vref / 4096.0f;        dbg_info("volt %d =%.2f rn", i,volt);    }    //定时器触发了转换,因此只需要读取即可    gd32_delay_ms(1000);}

通过以上代码,就实现了高效ADC转换。

兆易创新

兆易创新

兆易创新科技集团股份有限公司(股票代码603986)是全球领先的Fabless芯片供应商,公司成立于2005年4月,总部设于中国北京,在全球多个国家和地区设有分支机构,营销网络遍布全球,提供优质便捷的本地化支持服务。兆易创新致力于构建以存储器、微控制器、传感器、模拟产品为核心驱动力的完整生态,为工业、汽车、计算、消费电子、物联网、移动应用以及通信领域的客户提供完善的产品技术和服务,已通过ISO26262:2018汽车功能安全最高等级ASIL D体系认证,并获得IEC 61508功能安全产品认证以及ISO 9001、ISO 14001、ISO 45001等体系认证和邓白氏认证。同时,公司与多家世界知名晶圆厂、封装测试厂建立战略合作伙伴关系,共同推进半导体领域的技术创新。欲了解更多信息,请访问:www.GigaDevice.com

兆易创新科技集团股份有限公司(股票代码603986)是全球领先的Fabless芯片供应商,公司成立于2005年4月,总部设于中国北京,在全球多个国家和地区设有分支机构,营销网络遍布全球,提供优质便捷的本地化支持服务。兆易创新致力于构建以存储器、微控制器、传感器、模拟产品为核心驱动力的完整生态,为工业、汽车、计算、消费电子、物联网、移动应用以及通信领域的客户提供完善的产品技术和服务,已通过ISO26262:2018汽车功能安全最高等级ASIL D体系认证,并获得IEC 61508功能安全产品认证以及ISO 9001、ISO 14001、ISO 45001等体系认证和邓白氏认证。同时,公司与多家世界知名晶圆厂、封装测试厂建立战略合作伙伴关系,共同推进半导体领域的技术创新。欲了解更多信息,请访问:www.GigaDevice.com收起

查看更多

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

公众号:物联网思考;主要记录、分享、思考开发中遇到的技术小细节,涉及嵌入式单片机、C语言、传感器、低功耗物联网等。偶尔也可能是程序员健康、职场潜规则、生活思考、行业讨论。