打印

GD32F103单片机 ADC的同步采样(并行和交错)

[复制链接]
25|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、ADC 同步功能
       GD32F103 片上集成了 12 位逐次逼近式模数转换器模块(ADC),可以采样来自于 16 个外部通道 和 2 个内部通道上的模拟信号。这 18 个 ADC 采样通道都支持多种运行模式,采样转换后,转 换结果可以按照最低有效位对齐或最高有效位对齐的方式保存在相应的数据寄存器中。
        在有多个ADC模块的产品中,可以使用ADC同步模式。在ADC同步模式下,根据ADC_CTL0寄 存器中SYNCM[3:0]位所选的模式,转换的启动可以是ADC0和ADC1的交替触发或同步触发。 在同步模式下,当配置由外部事件触发的转换时,ADC0必须通过软件来配置触发来,从而避 免错误的触发引起不必要的转换。此外,对于ADC0和ADC1的外部触发必须被使能。(注意:在ADC同步模式下,即使DMA不用,也要将DMA置位,ADC1的转换数据可以通过ADC0数据 寄存器读取 )。
       GD32F103 ADC同步模式主要包括:独立模式、规则并行模式、规则快速交错模式和规则慢速交错模式四种。
[backcolor=var(--bg3)]
                                                    同步模式


二、独立模式
       在这种模式下,每个 ADC 都独立工作,互不干扰。该模式也是应用较简单的一种。这里主要以其他三种为主进行介绍。
三、规则并行模式
     此模式可并行转换常规序列,外部触发来源于 ADC0 常规序列触发(由 ADC_CTL1 寄存器的 ETSRC[2:0]决定),ADC1 常规序列配置为软件触发模式。 在 ADC0 或 ADC1 的转换事件结束时,即 ADC0 或 ADC1 的常规序列转换完毕,会产生一个 EOC 中断(如果某个 ADC 中断使能)。 32 位 ADC_RDATA 寄存器( [15: 0]位域用于保存 ADC0 常规通道采样数据,[31: 16]位域用 于保存 ADC1 常规通道采样数据),32 位的 DMA 被用来将 ADC_RDATA 中的数据传送到 SRAM。
注意:
1.若两个 ADC 模块使用了相同的采样通道,应保证不在同一时间使用该通道。
2.两个 ADC 在同一时刻采样的两个通道,应该配置相同的采样时间。
规则并行模式如下图所示
[backcolor=var(--bg3)]

规则并行模式
规则并行模式配置代码如下:
#include "adc.h"#include "systick.h"u32 reg_pal_data[4={0};void adc_set(void){        //结构体实例化        dma_parameter_struct dma_structure;        timer_parameter_struct timer_structure;        timer_oc_parameter_struct oc_structure;                 //使能时钟        rcu_periph_clock_enable(RCU_GPIOA);        rcu_periph_clock_enable(RCU_ADC0);        rcu_periph_clock_enable(RCU_ADC1);        rcu_periph_clock_enable(RCU_TIMER1);        rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12);        rcu_periph_clock_enable(RCU_DMA0);                //配置GPIO        gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_4);        gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_5);        gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_6);        gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_7);                //配置ADC0        adc_mode_config(ADC_DAUL_REGULAL_PARALLEL);        adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);        adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,4);        adc_regular_channel_config(ADC0,0,ADC_CHANNEL_4,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC0,1,ADC_CHANNEL_5,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC0,2,ADC_CHANNEL_6,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC0,3,ADC_CHANNEL_7,ADC_SAMPLETIME_55POINT5);        adc_external_trigger_source_config(ADC0,ADC_REGULAR_CHANNEL,ADC0_1_EXTTRIG_REGULAR_T1_CH1);        adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,ENABLE);                //配置ADC1        adc_data_alignment_config(ADC1,ADC_DATAALIGN_RIGHT);        adc_regular_channel_config(ADC1,0,ADC_CHANNEL_7,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC1,1,ADC_CHANNEL_6,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC1,2,ADC_CHANNEL_5,ADC_SAMPLETIME_55POINT5);        adc_regular_channel_config(ADC1,3,ADC_CHANNEL_4,ADC_SAMPLETIME_55POINT5);        adc_external_trigger_source_config(ADC1,ADC_REGULAR_CHANNEL,ADC0_1_2_EXTTRIG_REGULAR_NONE);        adc_external_trigger_config(ADC1,ADC_REGULAR_CHANNEL,ENABLE);                //配置定时器1通道1触发        timer_structure.alignedmode=TIMER_COUNTER_EDGE;        timer_structure.clockdivision=TIMER_CKDIV_DIV1;        timer_structure.counterdirection=TIMER_COUNTER_UP;        timer_structure.period=10000-1;        timer_structure.prescaler=12-1;        timer_structure.repetitioncounter=0;        timer_init(TIMER1,&timer_structure);                oc_structure.ocpolarity=TIMER_OC_POLARITY_HIGH;        oc_structure.outputstate=TIMER_CCX_ENABLE;        timer_channel_output_config(TIMER1,TIMER_CH_1,&oc_structure);        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,4000-1);        timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);        timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,DISABLE);                //配置DMA        dma_structure.direction=DMA_PERIPHERAL_TO_MEMORY;        dma_structure.memory_addr=(u32)reg_pal_data;        dma_structure.memory_inc=DMA_MEMORY_INCREASE_ENABLE;        dma_structure.memory_width=DMA_MEMORY_WIDTH_32BIT;        dma_structure.number=4;        dma_structure.periph_addr=ADC0+0x4c;        dma_structure.periph_inc=DMA_PERIPH_INCREASE_DISABLE;        dma_structure.periph_width=DMA_PERIPHERAL_WIDTH_32BIT;        dma_structure.priority=DMA_PRIORITY_ULTRA_HIGH;        dma_init(DMA0,DMA_CH0,&dma_structure);        dma_circulation_enable(DMA0,DMA_CH0);        dma_channel_enable(DMA0,DMA_CH0);                timer_enable(TIMER1);                //使能并校准ADC0        adc_enable(ADC0);        delay_ms(10);        adc_calibration_enable(ADC0);                //使能并校准ADC1        adc_enable(ADC1);        delay_ms(10);        adc_calibration_enable(ADC1);                //使能ADC0 DMA        adc_dma_mode_enable(ADC0);}
四、规则快速交错模式
快速交叉模式适用于两个 ADC 的常规序列采样同一个通道,,外部触发来源于 ADC0 常规序 列(由 ADC_CTL1 寄存器的 ETSRC[2:0]决定)。当触发产生时,ADC1 立刻启动,而 ADC0 在 7 个 ADC 时钟周期后启动。 如果 ADC0 和 ADC1 的 CTN 位被置位,所选的常规序列在两个 ADC 中被不停的转换。 32 位 ADC_RDATA 寄存器([15: 0]位域用于保存 ADC0 常规通道采样数据,[31: 16]位域用于 保存 ADC1 常规通道采样数据)。在 ADC0 产生 EOC 中断后(可通过置位 EOCIE 位),可通 过 32 位 DMA 将 ADC_RDATA 中数据传送到 SRAM。
注意:两个 ADC 模块常规通道的采样时间都应小于 7 个 ADC 时钟周期。
[backcolor=var(--bg3)]

规则快速交错模式
规则快速交错模式配置程序如下:
#include "adc.h"#include "systick.h"u32 reg_pal_data=0;void adc_set(void){        //结构体实例化        dma_parameter_struct dma_structure;        timer_parameter_struct timer_structure;        timer_oc_parameter_struct oc_structure;                 //使能时钟        rcu_periph_clock_enable(RCU_GPIOB);        rcu_periph_clock_enable(RCU_ADC0);        rcu_periph_clock_enable(RCU_ADC1);        rcu_periph_clock_enable(RCU_TIMER1);        rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12);        rcu_periph_clock_enable(RCU_DMA0);                //配置GPIO端口        gpio_init(GPIOB,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_0);        //配置模式为快速交错模式        adc_mode_config(ADC_DAUL_REGULAL_FOLLOWUP_FAST);                //配置ADC0        adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);        adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,4);        adc_regular_channel_config(ADC0,0,ADC_CHANNEL_8,ADC_SAMPLETIME_1POINT5);//小于7个采样时钟周期        adc_external_trigger_source_config(ADC0,ADC_REGULAR_CHANNEL,ADC0_1_EXTTRIG_REGULAR_T1_CH1);        adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,ENABLE);                //配置ADC1        adc_data_alignment_config(ADC1,ADC_DATAALIGN_RIGHT);        adc_regular_channel_config(ADC1,0,ADC_CHANNEL_8,ADC_SAMPLETIME_1POINT5);//小于7个采样时钟周期        adc_external_trigger_source_config(ADC1,ADC_REGULAR_CHANNEL,ADC0_1_2_EXTTRIG_REGULAR_NONE);        adc_external_trigger_config(ADC1,ADC_REGULAR_CHANNEL,ENABLE);                //配置定时器1通道1触发ADC转换        timer_structure.alignedmode=TIMER_COUNTER_EDGE;        timer_structure.clockdivision=TIMER_CKDIV_DIV1;        timer_structure.counterdirection=TIMER_COUNTER_UP;        timer_structure.period=10000-1;        timer_structure.prescaler=12-1;        timer_structure.repetitioncounter=0;        timer_init(TIMER1,&timer_structure);                oc_structure.ocpolarity=TIMER_OC_POLARITY_HIGH;        oc_structure.outputstate=TIMER_CCX_ENABLE;        timer_channel_output_config(TIMER1,TIMER_CH_1,&oc_structure);        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,4000-1);        timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);        timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,DISABLE);                //配置DMA        dma_structure.direction=DMA_PERIPHERAL_TO_MEMORY;        dma_structure.memory_addr=(u32)(&reg_pal_data);        dma_structure.memory_inc=DMA_MEMORY_INCREASE_ENABLE;        dma_structure.memory_width=DMA_MEMORY_WIDTH_32BIT;        dma_structure.number=1;        dma_structure.periph_addr=ADC0+0x4c;        dma_structure.periph_inc=DMA_PERIPH_INCREASE_DISABLE;        dma_structure.periph_width=DMA_PERIPHERAL_WIDTH_32BIT;        dma_structure.priority=DMA_PRIORITY_ULTRA_HIGH;        dma_init(DMA0,DMA_CH0,&dma_structure);        dma_circulation_enable(DMA0,DMA_CH0);        dma_channel_enable(DMA0,DMA_CH0);                timer_enable(TIMER1);                //校准并使能ADC        adc_enable(ADC0);        delay_ms(10);        adc_calibration_enable(ADC0);                adc_enable(ADC1);        delay_ms(10);        adc_calibration_enable(ADC1);                //使能ADC的DMA功能        adc_dma_mode_enable(ADC0);}
五、规则慢速交错模式
此模式应用于两个 ADC 的常规序列(通常一个常规通道),外部触发来源于 ADC0 常规序列 (由 ADC_CTL1 寄存器的 ETSRC[2:0]决定)。当触发产生时,ADC1 立刻启动,而 ADC0 在 14 个 ADC 时钟周期后启动,在 ADC0 启动后的 14 个时钟周期,ADC1 再次启动。 在这种模式下,不能使用连续转换模式,因为在这种模式下所选的常规通道在两个 ADC 中被 不停的转换。 32 位 ADC_RDATA 寄存器([15: 0]位域用于保存 ADC0 常规通道采样数据,[31: 16]位域用于 保存 ADC1 常规通道采样数据)。在 ADC0 产生 EOC 中断后(可通过置位 EOCIE 位),可通 过 32 位 DMA 将 ADC_RDATA 中数据传送到 SRAM。
注意:可允许的最大采样时间必须小于 14 个 CK_ADC 采样时钟,从而避免 ADC0 和 ADC1 在转换相同通道时出现采样时钟重叠。
[backcolor=var(--bg3)]

慢速交错功能

68355673ee1562e6f6.png (35.03 KB )

68355673ee1562e6f6.png

53431673ee15de06c3.png (35.03 KB )

53431673ee15de06c3.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

969

主题

2978

帖子

7

粉丝