折腾了几天了,还没有把DMA弄得明白,现在把自己做的双通道的AD采样记录一下,免得忘得太快了。
上篇文章已经讲得很详细了,对于ADC的采样,有几个结构需要初始化:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// 使能 ADC1时钟线
/* ADC1 configuration */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式
//为了保证单次通道采集不被覆盖,只好委屈求全了,注意这里的两个DISABLE!!!!!
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件控制转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);//这里是个转折点,如果没有使能,会永远卡在这一点,死机了。。。。
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
下面就可以进入真正的ADC配置了,双通道示意。
void GetADValue(void)
{
uint8_t i;
for(i=0;i<2;i++)
{
switch(i)
{
case 0:
/* ADC1 regular channel_8,configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); break;//转换时间为17.1US
case 1:
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5); break;//转换时间为17.1US
}
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);//此处与下面的DISABLE呼应,不可省略,虽然前面已经交代过了。
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//我原以为应该是SET,但实际测试结果让我深思良久
//EOC为0表示转换未完成,但重点还是在那个;,只是在告诉我们等待、等待而已!!!!唉。。。
ADCConvertedValue[i]=ADC_GetConversionValue(ADC1);
//数组存储采样值,便于调用查看。
ADC_ClearFlag(ADC1, ADC_FLAG_EOC); //清除EOC,DMA时读数据,硬件自动清除
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
ADC_Cmd(ADC1, DISABLE);//与上文呼应,完成一次采样,保证准确性。前面加个延时更为妥当。
}
}
写到这里应该就够明显了,最重要的思想已经表露无遗,剩下的无非就是如何使用采集到的值,还是各显神通吧!!
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』