GD32H7xx_ADC模拟配置问题

8 篇文章 0 订阅
1 篇文章 0 订阅

      GD32H7系列是兆易创新推出的新一代高性能MCU,基于ARM cortex-M7内核,主频高达600M。在使用该产品的时候,我们发现有几个引脚:PA0_C,PA1_C,PC2_C,PC3_C不太一样,这些引脚和PA0,PA1,PC2,PC3有什么区别和联系呢,下面我们来测试一下。

      先看看用户手册GPIO章节关于ADC模拟配置的描述,文中说PA0_C,PA1_C,PC2_C,PC3_C是直接连到ADC的模拟输入端,Pxy_C和Pxy之间是通过模拟开关直接相连,开关的默认状态取决于SYSCFG_PMCFG寄存器中PxySWON位的复位值,那复位值究竟是0还是1呢。

 

       根据手册上对于PxySWON位的描述,0是关闭模拟开关,1是打开模拟开关(引脚断开),因为开发板上有PC2_C引脚,不妨以PC2和PC2_C来测试较为方便。

       先进行程序设计,参考GD样例程序ADC0_TIMER_trigger_inserted_channel,这个样例程序和我们要测试的功能比较接近,稍加改动即可。两个通道ADC2_IN12(PC2),  ADC2_IN0(PC2_C),ADC注入组长度改为2,timer1比较事件触发ADC转换,ADC中断服务程序中读取转换结果。

      1.时钟配置 

void rcu_config(void)
{
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOC);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC2);
    /* enable trigsel clock */
    rcu_periph_clock_enable(RCU_TRIGSEL);
    /* enable timer1 clock */
    rcu_periph_clock_enable(RCU_TIMER1);
    rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
}

      2. GPIO 初始化,只配置PC2即可,PC2_C不需要进行模式配置。

void gpio_config(void)
{
	   gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE,GPIO_PIN_2);
}

      3. 定时器配置为5KHz,占空比为40%的PWM波,上升沿触发ADC转换

void timer_config(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    /* TIMER1 configuration */
    timer_initpara.prescaler         = 59999;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 9999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1, &timer_initpara);

    /* CH0 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 3999);
    timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);
  timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
}

      4. ADC2配置

void adc_config(void)
{
    /* reset ADC */
    adc_deinit(ADC2);
    /* ADC clock config */
    adc_clock_config(ADC2, ADC_CLK_SYNC_HCLK_DIV6);
    /* ADC contineous function enable */
    adc_special_function_config(ADC2, ADC_CONTINUOUS_MODE, DISABLE);
    /* ADC scan mode enable */
    adc_special_function_config(ADC2, ADC_SCAN_MODE, ENABLE);
    /* ADC resolution config */
    adc_resolution_config(ADC2, ADC_RESOLUTION_12B);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC2, ADC_DATAALIGN_RIGHT);

	 /* ADC channel length config */
    adc_channel_length_config(ADC2, ADC_INSERTED_CHANNEL, 2);
	
	  adc_inserted_channel_config(ADC2, 0, ADC_CHANNEL_0, 240);
	  adc_inserted_channel_config(ADC2, 1, ADC_CHANNEL_12, 240);
 
    /* ADC trigger config */
   adc_external_trigger_config(ADC2, ADC_INSERTED_CHANNEL, EXTERNAL_TRIGGER_RISING);
    /* clear the ADC flag */
    adc_interrupt_flag_clear(ADC2, ADC_INT_FLAG_EOC);
    adc_interrupt_flag_clear(ADC2, ADC_INT_FLAG_EOIC);
    /* enable ADC interrupt */
    adc_interrupt_enable(ADC2, ADC_INT_EOIC);

    /* enable ADC interface */
    adc_enable(ADC2);
    /* wait for ADC stability */
    delay_1ms(1);
    /* ADC calibration mode config */
    adc_calibration_mode_config(ADC2, ADC_CALIBRATION_OFFSET_MISMATCH);
    /* ADC calibration number config */
    adc_calibration_number(ADC2, ADC_CALIBRATION_NUM1);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC2);
}

      5. ADC2触发源选择

void trigsel_config(void)
{
    trigsel_init(TRIGSEL_OUTPUT_ADC2_INSTRG, TRIGSEL_INPUT_TIMER1_CH1);
}

      6.  ADC2中断优先级初始化

void nvic_config(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
	  nvic_irq_enable(ADC2_IRQn, 1, 1);
}

      7.  ADC2中断服务程序

void ADC2_IRQHandler(void)
{
    /* clear the ADC flag */
    adc_interrupt_flag_clear(ADC2, ADC_INT_FLAG_EOIC);
    /* read ADC inserted group data register */
    inserted_data[0] = adc_inserted_data_read(ADC2, ADC_INSERTED_CHANNEL_0);
    inserted_data[1] = adc_inserted_data_read(ADC2, ADC_INSERTED_CHANNEL_1);
}

    8.  串口输出ADC转换结果

while(1) {
        delay_1ms(3000);
        printf("\r\n ADC2 inserted channel 0 data = %d \r\n", inserted_data[0]);
        printf("\r\n ADC2 inserted channel 1 data = %d \r\n", inserted_data[1]);
        printf("\r\n ***********************************\r\n");
    }

       编译下载完程序后,先用万用表测量PC2和PC2_C两个引脚电压,PC2接近3.28V,PC2_C为1.82V左右,调节开发板上的电位器VR1,PC2_C的电压会跟着变化,PC2电压不变,说明在复位状态下PC2和PC2_C是处于断开状态。

       串口显示如下:

       在GPIO初始化中加入函数syscfg_analog_switch_disable(),也就是置PxySWON位为0。

void gpio_config(void)
{
	   gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE,GPIO_PIN_2);
	   syscfg_analog_switch_disable(SYSCFG_PC2_ANALOG_SWITCH);
}
void syscfg_analog_switch_disable(uint32_t gpio_answ)
{
    SYSCFG_PMCFG &= (uint32_t)(~gpio_answ);
}

      编译下载运行,再用万用表测量PC2和PC2_C两个引脚电压,两个引脚电压比较接近,PC2为1.92V,PC2_C为1.86V,说明模拟开关处于关闭状态。

串口输出显示:

         综上所述,复位状态下,PxySWON位为1,模拟开关处于断开状态,和手册上讲的复位值为0,有点出入。

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值