• STM32F0的多路ADC 无DMA


    前段时间几乎用了一下午的时间, 就为了调F0的两路ADC, 一开始想的办法是将采样的连续模式(ADC_ContinuousConvMode)使能, 然后连续拿两个值, 拿完分别返回.

    坏处不用说, 看着就傻, 就算你只需要一个ADC通道的值, 也要拿足N个, 比如你一共要拿5个ADC引脚的电压, 那就要全拿, 然后取其中第若干个, 如果你要拿8个做平均, 就要把时间再乘8, 看着就蠢.

    但是反复调试发现如果不连续采样, 第一次ok, 但是后面每次就只采后一个通道了, 很奇怪, 结果发现原来是居然没有一个方法去reset一个记录通道的寄存器, 看完规格书只能手动重置了.

    ADC初始化:

    void ADC1_DMA_Init(void)
    {
        GPIO_InitTypeDef    GPIO_InitStructure;
        ADC_InitTypeDef     ADC_InitStructure;
    
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    
        GPIO_Init(GPIOA, &GPIO_InitStructure);	
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_Init(GPIOA, &GPIO_InitStructure);			
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);		
    	
        ADC_DeInit(ADC1);	      
    	
        ADC_StructInit(&ADC_InitStructure);
        ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  
        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
        ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
        ADC_Init(ADC1, &ADC_InitStructure); 
        
        ADC_ChannelConfig(ADC1, ADC_Channel_7 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 1 with 239.5 Cycles as sampling time */  
        ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 1 with 239.5 Cycles as sampling time */     
    
        ADC_GetCalibrationFactor(ADC1);	 
        ADC_Cmd(ADC1, ENABLE);
    
    
    }
    

     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

    关掉连续模式.

    接着是重点:

    uint32_t getBatteryVol(void){
        __IO uint32_t i;
        __IO uint32_t result;
        __IO uint16_t tempADCResult=0,tempADCResultRef=0, tempADCBetween=0;
        __IO uint32_t average=0;   
    
        ADC1->CHSELR = 0;
        ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 1 with 239.5 Cycles as sampling time */  
        ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
        
        ADC_StartOfConversion(ADC1);	
    
        while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);  
           
        tempADCResultRef = ADC_GetConversionValue(ADC1);
        average = tempADCResultRef;
        
        for(i=1; i<8; i++){
            ADC_StartOfConversion(ADC1); 
        	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET){}
            
            tempADCResult = ADC_GetConversionValue(ADC1);  
            
            if( tempADCResult >= tempADCResultRef){
                tempADCBetween= tempADCResult - tempADCResultRef;
            }else{
                tempADCBetween = tempADCResultRef - tempADCResult; 
            }
            
            if(tempADCBetween <= ADC_Smoth){ 
                average += tempADCResult;
                tempADCResultRef = tempADCResult;  
            }else{
                average += tempADCResultRef;
            }
    
        }
        
        result = ((average >> 3 )* 2500 >> 12) * 2;
    
        return result;
    }
    

    ADC1->CHSELR = 0; 

    先把这个记录通道的寄存器(ADC1->CHSELR)reset掉, 然后制定再指定通道, 然后取8次相加再除8, 还做了一个平滑处理, 其实没必要.最后按照2.5伏参考电压再结合50%的分压返回一个实际的mv为单位的值.

    然后另一个取ADC的函数跟这个完全一样, 除了一行:

        ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 1 with 239.5 Cycles as sampling time */  

    换成:

        ADC_ChannelConfig(ADC1, ADC_Channel_7 , ADC_SampleTime_239_5Cycles); /* Convert the ADC1 Channel 7 with 239.5 Cycles as sampling time */  

    其他一毛一样, 就能取A7引脚, ADC1_7通道的值了, 最后分压啥的,就不多说了.

  • 相关阅读:
    Bayan 2015 Contest Warm Up D. CGCDSSQ 暴力
    Codeforces Round #361 (Div. 2) D. Friends and Subsequences RMQ+二分
    Educational Codeforces Round 21 D. Array Division 前缀和
    Educational Codeforces Round 23 E. Choosing The Commander Trie
    Educational Codeforces Round 23 D. Imbalanced Array 单调栈
    Codeforces Round #421 (Div. 1) B. Mister B and PR Shifts 模拟
    Educational Codeforces Round 24 E. Card Game Again 二分+线段树
    Educational Codeforces Round 25 E. Minimal Labels 优先队列
    Codeforces Round #426 (Div. 1) B. The Bakery DP+线段树
    Codeforces Round #407 (Div. 1) C. The Great Mixing 背包DP+Bitset
  • 原文地址:https://www.cnblogs.com/Montauk/p/6876062.html
Copyright © 2020-2023  润新知