此代码欲实现的功能是:使用中断或者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的代码我都给出来了,根据自身需要选择。