1930|8

95

帖子

0

资源

一粒金砂(中级)

[GD32F310评测]ADC的配置和使用 [复制链接]

循着上一次的设置,我们需要完成ADC的端口的初始化和调试准备。

修改外设配置函数

添加ADC的初始化函数,基本步骤完成GPIO的设置,完成ADC的排序器设计(之后实现),进行ADC使能和adc的校准。

引脚编号 引脚名称 端口分类 引脚复用 复用分类 说明
6 PA0-WKUP I/O ADC_IN0 ADC *I DC bus
7 PA1 I/O ADC_IN1 ADC *Uu
8 PA2 I/O ADC_IN2 ADC Uv
9 PA3 I/O ADC_IN3 ADC Uw
10 PA4 I/O ADC_IN4 ADC Iu
11 PA5 I/O ADC_IN5 ADC Iv
12 PA6 I/O ADC_IN6 ADC Iw

备注:目前仅考虑电流采样,因为电压采样接口存在冲突。

修改之后的测试用外设配置函数为:

 #define _ADC_TEST
 ​
 uint16_t adc_i[3]; // ADC result for current.
 dma_parameter_struct dma_adc;
 ​
 void peripheral_init()
 {
     // RCU:
     rcu_periph_clock_enable(RCU_GPIOA);  // GPIO A
     rcu_periph_clock_enable(RCU_CFGCMP); // CFGCMP clock
     rcu_periph_clock_enable(RCU_ADC);    // ADC
      rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
     rcu_periph_clock_enable(RCU_DMA); // DMA
     
     // System tick
     systick_config();
     
     // GPIO config
     gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0); // Input Key
     gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);  // Output Key
     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_1);
     gpio_bit_reset(GPIOA, GPIO_PIN_1);
     
     // NVIC - EXTI
     nvic_irq_enable(EXTI0_1_IRQn, 2U, 0U); // GPIO A0 -> EXTI 0
     syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0); // GPIO A0 Interrupt enable
     exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING); 
     exti_interrupt_flag_clear(EXTI_0);
     
     // ADC GPIO
     gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_4); // Iu
     gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_5); // Iv
     gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_6); // Iw
     
     // ADC channel config
     adc_channel_length_config(ADC_REGULAR_CHANNEL, 3);
     adc_regular_channel_config(0,ADC_CHANNEL_4,ADC_SAMPLETIME_1POINT5); // 1.5 cycle
     adc_regular_channel_config(1,ADC_CHANNEL_5,ADC_SAMPLETIME_1POINT5); // 1.5
     adc_regular_channel_config(2,ADC_CHANNEL_6,ADC_SAMPLETIME_1POINT5); // 1.5
     
     adc_data_alignment_config(ADC_DATAALIGN_RIGHT); // Right align
     adc_resolution_config(ADC_RESOLUTION_12B);
     
     adc_special_function_config(ADC_SCAN_MODE,ENABLE); // Scan mode
     adc_dma_mode_enable(); // Setup dma mode
     adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
     
 #ifdef _ADC_TEST
     // Case I: for now, the timer has not setup. So just test ADC
     adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_NONE); // software trigger FOR DEBUG
 ​
 #else
     // Case II: If Timer has been setup
     adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_T1_CH1); 
     // NOTE: Three channel of Timer0 is setup for generate PWM, so T1 may be a reasonable solution.
     //       This part may be changed, during debugging process.
 #endif
 ​
     // DMA for ADC
     dma_struct_para_init(&dma_adc);
     dma_adc.periph_addr = ADC_BASE;
     dma_adc.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; // 2 byte(s)
     dma_adc.memory_addr = (uint32_t)adc_i;
     dma_adc.memory_width = DMA_MEMORY_WIDTH_16BIT;
     dma_adc.memory_inc = (uint8_t)DMA_MEMORY_INCREASE_ENABLE;
     dma_adc.number = 3;
     dma_adc.priority = (uint32_t)DMA_PRIORITY_HIGH;
     
     dma_circulation_enable(DMA_CH0); // ADC DMA setup
     dma_init(DMA_CH0, &dma_adc); // inti DMA for ADC(1)
     dma_periph_address_config(DMA_CH0,ADC_BASE);
     dma_transfer_direction_config(DMA_CH0,DMA_PERIPHERAL_TO_MEMORY);
     dma_channel_enable(DMA_CH0);
     
     // ADC setup
     adc_enable();
     delay_1ms(10);
     adc_calibration_enable(); // calibration
     
 #ifdef _ADC_TEST
     // This only for ADC debug.
     adc_software_trigger_enable(ADC_REGULAR_CHANNEL); // First time read ADC
 #endif
 }
 ​
 ​

采样方法

为了实现采样,我们应当尝试扫描转换模式,在引脚定义章节我们已经计划需要读取7个通道的ADC信息。在数据手册11.4.5节介绍的“扫描转换模式”,其驱动时序如下图所示:

image-20220522093833550-16531835181481.png  

理论上电机驱动过程中应当关注采样的时间点,在11.4节给出了ADC的模块框图如下:

image-20220522095303030-16531843849602.png  

在10.4.10节给出了触发信号的规则:

规则通道的触发

ETSRC[2:0] 触发源
000 TIMER0_CH0
001 TIMER0_CH1
010 TIMER0_CH2
011 TIMER1_CH1
100 TIMER2_TRGO
101 TIMER14_CH0
110 EXTI_11(外部通道输入)
111 SWRCST(软件触发)

注入通道的触发

 

ETSIC[2:0] 触发源
000 TIMER0_TRGO
001 TIMER0_CH3
010 TIMER1_TRGO
011 TIMER1_CH0
100 TIMER2_CH3
101 TIMER14_TRGO
110 EXTI_15(外部通道输入)
111 SWRCST(软件触发)

对于芯片ADC的使用有如下注意事项,需要注意,否则可能导致ADC并未正常启动:

  • 时钟使能(ADC,ADC总线时钟分频器,DMA时钟)

  • ADC需要用到的GPIO通道复用

  • 配置排序器(rank)

  • 配置数据长度和数据对齐方式

  • 启用扫描模式和DMA

  • 允许外部触发,并选择外部触发源(为了测试通常选用软件触发源)

  • 配置ADC的DMA通道,我们此处使用了通道0,注意外设地址是ADC_BASE而不是要读取的目标位置RDATA

  • 启用ADC并进行ADC校准

  • 通过软件源触发ADC转换(测试用)

这一部分的代码已经从上面的初始化代码中得到了体现。

实际应用场景

在ADC的实际应用中,实际上是为了采集电机的反电动势和电机的电流,它们配置的关键如下:

  • 电流采样

对于电流采样为了规避开关信号的冲击,应当在下溢中断发生的时候开始转换。而Timer0通常设置为中间对齐模式,下溢出中断可以通过TIMER0_TRGO来选择。找张网图来说明一下位置关系。

image-20220522194308121.png  

  • 电压采样

电压采样应当在三相桥关断的情况下进行,此时可以读取到电机的反电动势,但是此时可以暂不做考虑,无论是在实际电机的驱动中,或者是在仿真中,由于电压是由发生器(脉冲)给定的,所以可以直接用调制值来代替采样值。目前局限于时间问题,考虑对于直流电机的驱动,暂且也不考虑。

ADC测试代码中可以使用软件触发来实现ADC的读取,可以通过如下测试代码实现:

     while(adc_flag_get(ADC_FLAG_EOC) != SET); // pending until convertion cmpt.
     while(dma_flag_get(DMA_CH0,DMA_FLAG_FTF) != SET); // pending until DMA transfer cmpt.
      // read ADC result here.
     
     delay_1ms(1); // break point here.
     
 #ifdef _ADC_TEST
     // This only for ADC debug.
     adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
 #endif

将这一段代码加入到项目中即可实现ADC测试效果。上图中标记出了可以通过全局变量监测的方式读取ADC的位置。

image-20220522214945817.png  

总结,GD32的手感总体还是相当棒的,由于之前被ST养出了懒病还没有改好,导致实际的调试过程异常痛苦。时长出现忘记使能时钟、忘记打开标志位的情况,不过后来简单看了看上古时期自己的笔记,加上慢慢熟悉整个系统之后,调试还是比较容易的。

此帖出自GD32 MCU论坛

回复

2601

帖子

3

资源

版主

写了这么长的帖子,辛苦了!建议出一些实际应用的例程,这样效果会好些。

点评

谢谢,这个和之前是一整套,等之后也许会形成一套体系吧  详情 回复 发表于 2022-5-25 00:17

回复

2325

帖子

0

资源

版主

感谢分享,这个ADC的采用率和精度如何?

点评

目前还没有直观感受,主要是这个东西不是PCB集中采样,都是用杜邦线跳线的话精度应该也不成参考  详情 回复 发表于 2022-5-25 00:17

回复

95

帖子

0

资源

一粒金砂(中级)

wangerxian 发表于 2022-5-24 18:54 感谢分享,这个ADC的采用率和精度如何?

目前还没有直观感受,主要是这个东西不是PCB集中采样,都是用杜邦线跳线的话精度应该也不成参考


回复

95

帖子

0

资源

一粒金砂(中级)

lugl4313820 发表于 2022-5-24 10:10 写了这么长的帖子,辛苦了!建议出一些实际应用的例程,这样效果会好些。

谢谢,这个和之前是一整套,等之后也许会形成一套体系吧


回复

2546

帖子

2

资源

五彩晶圆(初级)

辛苦楼主能不能做个“串口中断USART_INT_IDLE”的实验

点评

这个可能还不在我这次主题的范围之内,我可以之后仔细看看,了解一下,感谢您的建议!  详情 回复 发表于 2022-6-5 21:26

回复

9

帖子

0

资源

一粒金砂(中级)

受教了!好有创意,俺作为学生党很喜欢,在实践过程中受益匪浅

点评

加油呀!  详情 回复 发表于 2022-6-5 21:25

回复

95

帖子

0

资源

一粒金砂(中级)

Neeooc 发表于 2022-6-4 21:30 受教了!好有创意,俺作为学生党很喜欢,在实践过程中受益匪浅

加油呀!


回复

95

帖子

0

资源

一粒金砂(中级)

bigbat 发表于 2022-6-2 11:41 辛苦楼主能不能做个“串口中断USART_INT_IDLE”的实验

这个可能还不在我这次主题的范围之内,我可以之后仔细看看,了解一下,感谢您的建议!


回复
您需要登录后才可以回帖 登录 | 注册

相关帖子
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
    推荐帖子
    用线性光耦设计一个隔离系统时,要求达到隔离强度1800伏,设计的时候要考虑哪些

    请各位大佬指点一下,谢谢!

    TI工业月第三季——参考设计亮点抢先看

    TI工业月第三季——参考设计亮点抢先看 三次抽奖机会~快来~ 点击进入活动 活动时间:即日起&m ...

    MicroPython动手做(25)——语音合成与语音识别

    本帖最后由 eagler8 于 2020-5-22 06:57 编辑 1、TTS(Text-To-Speech,文本到语音) TTS是Text To Speech的缩写,即“ ...

    【Perf-V评测】(总结) 一次RISC-V之旅

      通过这两月的Perf-V开发板测评活动,我从零开始学习RISC-V,以开源的蜂鸟E203 CPU及SOC为基础进行实验,也翻阅了作者的书籍 ...

    高速电路环境下的旁路电容器应用

    附件是TI的技术文档 高速电路中旁路电容的应用,本文中对旁路有明确的定义,从中可以进一步验证我之前的帖子“旁路电容的选 ...

    【平头哥RVB2601创意应用开发】开箱、开发环境CDK安装、Demo测试

    收货开箱 593131593132593133 593134 上电测试 593136593135按照指导手册安装串口驱动和CDK 开发环境CDK安装 CD ...

    关闭
    站长推荐上一条 1/7 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表