使用ADC的基础配置步骤包括:开启时钟,配置ADC相关的GPIO口,配置和使能ADC对应的DMA通道,配置和使能ADC,ADC校准,开始触发。
1)使能ADC对应时钟,对应DMA的时钟,对应GPIO时钟:
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE);
2)配置对应GPIO为模拟输入模式:
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1| GPIO_Pins_2 | GPIO_Pins_3 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_ANALOG;
GPIO_Init(GPIOA, &GPIO_InitStructure);
3)配置ADC对应的DMA:需要先在DMA章节查找ADC对应的DMA通道(示例里就是DMA1_Channel1)。需要使用DMA是因为规则组的多通道ADC共用一个数据寄存器,所以多通道转化时需要开启DMA,否则数据会丢失。开启对应DMA后,每转换完一个通道的数据,DMA都会自动将数据寄存器里的数据搬运到用户预先设置好的数组里,这个搬运过程不需要用户关注/操作。
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//外设地址—即ADC1数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr= (uint32_t)&ADC_RegularConvertedValueTab;//内存地址—用户需要存储ADC转换数据的数组首地址
DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC;//DMA传输方向—这里是外设到内存
DMA_InitStructure.DMA_BufferSize = 4;//DMA传输数据量—这里是4,与ADC通道数量一样
DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;//外设地址自增--不自增,一直都是ADC1的数据寄存器
DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; //内存地址自增--自增,每传输完一次数据,内存地址就加一。例如:DMA第一次搬运的数据放在ADC_RegularConvertedValueTab[0],下一次搬运的数据就放在ADC_RegularConvertedValueTab[1]了,依次增加。直到达到DMA设置的BufferSize,这里时4。
DMA_InitStructure.DMA_PeripheralDataWidth= DMA_PERIPHERALDATAWIDTH_HALFWORD; //外设数据格式--16bit,AT32F403的ADC有效数据是12bit,这里选择16bit的数据格式就可以。
DMA_InitStructure.DMA_MemoryDataWidth = DMA_PERIPHERALDATAWIDTH_HALFWORD; //内存数据格式--16bit,注意对应的ADC_RegularConvertedValueTab数组定义的时候需要定义为16bit格式。
DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; //传输模式--循环模式,循环模式即DMA搬运完4次之后,内存地址又从ADC_RegularConvertedValueTab[0]开始。
DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; //传输优先级--高
DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; //内存到内存--关闭
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ChannelEnable(DMA1_Channel1, ENABLE); //DMA通道使能
4)配置ADC:
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC模式--独立模式
ADC_InitStructure.ADC_ScanMode = ENABLE; //扫描模式--使能,多通道转换的时候,需要开启扫描模式,否则会一直转换第一个通道。
ADC_InitStructure.ADC_ContinuousMode = DISABLE; //连续模式--失能
ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None; //外部触发—选择软件触发(触发方式还可以使用定时器触发/外部中断触发等方式,这里选择最基础的软件触发)
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐--右对齐
ADC_InitStructure.ADC_NumOfChannel = 4; //转换通道数--4
ADC_Init(ADC1, &ADC_InitStructure);
5)使能ADC的DMA功能:
ADC_DMACtrl(ADC1, ENABLE);
6)ADC通道配置(通道顺序,采样时间):
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41_5); //ADC1的通道0(对应GPIO口为PA0),转化顺序为1,采样时间为41.5个ADCCLK
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41_5); //ADC1的通道1(对应GPIO口为PA1),转化顺序为2,采样时间为41.5个ADCCLK
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41_5); //ADC1的通道2(对应GPIO口为PA2),转化顺序为3,采样时间为41.5个ADCCLK
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41_5); //ADC1的通道3(对应GPIO口为PA3),转化顺序为4,采样时间为41.5个ADCCLK
7)ADC外部触发使能、配置:
ADC_ExternalTrigConvCtrl(ADC1, ENABLE);//外部触发使能—注意,软触发也算外部触发,也需要使能外部触发。
8)ADC使能/唤醒:
ADC_Ctrl(ADC1, ENABLE);
9)ADC校准:
ADC_RstCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
delay_ms(10);
10)ADC软触发--开始转换:
ADC_SoftwareStartConvCtrl(ADC1, ENABLE);