adc的多通道

2019-07-20 15:57发布

#include "adc.h"
#include "delay.h"                 

#define ADC1_DR_ADDRESS    ((uint32_t)0x4001204C)

/* 变量 ----------------------------------------------------------------------*/
extern __IO uint16_t ADC1ConvertedValue[64][3];

//初始化ADC                                                                                                                          
void  Adc_Init(void)
{   
    ADC_InitTypeDef       ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    DMA_InitTypeDef       DMA_InitStructure;
    GPIO_InitTypeDef      GPIO_InitStructure;

    /* 使能 ADC1, DMA2 和 GPIO 时钟 ****************************************/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE); //使能GPIOA,DMA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC1时钟

    /* DMA2 Stream0 channel0 配置 **************************************/
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; //DMA外设地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue;//DMA 存储器0地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到储存器
    DMA_InitStructure.DMA_BufferSize = 128;  //数据传输量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度:8位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据长度:8位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //DMA工作在循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高 等优先级
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
    DMA_Init(DMA2_Stream0, &DMA_InitStructure); //初始化DMA Stream
    DMA_Cmd(DMA2_Stream0, ENABLE); //开启DMA传输

    /* 配置ADC1通道3、5引脚为模拟输入模式******************************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1| GPIO_Pin_4 ;//|GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  //模拟输入
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /****************************************************************************   
          PCLK2 = HCLK / 2
          下面选择的是2分频
          ADCCLK = PCLK2 /2 = HCLK / 4 = 168 / 4 = 42M
      ADC采样频率: Sampling Time + Conversion Time = 3 + 12 cycles = 15cyc
                    Conversion Time = 42MHz / 15cyc = 2.8Mbps.
        *****************************************************************************/
    /* ADC公共部分初始化**********************************************************/
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟
    ADC_CommonInit(&ADC_CommonInitStructure);//初始化

    /* ADC1 初始化 ****************************************************************/
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;//  扫描模式       
    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 = 3;//3个转换在规则序列中
    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 规则 channel3、5 配置 *************************************/
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_112Cycles);//ADC1,ADC通道,112个周期,提高采样时间可以提高精确度       
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_112Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_112Cycles);
    /* 使能DMA请求(单ADC模式) */
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

    /* 使能 ADC1 DMA */
    ADC_DMACmd(ADC1, ENABLE);  //adc开启DMA传输

    /* 使能 ADC1 */
    ADC_Cmd(ADC1, ENABLE);  //开启AD转换器

    /* 软件启动ADC转换 */
        ADC_SoftwareStartConv(ADC1);
}                                  


主程序



#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"


//ALIENTEK 探索者STM32F407开发板 实验18
//ADC模数转换实验-库函数版本  
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com  
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK

__IO uint16_t ADC1ConvertedValue[64][3];
__IO uint32_t ADC1ConvertedVoltage[3];

int main(void)
{
    u8 i;
        u8 j;
//        u8 k;
        float temp1,temp2,temp3;//temp3;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);    //初始化延时函数
        uart_init(115200);        //初始化串口波特率为115200
        LED_Init();                                        //初始化LED
        LCD_Init();         //初始化LCD接口
        Adc_Init();         //初始化ADC
        POINT_COLOR=RED;
         
        LCD_ShowString(200,70,200,16,24,"UESTC");       
       
       
       

        while(1)
        {
               
                    ADC1ConvertedVoltage[0] = 0;
        ADC1ConvertedVoltage[1] = 0;
                    ADC1ConvertedVoltage[2] = 0;
        for(i=0;i<3;i++)
        {
            for(j=0;j<64;j++)
            {
                ADC1ConvertedVoltage += ADC1ConvertedValue[j];
            }            
            ADC1ConvertedVoltage = ADC1ConvertedVoltage/64;
        }

        temp1 = ADC1ConvertedVoltage[0]*3.3/4096;
        temp2 = ADC1ConvertedVoltage[1]*3.3/4096;
                                temp3 = ADC1ConvertedVoltage[2]*3.3/4096;
        printf("AD1:%d  Vol:%4.2fV   AD2:%d  Vol:%4.2fV ",ADC1ConvertedVoltage[0],temp1,ADC1ConvertedVoltage[1],temp2);

                LCD_ShowxNum(134,130,ADC1ConvertedVoltage[0],4,16,0);    //显示ADCC采样后的原始值               
                i=temp1;                            //赋值整数部分给adcx变量,因为adcx为u16整形
                LCD_ShowxNum(134,150,i,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
                temp1-=i;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
                temp1*=1000;                           //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
                LCD_ShowxNum(150,150,temp1,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.

                LCD_ShowxNum(134,170,ADC1ConvertedVoltage[1],4,16,0);    //显示ADCC采样后的原始值               
                i=temp2;                            //赋值整数部分给adcx变量,因为adcx为u16整形
                LCD_ShowxNum(134,190,i,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
                temp2-=i;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
                temp2*=1000;                           //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
                LCD_ShowxNum(150,190,temp2,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.        

                LCD_ShowxNum(134,230,ADC1ConvertedVoltage[2],4,16,0);    //显示ADCC采样后的原始值               
                i=temp3;                            //赋值整数部分给adcx变量,因为adcx为u16整形
                LCD_ShowxNum(134,250,i,1,16,0);    //显示电压值的整数部分,3.1111的话,这里就是显示3
                temp3-=i;                           //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
                temp3*=1000;                           //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
                LCD_ShowxNum(150,250,temp3,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.   
               
                LED0=!LED0;
                delay_ms(1000);       


}





为什么我采集两个通道的时候可以,采集三个的时候就采集不到了,求大神帮我看看程序哪里不对

         









0条回答

一周热门 更多>