STM32
直播中

笑尽往事

9年用户 878经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

STM32F407三重ADC配置过程是怎样的?

STM32F407三重ADC配置过程是怎样的?

回帖(1)

蔡艳

2021-11-23 10:04:48
#include "adc.h"
#include "stm32f4xx.h"
__IO uint16_t ADC_ConvertValue[3]={10,10,10};//定义一个数组存储数字电压,ADC_ConvertValue[0]存储ADC1的数据,ADC_ConvertValue[1]存储ADC2的数据
//一定要配置为16位的数据,因为每一次传输的数据都是16位半字的
                                                                  
                                                                  
//ADC引脚功能配置-----PB组的引脚存在问题,具体我也不太清楚为什么
static void ADC_GPIO_Config(void)
{
          GPIO_InitTypeDef  GPIO_InitStructure;
          //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟--对应PB1
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟--对应PA5
          //PA1-ADC1_CH1
          GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不上下拉
          GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
               
          //PA6-ADC2_CH6
          GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不上下拉
          GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化


         //PA0-ADC3_CH0
          GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不上下拉
          GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
}








//ADC模式配置
static void ADC_Mode_Config(void)
{
        /********DMA配置********/
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//开启DMA2时钟,ADC的DMA通道都在DMA2下,查DMA表,在中文参考手册里面
//        DMA_DeInit(DMA2_Stream0);//重置DMA2的流2,在多重ADC模式下,只要配置ADC1的流就行,因为ADC1是主ADC
        DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)ADC_CDR_ADDR;//外设基地址:CDR寄存器
        DMA_InitStructure.DMA_Memory0BaseAddr=(u32)ADC_ConvertValue;//存储器基地址,注意一定要是32位的,其它位数的则必须转换一下
        DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;//数据传输方向,外设到存储器
        DMA_InitStructure.DMA_BufferSize=3;//一次传输数据的量,因为我使用的是ADC的DMA模式1,所以每次都是只传输1个数据
        DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址不递增
        DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器地址递增
        DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//外设传输数据的宽度,16位,半字,2字节
        DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//存储器的数据大小也要和外设一样,在使用FIFO模式时可以不一样
        DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//DMA模式,这里选择循环传输
        DMA_InitStructure.DMA_Priority=DMA_Priority_High;//DMA传输通道优先级设置,因为只使用了一个DMA通道,所以不用管优先级
       
        //以下是DMA的FIFO功能配置,是不需要的,所以失能,其它配置不用管
        DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;//未使用FIFO模式,所以不使能
        DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull;
        DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;
        DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
       
        DMA_InitStructure.DMA_Channel=DMA_Channel_0;//DMA的通道选择,因为ADC1使用DMA2,数据流0,通道0,这个是手册固定死的
       
        DMA_Init(DMA2_Stream0,&DMA_InitStructure);//初始化DMA所有参数
        DMA_Cmd(DMA2_Stream0,ENABLE);//使能DMA流,此后DMA可用
       
       
        /************ADC配置***********/
        ADC_InitTypeDef ADC_InitStructure;
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC1的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);//开启ADC2的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);//开启ADC3的时钟
       
        RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);    // ADC1复位
    RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);   // 复位结束


    RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC2, ENABLE);    // ADC2复位
    RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC2, DISABLE);   // 复位结束


        //----------------------ADC Common结构体初始化-------------------------------------
        ADC_CommonInitStructure.ADC_Mode=ADC_TripleMode_RegSimult;//ADC模式,三重ADC规则同步模式
        ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//ADC时钟分频:4分频
        ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_1;//ADC的DMA传输模式1,参考中文参考手册可知
        ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//两个ADC采样时间间隔,,交替模式才有效
       
        ADC_CommonInit(&ADC_CommonInitStructure);//初始化ADC通用参数部分
       
       
        //-----------------------ADC Init结构体初始化-------------------------------
        ADC_StructInit(&ADC_InitStructure);//初始化一遍ADC_InitStructure,使其有原始值
        ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//ADC分辨率,使用12位分辨率,最大值是4096
        ADC_InitStructure.ADC_ScanConvMode=DISABLE;//不使用ADC通道扫描模式,因为每个ADC只有一个通道参与转换
        ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//开启连续转换模式
        ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不是使用外部边沿触发
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部触发通道选择。因为使用了软件触发,这个选项随便选就行
        ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//对齐方式选择右对齐
        ADC_InitStructure.ADC_NbrOfConversion=1;//转换通道数目,每个ADC只有1个
       
       
        //ADC1的结构体初始化
        ADC_Init(ADC1,&ADC_InitStructure);
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_3Cycles);//配置ADC1,通道8,通道转换顺序1,采样时间为3个时钟周期
       
        //ADC2的结构体初始化
        ADC_Init(ADC2,&ADC_InitStructure);
        ADC_RegularChannelConfig(ADC2,ADC_Channel_6,1,ADC_SampleTime_3Cycles);//配置ADC2,通道9,通道转换顺序1,采样时间为3个时钟周期
       
        //ADC3的结构体初始化
        ADC_Init(ADC3,&ADC_InitStructure);
        ADC_RegularChannelConfig(ADC3,ADC_Channel_0,1,ADC_SampleTime_3Cycles);//配置ADC2,通道9,通道转换顺序1,采样时间为3个时钟周期
       
       
        ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);//使能多重ADC模式下的DMA传输请求after last transfer (multi-ADC mode)
        ADC_DMACmd(ADC1,ENABLE);//使能ADC1的DMA功能
       
       
        ADC_Cmd(ADC1,ENABLE);//使能ADC1
        ADC_Cmd(ADC2,ENABLE);//使能ADC2
        ADC_Cmd(ADC3,ENABLE);//使能ADC3
       
        ADC_SoftwareStartConv(ADC1);//软件触发开始转换,只用触发ADC1即可,ADC23自动打开
       
       
       
}






void MY_ADC_Init(void)
{
        ADC_GPIO_Config();
        ADC_Mode_Config();
}
遇到的问题描述:
三重ADC,单通道采样,规则同时。
ADC1-CH1,ADC2-CH6,ADC3-CH0
出现的问题:
初次用三重ADC时,选用的是PB引脚做ADC的输入,但是发现数据非常乱,完全不符合实际数据,出现了两个电压数据完全相同、一个电压数据为0无变化的情况,以为是DMA和ADC在配置的时候错误,没有配置正确,但是对照网上的例子和野火、正点原子的例程发现配置是不应该有问题的,于是我选择换一个引脚组进行配置,PA组,更换之后数据开始正确采集,也没有错误,迷一样的问题呀
举报

更多回帖

发帖
×
20
完善资料,
赚取积分