RT,分情况讨论 单ADC可以连续低速均匀采样数据处理、截断式高速均匀采样(高达36M/(3+6)),多ADC可以高速截断式高速均匀采样(高达36M/5)
参考资料:
http://download.csdn.net/detail/laoylhuli/4420045
http://www.fx114.net/qa-15-78897.aspx
应用笔记:STM32系列微控制器的ADC各模式说明及其应用例程 http://www.stmcu.org/document/list/index/sort-new/category-178?p=1
官方例程
单ADC 时,DMA采用normal模式,DMA进入TC中断后,需要做一下操作:
step1:关闭DMA
step2: 重新初始化,使能DMA
step3:清状态位,软件触发ADC
代码如下:
void DMA_slow_configure(){
/* DMA2 Stream0 channel0 configuration */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_CDR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCTripleConvertedValue_slow;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = SizeOfBuffer; // 缓存
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设 数据 大小 字
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 存储 大小
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 若用中断,则用一般模式, 若不用中断 则循环模式 !!!!!!!!!!!!!!
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 存储 是否 突发传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 外设 是否 突发传输
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
//MemSize /PerSize * MemoryBurst 的倍数 = PerSize * PeripheralBurst的倍数
DMA_ClearFlag(DMA2_Stream0,DMA_IT_TC);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE); // 中断
//* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
}
void ADC_slow_configure(){
/* ADC Common configuration *************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // !!!!!!!!!!
// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; // 5--20个 单个adc连续转换,此设置无效
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // !!!!!!!!!!!
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; // 分频 APB2/div =72 /div
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; // bit
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 通道扫描
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 是否使能 连续采样 看情况
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1; // 通道数目
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_28Cycles);// 72M /ADC_Prescaler_Div8 /(28+12)
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); //源数据变化时开启DMA传输
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
/* Start ADC1 Software Conversion */
// ADC_SoftwareStartConv(ADC1);
}
void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
adc_sample=1;
}
}
int main(void) // CPU 144 Mhz
{
GPIO_configure();
NVIC_config();
USART6_Configuration();
DMA_slow_configure();
ADC_slow_configure();
ADC_SoftwareStartConv(ADC1);
while (1)
{
if(adc_sample){
adc_sample=0;
DMA_Cmd(DMA2_Stream0, DISABLE);// DMA 配置时,按理说应该先停止dma 实测不停止也能工作
DMA_slow_configure();
ADC1->SR=0; // 必不可少,位置必须在启动ADC前
ADC_SoftwareStartConv(ADC1); // 必不可少
//单ADC非循环模式,若多ADC可以不需要重新启动
}
}
}
三重ADC模式 ,高速率均匀,难以连续采样,变通地采一段进行处理后,再去采样。
文件见:http://download.csdn.net/detail/laoylhuli/4420045
注意点:三重ADC时,DMA中断后,重新开启ADC-DMA时,可以不做软件触发ADC,单ADC时,必须软件触发ADC :ADC_SoftwareStartConv(ADC1)。具体原因,待以后在研究。