本帖最后由 pofu007 于 2014-8-1 13:00 编辑
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 扫描一个通道组
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 模数转换工作在单次转换模式
ADC_InitStructure.ADC_NbrOfChannel = 10;
如此配置,我理解的意思是这样的,regular group中含10个通道,启动转换信号发生后,采用扫描方式对regular group中的10个通道完成转换一次。
但是我试图用while(RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));去判断转换是否完成的时候,发现无法跳出循环,也就是EOC位不会置位。
另外采用扫描方式需要配置DMA我已设置好,调试发现启动转换后DMA对应的内存中确实有数据,难道启用的DMA后,扫描方式不需要去查询转换是否完成?
为了说明问题,我把配置的代码都贴一下。
u16 AD_Value[10] = {0};
//=============================================================================
// 入口参数:
// 返 回:
// 函数功能:ADC模块初始化配置
//=============================================================================
void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
//使能ADC1通道时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
//设置ADC模块时钟分频系数为6,64M/8=8M,ADC最大工作时钟频率不能超过14M
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
//复位ADC1,将外设ADC1的全部寄存器重设为缺省值
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 扫描一个通道组
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 10; // 顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); // 根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
// 设置指定ADC的规则组通道,电池电压检测端口为AIN2,转换10,去除最大最小值,取剩余8个有效值的均值
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5 ); //ADC1,ADC通道,采样时间为55.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 4, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 5, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 6, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 7, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 8, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 9, ADC_SampleTime_55Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 10, ADC_SampleTime_55Cycles5 );
// 开启ADC1的DMA支持
ADC_DMACmd(ADC1, ENABLE);
//使能ADC1
ADC_Cmd(ADC1, ENABLE);
//使能复位校准
ADC_ResetCalibration(ADC1);
//等待复位校准结束
while(ADC_GetResetCalibrationStatus(ADC1));
//开启AD校准
ADC_StartCalibration(ADC1);
//等待校准结束
while(ADC_GetCalibrationStatus(ADC1));
}
//=============================================================================
// 入口参数:
// 返 回:
// 函数功能:DMA模块初始化配置
//=============================================================================
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// 使能DMA1时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; // DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)AD_Value; // DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 内存作为数据传输目的地
DMA_InitStructure.DMA_BufferSize = 10; // DMA通道的缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 数据位宽为16bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA工作在循环缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA通道拥有最高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // DMA通道不设置内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
}
u16 GetResultValue(void)
{
u16 ResultValue = 0;
u16 MinValue = (u16)0xffff;
u16 MaxValue = 0;
u8 i = 0;
// 软件启动ADC1转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// 等待转换完成
while(RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
for(i = 0; i < 10; i++)
{
ResultValue += AD_Value;
if(AD_Value < MinValue)
{
MinValue = AD_Value;
}
if(AD_Value > MaxValue)
{
MaxValue = AD_Value;
}
AD_Value = 0;
}
ResultValue -= MinValue + MaxValue;
return ResultValue >>= 3;
}
|
|