单片机
返回首页

stm32和同类单片机用ADC采集多通道信号量

2024-10-08 来源:cnblogs

在此之前,使用stm32的ADC采集信号,使用到的通道就只有一个,用的时候也是别人写好的代码,没去研究,然而最近用GD32F350单片机作一个电源板时,要采集6个通道的信号,所以就仔细看了手册,有规则通道和注入通道两个概念,按概念,规则通道是按顺序采集,注入通道可以最多设备四个,有独立的保存采集数据的寄存器。如果超过4个就不能没每个每个通道对应一个数据寄存器;如果是规则通道,当通道数大于一时是可以先设置采集通道再读数据,但是我想要的是像手册上说大的一次就把6个通道的数据采集出来,但是规则通道只有一个数据寄存器,如何知道每一次采集的数据是对应哪一个通道呢?最后问了一个做电源有经验的人,他说使用DMA,设置数据长度为6个,然后每个通道采集的的数据就按顺序存到指定的地址了,真是一语惊醒梦中人啊。看看代码吧:


void dma_config(void)

{

    dma_parameter_struct dma_init_struct;


        rcu_periph_clock_enable(RCU_DMA);

    /* initialize DMA channel0 */

    dma_deinit(DMA_CH0);

    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;

    dma_init_struct.memory_addr = (uint32_t)ad_value;//指定DMA数据空间地址

    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;

    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;

    dma_init_struct.number = 48;

    dma_init_struct.periph_addr = (uint32_t)&(ADC_RDATA);

    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;

    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;

    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;

    dma_init(DMA_CH0, dma_init_struct);

    

    /* configure DMA mode */

    dma_circulation_enable(DMA_CH0);

    dma_memory_to_memory_disable(DMA_CH0);

    

    /* enable DMA channel0 */

    dma_channel_enable(DMA_CH0);

    dma_interrupt_enable(DMA_CH0, DMA_INT_FTF);

    nvic_irq_enable(DMA_Channel0_IRQn , 0U, 0U);//配置中断优先级

}


void ADCSampleInit(void)

{


//    rcu_periph_clock_enable(RCU_GPIOB);    

//    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);

// gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);

    

    dma_config();    

    // ADCCLK = PCLK2/6

    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV4);// ADC时钟27MHz

    rcu_periph_clock_enable(RCU_ADC);

    rcu_periph_clock_enable(RCU_GPIOA);

    

    //PA2,3,4,5,6

    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE,

                                GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);

    

    // ADC channel length config 设置规则组的数量,转换扫描时按此数量扫描

    adc_channel_length_config(ADC_REGULAR_CHANNEL, 6);


    /* ADC regular channel config */

    adc_regular_channel_config(0, ADC_CHANNEL_2, ADC_SAMPLETIME_1POINT5);

    adc_regular_channel_config(1, ADC_CHANNEL_3, ADC_SAMPLETIME_1POINT5);

    adc_regular_channel_config(2, ADC_CHANNEL_4, ADC_SAMPLETIME_1POINT5);

    adc_regular_channel_config(3, ADC_CHANNEL_5, ADC_SAMPLETIME_1POINT5);

    adc_regular_channel_config(4, ADC_CHANNEL_6, ADC_SAMPLETIME_1POINT5);

    //Vrefin

    adc_regular_channel_config(5, ADC_CHANNEL_17, ADC_SAMPLETIME_13POINT5);//ADC_SAMPLETIME_13POINT5 1515 //ADC_SAMPLETIME_28POINT5 1462

    //adc_regular_channel_config(5, ADC_CHANNEL_16, ADC_SAMPLETIME_13POINT5);

    // Vrefin enable

    adc_tempsensor_vrefint_enable();

    /* ADC external trigger enable */

    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

    /* ADC external trigger source config */

    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);

        

    /* ADC data alignment config */

    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);//数据为右对齐

    /* enable ADC interface */

    adc_enable();

    /* ADC calibration and reset calibration */

    adc_calibration_enable();

    /* ADC SCAN function enable */

    adc_special_function_config(ADC_SCAN_MODE, ENABLE);//使能扫描模式

    /* ADC continuous mode function enable */        

    adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE); //连续模式

    /* ADC DMA function enable */

    adc_dma_mode_enable();//使用ADC DMA, ADC的数据将会存入DMA模块中,这是定义的DMA数据空间为ad_value[]

    

    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);// 软件出发一次采样


原来就这个简单。

这里还要注意一个问题,就是采样时间,采样时间越短,输入的阻抗越小,这是如果你的信号是经过电阻分压后接入单片机的,那输入阻抗会改变电路设计上的分压比例,这时就要通过测量校准实际的比例值,比如电压经过300k+200K的电阻接到地,从两个电阻中间取信号,按电阻比例算分压比例是2/(3+2)=0.4,但若设置采样时间为1.5T,实际测出的比例是0.3355。


另一个是基准电压问题,如果VDDA不怎么稳定,会导致调试代码是容易中断,还有就是采集到的信号和实际偏差很大,这是可以通过采集弹片内部1.2V基准电压Vrefin得到的值反推出实际的VDDA的值,即实际采样值Vin=1.2xVrefinADC/VrefinADC.


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章