[新品上市]

【APM32F107VCT6 MINI开发板测评】之ADC

[复制链接]
196|0
手机看帖
扫描二维码
随时随地手机跟帖
woai32lala|  楼主 | 2023-3-18 22:25 | 显示全部楼层 |阅读模式
本帖最后由 woai32lala 于 2023-3-18 22:26 编辑

【APM32F107VCT6 MINI开发板测评】之ADC
引言与说明
为了将生活中的温度、压力、光强、声音模拟信号送入数字设备进行处理,必须先将模拟信号转换为相对应的数字信号。能够将连续变化的模拟信号转换为离散的数字信号的器件就为模数转换器。对于MCU来说,ADC已成为MCU不可缺少的外设。

ADC介绍
我们测评的这款AMP32F107VCT6,它的ADC资源如下。
图片3.png
从上图来看,AMP32F107VCT6的ADC资源是非常丰富的。
下面我们用例程ADC_MultiChannelScan来测试一下它的的多路ADC采集,之前F003系列,ADC管脚经过SWD引脚,在进行多路ADC采集的时候,在线仿真会卡死,不能实时显示采集数据,F107系列的ADC管脚没有经过SWD引脚,理论上来说应该可以实时显示,那就让我们来测试一下。
通过数据手册我们可以看到,PA0 - PA5分别对应着ADC12的IN0- IN5,下面我们就进行这几路的多路ADC采集操作。
图片1.png 参考电压为3.3V
参谋电压.png

本例程的功能是多路ADC使用DMA采集,并且将采集的到的数据转换为电压通过串口1输出。

串口初始化
<font face="宋体">USART_Config_T USART_ConfigStruct;
   
    /* USART config */
    USART_ConfigStruct.baudRate = 115200;
    USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
    USART_ConfigStruct.mode = USART_MODE_TX;
    USART_ConfigStruct.parity = USART_PARITY_NONE;
    USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
    USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;

    APM_MINI_COMInit(COM1, &USART_ConfigStruct);</font>
DMA初始化
<font face="宋体">void DMA_Init(void)
{
    DMA_Config_T dmaConfig;

    /* Enable DMA Clock */
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);

    /* DMA config */
    dmaConfig.peripheralBaseAddr = ADC_DR_ADDR;
    dmaConfig.memoryBaseAddr = (uint32_t)&adcData;
    dmaConfig.dir = DMA_DIR_PERIPHERAL_SRC;
    dmaConfig.bufferSize = ADC_CH_SIZE;
    dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
    dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;
    dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;
    dmaConfig.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;
    dmaConfig.loopMode = DMA_MODE_CIRCULAR;
    dmaConfig.priority = DMA_PRIORITY_HIGH;
    dmaConfig.M2M = DMA_M2MEN_DISABLE;
   
    /* Enable DMA channel */
    DMA_Config(DMA1_Channel1, &dmaConfig);
   
    /* Enable DMA */
    DMA_Enable(DMA1_Channel1);
}

</font>

ADC初始化
* [url=home.php?mod=space&uid=247401]@brief[/url]     ADC Init
*
* @param     None
*
* @retval    None
*/
void ADC_Init(void)
{
    GPIO_Config_T           gpioConfig;
    ADC_Config_T            adcConfig;

    /* Enable GPIOA clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);

    /* ADC channel 0 configuration */
    GPIO_ConfigStructInit(&gpioConfig);
    gpioConfig.mode    = GPIO_MODE_ANALOG;
    gpioConfig.pin     = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3| GPIO_PIN_4| GPIO_PIN_5;
    GPIO_Config(GPIOA, &gpioConfig);

    /* Enable ADC clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);

    /* ADC configuration */
    ADC_Reset(ADC1);

    ADC_ConfigStructInit(&adcConfig);
    adcConfig.mode                  = ADC_MODE_INDEPENDENT;
    adcConfig.scanConvMode          = ENABLE;
    adcConfig.continuosConvMode     = ENABLE;
    adcConfig.externalTrigConv      = ADC_EXT_TRIG_CONV_None;
    adcConfig.dataAlign             = ADC_DATA_ALIGN_RIGHT;
    /* channel number */
    adcConfig.nbrOfChannel          = ADC_CH_SIZE;
    ADC_Config(ADC1, &adcConfig);
   
    /* ADCCLK = PCLK2/4 */
    RCM_ConfigADCCLK(RCM_PCLK2_DIV_4);

    /* ADC channel Convert configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_13CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_1, 2, ADC_SAMPLETIME_13CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_2, 3, ADC_SAMPLETIME_13CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_3, 4, ADC_SAMPLETIME_13CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_4, 5, ADC_SAMPLETIME_13CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_5, 6, ADC_SAMPLETIME_13CYCLES5);


    /* Config DMA */
    DMA_Init();

    /* Enable ADC DMA */
    ADC_EnableDMA(ADC1);

    /* Enable ADC */
    ADC_Enable(ADC1);

    /* Enable ADC1 reset calibration register */
    ADC_ResetCalibration(ADC1);
    /* Check the end of ADC1 reset calibration register */
    while(ADC_ReadResetCalibrationStatus(ADC1));

    /* Start ADC1 calibration */
    ADC_StartCalibration(ADC1);
    /* Check the end of ADC1 calibration */
    while(ADC_ReadCalibrationStartFlag(ADC1));

    /* Start ADC1 Software Conversion */
    ADC_EnableSoftwareStartConv(ADC1);
}</font>
ADC电压转换
void ADC1_Isr(void)
{
    uint16_t adcData = 0;
    uint16_t voltage = 0;
   
    if (ADC_ReadIntFlag(ADC1, ADC_INT_EOC) == SET)
    {
        ADC_ClearIntFlag(ADC1, ADC_INT_EOC);
        /* Read ADC Conversion value */
        adcData = ADC_ReadConversionValue(ADC1);
        /* voltage(mV) = adcData * (3300mV / 4095) */
        voltage = (adcData * 3300) / 4095;
        printf("\r\n voltage : %d mV\r\n", voltage);
    }
}

接线 接线.jpg
我们用的PA0 - PA5 6个引脚
PA0 接GND、PA1悬空、PA2接VCC、PA3接GND、PA4和PA5悬空。通过在线仿真发现,PA0接GND可以得到0左右,PA2接GND数值在十几往上,PA2接VCC是4095,我感到疑惑的是PA3接GND的问题为什么不等于0,而且数据跳动还挺大的。
图片2.png
串口输出ADC转换电压
同样PA3接地,仍然后10mv左右的电压
图片4.png
但看原理图,PA3是接在串口2上,串口2并没有用,这样PA3还是接在GND上,所以不知道这个跳动从哪来的,希望官方看一下这个数据。 图片5.png
以上就是对ADC多路采集的测评,疑惑的问题就是在PA3管脚采集电压上,如有问题。请指教。











使用特权

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

本版积分规则

102

主题

497

帖子

5

粉丝