STM32L1xx——ADC(中断/DMA)样例代码

此代码欲实现的功能是:使用中断或者DMA的方式采集滑动变阻器采集到的电压值,使用单ADC单通道采样!

(由于不是直接需要电压,所以转换函数我就没列出来,可根据自身需要去网上查到转换的函数。)

代码结构树为:


                             |————ADC_GPIO_Config(void)
   ADC_Config(void)|————ADC_Mode_Config(void)
                             |_______ADC_NVIC_Config(void) / ADC_DMA_Config(void)

ADC_GPIO_Config:

void ADC_GPIO_Config(void)
{
    //初始化PA2引脚
  GPIO_InitTypeDef GPIO_InitStruct;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
    GPIO_InitStruct.GPIO_Pin = ADC_GPIO_PIN;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(ADC_GPIO_PORT,&GPIO_InitStruct);
    
}

ADC_Mode_Config:

void ADC_Mode_Config(void)
{
    ADC_InitTypeDef ADC_InitStruct;
    RCC_HSICmd(ENABLE);                    //开启HSI时钟,非常重要,stm32l151的时钟由HSI提供
    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC时钟
    ADC_DeInit(ADC1);
    ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;//不使用扫描模式
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//使能连续转换
    ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不使用外部触发,无需设置
    ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
    ADC_InitStruct.ADC_NbrOfConversion = ADC_Channel_1;//使用的通道数=1
    ADC_Init(ADC1,&ADC_InitStruct);
    ADC_RegularChannelConfig(ADC1,ADC_Channel_2,1,ADC_SampleTime_4Cycles);//配置ADC的通道转换顺序和采样时间
#if ADC_DMA_ENABLE
    ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);    //开启ADC_CR2的DDS位,使DMA完成后可以自动开始
    ADC_DMACmd(ADC1,ENABLE);                            //开启DMA
#else
    ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);               //使能规则通道转换完成中断
#endif
    ADC_Cmd(ADC1,ENABLE);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET); //等待ADC启动完成
    ADC_SoftwareStartConv(ADC1);
}

ADC_NVIC_Config:

void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);                            //配置组优先级
    NVIC_InitStruct.NVIC_IRQChannel = ADC1_IRQn;                                //选择中断源
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;            //抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;                            //子优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                                //开总中断
    NVIC_Init(&NVIC_InitStruct);                                                                //初始化结构体
}

ADC_DMA_Config:

void ADC_DMA_Config(void)
{
    DMA_InitTypeDef DMA_InitStruct;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
    DMA_DeInit(DMA1_Channel1);                                    //DMA复位
    
    DMA_InitStruct.DMA_PeripheralBaseAddr = ADC_DR_ADDRESS;              //外设地址
    DMA_InitStruct.DMA_MemoryBaseAddr =  ((uint32_t) &ADC_Data);                                //存储器地址
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                                 //ADC发出数据
    DMA_InitStruct.DMA_BufferSize = 1;                                            //传输数据数量
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //串口数据寄存器只有一个,不自增
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;                    //存储器地址不自增
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //外设数据宽度:半字d
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                    //存储器数据传输宽度
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;                                        //循环发送
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;                            //优先级为高
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
    
    DMA_Init(ADC_DMA_CHANNEL,&DMA_InitStruct);                                        //ADC的DMA使用通道ADC1通道1
    DMA_Cmd(ADC_DMA_CHANNEL, ENABLE);
    
}

Note:中断和DMA的代码我都给出来了,根据自身需要选择。

原文地址:https://www.cnblogs.com/Irvingcode/p/11877765.html