野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14634|回复: 2

同步规则多通道ADC+DMA

[复制链接]
发表于 2018-7-10 00:59:25 | 显示全部楼层 |阅读模式
本帖最后由 wx_NkGPU381 于 2018-7-10 01:02 编辑

采用ADC1和ADC2两个同步规则,ADC1用PC1、PC2两个通道 ,ADC2用PC3、PC5两个通道,1和3通过电位器采集电压,2和5悬空。  1、2两个通道没问题,但是3、5两个通道采集到的值会相互影响,3通道经过转换后电压为0V时5通道为1V左右,3通道经过转换后电压为3.3V时5通道为2V左右,这是为什么?这么做才能没影响


下面是代码:
        (ADC.h文件)
#ifndef __ADC_H
#define __ADC_H
#include "stm32f10x.h"

#define ADC_1_CHANNEL1                 ADC_Channel_11
#define ADC_1_CHANNEL2                 ADC_Channel_12
#define ADC_2_CHANNEL1                 ADC_Channel_13
#define ADC_2_CHANNEL2                 ADC_Channel_15
#define ADC_DMA_CHANNEL   DMA1_Channel1

static void ADCx_GPIO_Config(void);
static void DMA_Mode_Config(void);
static void ADC_Mode_Config(void);

void ADCx_Init2(void);

#endif


      (ADC.c文件)
#include "ADC.h"

__IO uint32_t Voltage[2]={0,0};

static void ADCx_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        
        // ADCx_1 GPIO 初始化
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOC, &GPIO_InitStructure);


        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

        // ADCx_2 GPIO 初始化        
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
}

static void DMA_Mode_Config(void)
{
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        DMA_DeInit(DMA1_Channel1);        
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&( ADC1->DR ));        
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Voltage;        
        DMA_InitStructure.DMA_BufferSize = 2;        
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;        
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;        
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);
        DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);
        
}

static void ADC_Mode_Config(void)
{
        ADC_InitTypeDef ADC_InitStructure;        
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_ADC1, ENABLE );
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_ADC2, ENABLE );
        
        // 双ADC的规则同步
        ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;        
        // 扫描模式
        ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
        // 连续转换模式
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
        // 不用外部触发转换,软件开启即可
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
        // 转换结果右对齐
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        
        // 转换通道个数
        ADC_InitStructure.ADC_NbrOfChannel = 2;                        
        // 初始化ADC
        ADC_Init(ADC1, &ADC_InitStructure);        
        // 配置ADC时钟PCLK2的8分频,即9MHz
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);         
        // 配置ADC 通道的转换顺序和采样时间
        ADC_RegularChannelConfig(ADC1, ADC_1_CHANNEL1, 1, ADC_SampleTime_239Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_1_CHANNEL2, 2, ADC_SampleTime_239Cycles5);        
        
        ADC_DMACmd(ADC1, ENABLE);
        
        
        
        // 双ADC的规则同步
        ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;        
        // 扫描模式
        ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
        // 连续转换模式
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
        // 不用外部触发转换,软件开启即可
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
        // 转换结果右对齐
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        
        // 转换通道个数
        ADC_InitStructure.ADC_NbrOfChannel = 2;                        
        // 初始化ADC
        ADC_Init(ADC2, &ADC_InitStructure);        
        // 配置ADC时钟为PCLK2的8分频,即9MHz
        RCC_ADCCLKConfig(RCC_PCLK2_Div8);         
        // 配置ADC 通道的转换顺序和采样时间
        ADC_RegularChannelConfig(ADC2, ADC_2_CHANNEL1, 1, ADC_SampleTime_239Cycles5);
        ADC_RegularChannelConfig(ADC2, ADC_2_CHANNEL2, 2, ADC_SampleTime_239Cycles5);
        
        ADC_ExternalTrigConvCmd(ADC2, ENABLE);
        
        ADC_Cmd(ADC1, ENABLE);        
        
        // 初始化ADC 校准寄存器
        ADC_ResetCalibration(ADC1);
        // 等待校准寄存器初始化完成
        while(ADC_GetResetCalibrationStatus(ADC1));        
        // ADC开始校准
        ADC_StartCalibration(ADC1);
        // 等待校准完成
        while(ADC_GetCalibrationStatus(ADC1));
        
        ADC_Cmd(ADC2, ENABLE);        
        // 初始化ADC 校准寄存器  
        ADC_ResetCalibration(ADC2);
        // 等待校准寄存器初始化完成
        while(ADC_GetResetCalibrationStatus(ADC2));        
        // ADC开始校准
        ADC_StartCalibration(ADC2);
        // 等待校准完成
        while(ADC_GetCalibrationStatus(ADC2));
        
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
        
}

void ADCx_Init2(void)
{
        ADCx_GPIO_Config();
        DMA_Mode_Config();
        ADC_Mode_Config();
}



        (main.c文件)

#include "stm32f10x.h"
#include "ADC.h"
#include "bsp_usart.h"
#include "delay.h"


extern __IO uint32_t Voltage[2];
__IO float RealVoltage[4]={0,0,0,0};



int main(void)
{


                uint32_t temp0=0 ,temp1=0,temp2=0,temp3=0;
                USART_Config();
                ADCx_Init2();
                printf("\r\n ----这是一个双ADC多通道规则同步+DMA采集实验----\r\n");
                printf("开始ADC转换\n");
               
                while (1)
        {        
    // 取出ADC1数据寄存器的高16位,这个是ADC2的转换数据
                temp0 = (Voltage[0]&0XFFFF0000) >> 16;
                // 取出ADC1数据寄存器的低16位,这个是ADC1的转换数据
                temp1 = (Voltage[0]&0XFFFF);        
                temp2 = (Voltage[1]&0XFFFF0000) >> 16;
                temp3 = (Voltage[1]&0XFFFF);
                RealVoltage[0] =(float) temp0/4096*3.3;
                RealVoltage[1] =(float) temp1/4096*3.3;
                RealVoltage[2] =(float) temp2/4096*3.3;
                RealVoltage[3] =(float) temp3/4096*3.3;
               
                printf("\r\n ADCx_1 value1 = %f V \r\n",RealVoltage[1]);
                printf("\r\n ADCx_2 value1 = %f V \r\n",RealVoltage[0]);
                printf("\r\n ADCx_1 value2 = %f V \r\n",RealVoltage[3]);
                printf("\r\n ADCx_2 value2 = %f V \r\n",RealVoltage[2]);
               
                printf("\r\n\r\n");
                SysTick_Delay_Ms(4000,Use_72M);  //延时4秒而已
                 
        }
        
}






回复

使用道具 举报

发表于 2018-7-10 08:40:34 | 显示全部楼层
看看板子上的这两个引脚是不是接到其它芯片了
回复 支持 反对

使用道具 举报

发表于 2019-1-15 15:18:24 | 显示全部楼层
楼主是不是感觉多加的两个通道值并没有读取到
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 05:35 , Processed in 0.029214 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表