STM32F407 双ADC DMA 规则同步采集,第一次初始化后DMA中断正常,中断后再次启动DMA就再也不能产生DMA中断。
ADC DMA初始化:
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Enable peripheral clocks *************************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
/* DMA2_Stream0 channel0 configuration **************************************/
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //指定DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; //指定了外设基地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value; //指定内存0基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //指定数据从外围到内存
DMA_InitStructure.DMA_BufferSize = 100; //DMA缓冲器大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //指定外设寄存器地址是否递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //指定外设数据的宽度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //指定内存数据的宽度
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //指定Streamx DMAy的运行模式为普通
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //指定DMA优先级别
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //指定使用FIFO模式还是直接模式
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //指定了FIFO阈值
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //内存突发传输每次转移一个数据
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发传输每次转移一个数据
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE); //开 DMA2_Stream0 中断
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE); //开DMA2_Stream0
// DMA2_Stream0->CR |= 0x00000001; //DMA使能
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; //同步规则模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //时钟分频
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2; //配置直接存储器存取模式多ADC模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//采集间隔时间
ADC_CommonInit(&ADC_CommonInitStructure);
// ADC->CCR=0X8006;
/* ADC1 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位ADC
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描关
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //否选择外部触发边沿来触发一个规则组的转换 (不用,这里采用软件启动)
// ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_T1_CC1 //是否选择外部事件来触发一个规则组的转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1; //指定数量的ADC通道数。
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC1 regular channel18 (VBAT) configuration ******************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_15Cycles);
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
/* Enable ADC1 **************************************************************/
ADC_DMACmd(ADC1, ENABLE); //只有ADC1和ADC3具有DMA请求功能,ADC2是利用双ADC模式时ADC1的请求
ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //开ADC 的中断
ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE); //开ADC 的中断
ADC_SoftwareStartConv(ADC1);
}
DMA重启配置:
void DMA_REConfig(void)//重新启动DMA, 开始ADC采集
{
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_BufferSize = 100; //DMA缓冲器大小
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE); //开 DMA2_Stream0 中断
DMA_Cmd(DMA2_Stream0, ENABLE); //开DMA2_Stream0
a=DMA2_Stream0->CR ;
}
DMA中断:
void DMA2_Stream0_IRQHandler (void)//DMA2 通道0 中断程序
{
u32 a=DMA2->LISR;
if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
// DMA_Cmd(DMA2_Stream0, DISABLE); //关MDA
// if(start)
// {
// start=0;
dmabz=1;
// }
}
DMA2->LIFCR |= 0X0000003D; //清除所有中断
}
请高手指教 |