STM32F407多通道采样DMA数据为0

2019-07-20 13:19发布

本帖最后由 Learning 于 2017-7-17 23:28 编辑

我想用ADC1和ADC2采样4个端口数据,并用DMA2传输。数据处理在DMA中断中完成,由于串口坏了,我用LED小灯检测是否正常。结果发现中断可以进入,但是不管我接地或者3.3,DMA返回的值一直为0(LED2常亮),反复对照例程和网上的问题也没有发现哪里错了。


下面是主程序:
float temp;
int main(void)
{   

     NVIC_SetPriorityGrouping(PRIORITY_GROUP);

     SystemInit();
     LED_Init();
     ADC_Inits();


     while(1)
     {
         MEA_StartConv();
         temp = Get_ADC_IP()*3.3/4095;
            if (temp > 3 ){
                LED3 = 0;
            }
            else
                LED3 = 1;

            if (temp < 0.5){
                LED2 = 0;
            }
            else
                LED2 = 1;
     }
     
}
下面给出我的ADC程序

    #include "ADC.h"
    #include "interrupt_priority_conf.h"
    #include "LED.h"

static uint16_t ADC1_Buf[16], ADC2_Buf[16];
static float MEA_CONV_RATIO[4] = {ADC_IP_CONV_RATIO, ADC_BUCK1_CONV_RATIO, ADC_BUCK2_CONV_RATIO, ADC_BUCK3_CONV_RATIO};
static uint16_t ADC_IP[1];
static uint16_t ADC_BUCK[4];

void ADC_Inits(void)
{
      ADC_GPIO_Init();
      ADC_DMA_Init();
}
/********************************************************************

*********************************************************************/
void ADC_GPIO_Init(void)
{

    TIM_ADC_GPIO_INIT_CLK(ADC_IP_GPIO_CLK | ADC_BUCK1_GPIO_CLK | ADC_BUCK2_GPIO_CLK | ADC_BUCK3_GPIO_CLK, ENABLE);        /* Enable ADC1 and GPIOA clock */

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;           
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;        
   
    GPIO_InitStructure.GPIO_Pin =  ADC_BUCK1_Pin;
    GPIO_Init(ADC_BUCK1_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  ADC_BUCK2_Pin;
    GPIO_Init(ADC_BUCK2_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  ADC_BUCK3_Pin;
    GPIO_Init(ADC_BUCK3_GPIO, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = ADC_IP_Pin ;
    GPIO_Init(ADC_IP_GPIO, &GPIO_InitStructure);
}
   
/********************************************************************
鍑芥暟鍚嶎柟static void ADC1_Mode_Init(void)
*********************************************************************/
void ADC_DMA_Init(void)
{

    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    FLASH_PrefetchBufferCmd(ENABLE);
    FLASH_DataCacheCmd(ENABLE);
    FLASH_InstructionCacheCmd(ENABLE);
    PWR->CR |= (uint32_t) PWR_CR_ADCDC1;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2,ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

    DMA_DeInit(MEA_ADC1_DMA_STREAM);
    DMA_DeInit(MEA_ADC2_DMA_STREAM);
    /*************************************DMA_ADC1********************************************/

        DMA_InitStructure.DMA_Channel = MEA_ADC1_DMA_CHANNEL;
        DMA_InitStructure.DMA_BufferSize = 16;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) ADC1_Buf;
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(ADC1+0x4c));
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
        DMA_Init(MEA_ADC1_DMA_STREAM, &DMA_InitStructure);
        DMA_Cmd(MEA_ADC1_DMA_STREAM, ENABLE);

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);

        NVIC_InitStructure.NVIC_IRQChannel = MEA_ADC1_DMA_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = MEA_ADC1_DMA_PREPRIO;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = MEA_ADC1_DMA_SUBPRIO;
        NVIC_Init(&NVIC_InitStructure);
        DMA_ITConfig(MEA_ADC1_DMA_STREAM, DMA_IT_TC, ENABLE);

        /*************************************DMA_ADC2********************************************/
        DMA_InitStructure.DMA_Channel = MEA_ADC2_DMA_CHANNEL;
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) ADC2_Buf;
        DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(ADC2+0x4c));
        DMA_Init(MEA_ADC2_DMA_STREAM, &DMA_InitStructure);
        DMA_Cmd(MEA_ADC2_DMA_STREAM, ENABLE);

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);


        NVIC_InitStructure.NVIC_IRQChannel = MEA_ADC2_DMA_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = MEA_ADC2_DMA_PREPRIO;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = MEA_ADC2_DMA_SUBPRIO;
        NVIC_Init(&NVIC_InitStructure);
        DMA_ITConfig(MEA_ADC2_DMA_STREAM, DMA_IT_TC, ENABLE);

        /*************************************ADC2********************************************/
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

    ADC_InitStructure.ADC_NbrOfConversion = 16;
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
   
    ADC_Init(ADC1, &ADC_InitStructure);
    ADC_Init(ADC2, &ADC_InitStructure);

    int i;
    for (i = 0; i < 8; ++i) {
    ADC_RegularChannelConfig(ADC1, ADC_IP_CHANNEL, i * 2 + 1, ADC_SampleTime_3Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_BUCK1_CHANNEL, i * 2 + 2, ADC_SampleTime_3Cycles);

    ADC_RegularChannelConfig(ADC2, ADC_BUCK2_CHANNEL, i * 2 + 1, ADC_SampleTime_3Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_BUCK3_CHANNEL, i * 2 + 2, ADC_SampleTime_3Cycles);
    }

    ADC_Cmd(ADC1, ENABLE);
    ADC_DMACmd(ADC1, ENABLE);
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
   
    ADC_Cmd(ADC2, ENABLE);
    ADC_DMACmd(ADC2, ENABLE);
    ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);

    MEA_StartConv();
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC ==RESET));
    while(ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC ==RESET));
}

/*******************************************************************
均值处理
  ***************************************************************/
void MEA_CalcAvg(uint16_t buf[16], uint16_t* ji_shu, uint16_t* ou_shu)
{
     uint16_t i, j, p, tmp;
     for(i = 0; i<4; ++i){
         p = i;
         for(j = p+2; j<16; j+=2){
             if(buf[j] > buf[p])
                 p = j;
         }
         tmp = buf;
         buf = buf[p];
         buf[p] = tmp;
     }

     for(i = 4; i<8; ++i){
         p = i;
         for(j = p+2; j<16; j+=2){
             if(buf[j] < buf[p])
                 p = j;
         }
         tmp = buf;
         buf = buf[p];
         buf[p] = tmp;
     }

     tmp = 0;
     // buf[9],[11],[13],[15]
     for(i = 9; i<16; i+=2){
         tmp += buf;
     }
     *ji_shu = (tmp+2)/4;//鍔&#65533;2闄や互4锛屽洓鑸嶄簲鍏&#65533;

     tmp = 0;
     // buf[8],[10],[12],[14]
     for(i = 8; i<16; i+=2){
         tmp += buf;
     }
     *ou_shu = (tmp+2)/4;


}
/*******************************************************************

  ***************************************************************/
static int ADC_ConvDoneFlag = 0;

void MEA_ADC1_DMA_IRQHandler()
{
     if(DMA_GetITStatus(MEA_ADC1_DMA_STREAM, MEA_ADC1_DMA_IT_TCIF)){            //濡傛灉DMA_ADC1鏁版嵁娴佷紶杈撲腑鏂?畬鎴&#65533;

         DMA_ClearITPendingBit(MEA_ADC1_DMA_STREAM, MEA_ADC1_DMA_IT_TCIF);    //娓呴櫎涓?柇鏍囧織浣&#65533;//ADC1閲囨牱鍊煎彇骞冲潎锛屽瓨鍌ㄧ粨鍒癕EA_Result[0],MEA_Result[3]
     }
    ADC_ConvDoneFlag |= 1;
    if(ADC_ConvDoneFlag == 0x03){
        MEA_CalcAvg(ADC1_Buf, &ADC_IP[0], &ADC_BUCK[1]);
        ADC_ConvDoneFlag = 0;

//        LED3 = !LED3;
    }
}

void MEA_ADC2_DMA_IRQHandler()
{
     if(DMA_GetITStatus(MEA_ADC2_DMA_STREAM, MEA_ADC2_DMA_IT_TCIF)){

         DMA_ClearITPendingBit(MEA_ADC2_DMA_STREAM, MEA_ADC2_DMA_IT_TCIF);
     }

     ADC_ConvDoneFlag |= 2;
     if(ADC_ConvDoneFlag == 0x03){
        MEA_CalcAvg(ADC2_Buf, &ADC_BUCK[2], &ADC_BUCK[3]);
         ADC_ConvDoneFlag = 0;

//        LED3 = !LED3;
     }
}



float Get_ADC_IP(void)
{
     return ADC_IP[0];
}

float Get_ADC_BUCK(int Channel)
{
    assert_param(Channel >= 0 && Channel < 4);
     return ADC_BUCK[Channel]*MEA_CONV_RATIO[Channel];
}


void MEA_StartConv(void)
{
     ADC_SoftwareStartConv(ADC1);
     ADC_SoftwareStartConv(ADC2);
     ADC_SoftwareStartConv(ADC3);

}

ADC中定义的参数:
/*
* ADC.h
*
*
*/
#ifndef ADC_H_
#define ADC_H_
#include "stm32f4xx.h"

//////////////////////////////////////////////////////////////////////////////////

#define TIM_ADC_GPIO_INIT_CLK RCC_APB1PeriphClockCmd


#define ADC_IP_GPIO_CLK                    RCC_AHB1Periph_GPIOA
#define ADC_IP_GPIO                        GPIOA
#define ADC_IP_Pin                        GPIO_Pin_0
#define ADC_IP_CHANNEL                    ADC_Channel_0
#define ADC_IP_INDEX                    0
#define ADC_IP_CONV_RATIO                20*(3.3/4095)
            

#define ADC_BUCK1_GPIO_CLK                RCC_AHB1Periph_GPIOA
#define ADC_BUCK1_GPIO                    GPIOA
#define ADC_BUCK1_Pin                    GPIO_Pin_1
#define ADC_BUCK1_CHANNEL                ADC_Channel_1
#define ADC_BUCK1_INDEX                    1
#define ADC_BUCK1_CONV_RATIO            (3.3/4095)

#define ADC_BUCK2_GPIO_CLK                RCC_AHB1Periph_GPIOA
#define ADC_BUCK2_GPIO                    GPIOA
#define ADC_BUCK2_Pin                    GPIO_Pin_2
#define ADC_BUCK2_CHANNEL                ADC_Channel_2
#define ADC_BUCK2_INDEX                    2
#define ADC_BUCK2_CONV_RATIO            (3.3/4095)

#define ADC_BUCK3_GPIO_CLK                RCC_AHB1Periph_GPIOA
#define ADC_BUCK3_GPIO                    GPIOA
#define ADC_BUCK3_Pin                    GPIO_Pin_3
#define ADC_BUCK3_CHANNEL                ADC_Channel_3
#define ADC_BUCK3_INDEX                    3
#define ADC_BUCK3_CONV_RATIO            (3.3/4095)

#define MEA_ADC1_DMA_STREAM                DMA2_Stream0
#define MEA_ADC1_DMA_CHANNEL            DMA_Channel_0
#define MEA_ADC1_DMA_IRQChannel            DMA2_Stream0_IRQn
#define MEA_ADC1_DMA_IRQHandler            DMA2_Stream0_IRQHandler
#define MEA_ADC1_DMA_IT_TCIF            DMA_IT_TCIF0

#define MEA_ADC2_DMA_STREAM                DMA2_Stream2
#define MEA_ADC2_DMA_CHANNEL            DMA_Channel_1
#define MEA_ADC2_DMA_IRQChannel            DMA2_Stream2_IRQn
#define MEA_ADC2_DMA_IRQHandler            DMA2_Stream2_IRQHandler
#define MEA_ADC2_DMA_IT_TCIF            DMA_IT_TCIF2







友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
正点原子
1楼-- · 2019-07-20 17:15
帮顶
tt朝花夕拾
2楼-- · 2019-07-20 20:18
1 先帮顶;
2 2个adc采集4个通道么?不知道线路的样子;
3 adc通过dma采集,先看下adc的测量点的电压,用万用表量下是否为0呢?排查硬件线路;
4 之后再通过断点查看下adc开启转换后,adc-> DR寄存器是否有变化,对应的4096/3.3v的关系,看下转换出来是多少v;
5 最后再查看dma采集;
个人小建议;

一周热门 更多>