【GD32450I-EVAL】ADC:软件触发+中断+单次转换模式

tinnu   2020-10-8 00:22 楼主

(一)ADC性能

GD32F450拥有3个ADC,每个ADC的采样速度最高可以达到2.6Mpsp,这还是在12位最高精度的条件下,如果降低精度还能更快。

 

(二)ADC概念

GD32的各种设计与国外大厂的很像:

 

1-注入组和规则组
规则组为常规转换,注入组类似于中断,中间插入一次计划外的转换


2-通道
有3个ADC,每个ADC有19路通道,每个ADC的每个通道都映射到固定的引脚,这可以在数据手册中查询到。


3-转换序列
相当于一个工作队列,序列第一位的转化完,第二位的接着,全部转化完后可以重新再转化一轮
规则组可以控制多达16个序列
注入组少一点,只能支持4个序列

 

(三)ADC与IO映射关系

每个ADC的每个通道都映射到固定的引脚

比如本次使用的PC3引脚

ADC 引脚.png

就是与ADC012三个ADC的IN13通道映射起来的,只要配置了PC3为模拟功能(AFIO),ADC任意一个使能了13通道就可以获取该引脚的模拟量值。

ADC AFIO.png 配置代码:


    // config the GPIO as analog mode, for ADC 
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);

 

(四)ADC寄存器

ADC的寄存器看上去不少,但实际上只使用规则组进行单个通道转化的时候绝大部分都是用不到的。

寄存器.png 看门狗、过采样、注入、摘要这些都不需要管。

因为转换的只有一个通道,就不需要涉及多个通道轮流转换的问题(即转换序列),因此同步相关配置也暂时无用。

 

所以需要配置的寄存器只有控制寄存器01、采样时间寄存器01、规则序列寄存器012

 

(五)ADC配置流程

如果采用最简单的单次转化的工作方式,参考手册给出了配置流程:

单次转化.png 看着有8步,实际上:

第1步是设置ADC工作方式,在单次转化中,这些相关位都是保持为0,即复位值,如果是初始化配置根本不需要理睬。

第4步是配置硬件触发方式

第5-8步都不是初始化的工作

即实际最简单初始化只需要做第2、3步

 

 

(六)初始化

1-配置RSQ:

调用函数,设置该ADC有多少个序列,这里只有一个通道需要转换,只有一个序列:

    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);

操作 ADC_RSQ0 的 RL位    规则通道序列长度    规则通道转换序列中的总的通道数目为 RL[3:0]+1。
操作 ADC_ISQ 的 TL 位    注入通道组长度    注入组总的通道数目为 IL[1:0]+1。

参数功能:

2-规则组或者注入组

3-多少个序列

 

2-配置SAMPT

设置具体哪个通道对应哪个序列

adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_15);

操作寄存器的过程比较复杂,同时操作了 ADC_RSQ2 寄存器
和操作 ADC_SAMPT1 寄存器    设置通道采样时间

函数参数功能:

/*!
    \brief      configure ADC regular channel
    \param[in]  adc_periph: ADCx,x=0,1,2
    \param[in]  rank: the regular group sequencer rank,this parameter must be between 0 to 15
    \param[in]  adc_channel: the selected ADC channel
                only one parameter can be selected which is shown as below:
      \arg        ADC_CHANNEL_x(x=0..18): ADC Channelx
    \param[in]  sample_time: the sample time value
                only one parameter can be selected which is shown as below:
      \arg        ADC_SAMPLETIME_3: 3 cycles
      \arg        ADC_SAMPLETIME_15: 15 cycles
      \arg        ADC_SAMPLETIME_28: 28 cycles
      \arg        ADC_SAMPLETIME_56: 56 cycles
      \arg        ADC_SAMPLETIME_84: 84 cycles
      \arg        ADC_SAMPLETIME_112: 112 cycles
      \arg        ADC_SAMPLETIME_144: 144 cycles
      \arg        ADC_SAMPLETIME_480: 480 cycles
    \param[out] none
    \retval     none
*/

2-第三个参数配置的通道,在规则组哪个序列

3-哪个通道

4-转换多少个时钟

 

(七)使能中断功能

ADC的所有中断都在同一个中断向量里:

中断向量.png 使能:

 

    //ADC INT
    adc_interrupt_enable(ADC0, ADC_INT_EOC);
    nvic_irq_enable(ADC_IRQn, 2U, 0U);

服务函数:

void ADC_IRQHandler(void)
{
    uint16_t i=0;
    char t_char[30] = "";
    if(adc_interrupt_flag_get(ADC0, ADC_INT_FLAG_EOC)==SET)
    {
        i = adc_regular_data_read(ADC0);

        sprintf(t_char, "adc:%x\t%f\r\n", i, (float)i/0xFFF*3.3);
        PRINTF_UART0(t_char);
        adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
    }
}

 

(八)软件启动转换

前面第五步提到,软件启动是置位 SWRCST ,这个位会硬件复位。对应库函数:

adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);

 

在主循环中调用:

1-使能ADC并校准

    // enable ADC interface 
    adc_enable(ADC0);
    // wait for ADC stability 
    delay_ms(1);
    // ADC calibration and reset calibration 
    adc_calibration_enable(ADC0);

2-主循环内

    while(1){
        delay_ms(4);
		
		if(t_ledshark >20){
			t_ledshark = 0;
			gd_eval_led_toggle(LED1);
            adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
		}
		t_ledshark++;
}

 

(九)效果

2.gif

更清晰的视频等审核之后再传

回复评论 (4)

玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2020-10-9 15:49

写的很详细!大概看了下好像使用上差不多.

默认摸鱼,再摸鱼。2022、9、28
点赞  2020-10-11 21:41

好好好

点赞  2020-10-15 09:24


补充个视频

点赞  2020-10-25 22:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复