灵动微MM32F003硬件最小系统 --- 多路ADC DMA中断读取例程解析【6】

MM32F003的ADC可以通过启用DMA功能,加快ADC数据的获取,并减轻系统开销。本例程通过开启DMA中断,直接将ADC数据搬运至指定内存空间,减少系统开销。
ADC的配置方式与例程解析【5】相同。这里重点介绍DMA的初始化过程。

1 DMA的初始化

void DMAInit(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) & (ADC1->ADDATA);           //DMA transfer peripheral address
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCValue;                      //DMA transfer memory address
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                          //DMA transfer direction from peripheral to memory
    DMA_InitStructure.DMA_BufferSize = ADCSCANNUM;                              //DMA cache size
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //After receiving the data, the peripheral address is forbidden to move backward
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     //After receiving the data, the memory address is shifted backward
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Define the peripheral data width to 16 bits
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //Define the memory data width to 16 bits
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                             //Cycle conversion mode
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         //DMA priority is high
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                //M2M mode is disabled
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    DMA_Cmd(DMA1_Channel1, ENABLE);

    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                              //DMA interrupt initialization
    NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
}

DMA的初始化主要修改DMA的数据源地址DMA_InitStructure.DMA_PeripheralBaseAddr、DMA的数据目标地址DMA_InitStructure.DMA_MemoryBaseAddr和DMA的数据区大小DMA_InitStructure.DMA_BufferSize这三个参数。

2 DMA中断服务程序

void DMA1_Channel1_IRQHandler(void)
{
    ADC_SoftwareStartConvCmd(ADC1, DISABLE);                                     //Stop Conversion
    DMA_ClearITPendingBit(DMA1_IT_TC1);                                          //Clear interrupt flag
    ADCflag = 1;                                                                //Erected transmission complete flag

}

DMA的数据目标地址存满后会产生中断,进入DMA中断服务程序。

3 main主程序

int main(void)
{
    u16 chan, averagenumber = 0;
      Uart_ConfigInit(9600);
    //  SystemInit();
    //  InitSystick();
    //Initialize DMA
    //
    DMAInit();
    ADCConfig(ADCch0);  //PA0
    ADCConfig(ADCch10); //PB3
    ADCConfig(ADCch11); //PB4
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);                                      //Start Conversion

    while(1) {
        if(ADCflag == 1) {
            ADCflag = 0;
            for(chan = 0; chan < ADCSCANNUM; chan++) {
                varADCavarage[averagenumber][chan] = ADCValue[chan];
            }
            //memcpy(&(varADCavarage[averagenumber][0]),ADCValue,ADCSCANNUM);
            ADC_SoftwareStartConvCmd(ADC1, ENABLE);
            averagenumber++;
            if(averagenumber >= AVERAGELEN) {
                averagenumber = 0;
                ADCTrigFilterflag = 1;
            }
        }
        if(ADCTrigFilterflag) {                             //Determine whether the second-order filter is over
            ADCFilter();
            ADCTrigFilterflag = 0;                         //Clear the filter end flag
            Get_ADCVolatge();                              //Convert the filtered value to voltage

        }

    }
}

每次进入DMA中断服务程序都会修改标志位,主程序会通过while()循环去查询标志位ADCflag,当ADCflag为1时,即对ADC读取的数据进行累加计算平均值和ADC数值转换电压数值的操作。

你可能感兴趣的:(灵动微MM32F003硬件最小系统 --- 多路ADC DMA中断读取例程解析【6】)