/******************************************************************************* * Function Name : DMA_ADC_Transfer_Reset * Description : ADC1/ADC2 DMA传输通道复位,准备下一次DMA传输 * Input : None * Output : None * Return : None *******************************************************************************/ void DMA_ADC_Transfer_Reset(void) { //开始DMA传输 //以下5句是采用函数方式共耗时多达百多个周期 //DMA_Cmd(DMA_Channel1, DISABLE);//先要禁止DMA_ChannelX,才能修改DMA通道X传输数量寄存器DMA_CNDTRx //DMA_ClearFlag(DMA_FLAG_GL1|DMA_FLAG_TC1|DMA_FLAG_HT1|DMA_FLAG_TE1); //DMA_InitStructure.DMA_BufferSize = Transfer_ReceiveData_Buffer.InWord.SampleDepth;//重新设置要通过DMA传输数据量 //DMA_Init(DMA_Channel1, &DMA_InitStructure); //DMA_Cmd(DMA_Channel1, ENABLE);// Enable DMA channel1 //以下4句是采用直接写寄存器方式一共耗时24个周期 DMA_Channel1->CCR &= ~(1<<0); //禁用DMA_Channel,EN是CCR1寄存器的0位 DMA->IFCR |= 0x0000000F;//清除CHANNEL1的4个标志 DMA_Channel1->CNDTR = (u16)Transfer_ReceiveData_Buffer.InWord.SampleDepth;//重新设置要设置的DMA传输数据量 DMA_Channel1->CCR |= (1<<0);//重新使能DMA_channel1 while(!(DMA->ISR & DMA_FLAG_TC1)); DMA_Channel1->CCR &= ~(1<<0); //禁用DMA_Channel,EN是CCR1寄存器的0位 }
/******************************************************************************* * Function Name : DMA_ADC_Transfer_Init * Description : ADC1/ADC2 DMA传输通道初始化 * Input : None * Output : None * Return : None *******************************************************************************/ void DMA_ADC_Transfer_Init(void) { /* DMA channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;//ADC数据寄存器地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Transfer_SendData_Buffer.InWord.data[0];//目标缓冲区地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设是源 DMA_InitStructure.DMA_BufferSize = 0;//设置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;//DMA模式:Circular循环模式/Normal普通模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//内存到内存模式不使能 DMA_Init(DMA_Channel1, &DMA_InitStructure); /* Enable DMA channel1 */ //DMA_Cmd(DMA_Channel1, ENABLE); }
/******************************************************************************* * Function Name : ADC_Initial * Description : ADC1/ADC2初始化 * Input : None * Output : None * Return : None *******************************************************************************/ void ADC_Initial(void) { /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC1/ADC2同时并行采样模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//多通道扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式(转换后即停止) ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;//触发模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1 , &ADC_InitStructure);
/* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_1Cycles5);
/* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* ADC2 configuration ---配置同ADC1--------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register 校准ADC1*/ 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)); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE);
/* Enable ADC2 reset calibaration register 校准ADC2*/ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2));
/* Start ADC2 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while(ADC_GetCalibrationStatus(ADC2)); /* Test on channel1 transfer complete flag */ //while(!DMA_GetFlagStatus(DMA_FLAG_TC1)); /* Clear channel1 transfer complete flag */ //DMA_ClearFlag(DMA_FLAG_TC1); ADC_ExternalTrigConvCmd( ADC1, ENABLE); }
/******************************************************************************* * Function Name : ADC_Sample_Frequency_Set * Description : 根据输入的频率设置,TIM2_CC2产生相应的频率 * 用来控制ADC的采样,Frequency=1000000/(Prescaler+1)来产生 * 因此有些频率计算不准确,一般频率为2或5的倍数才准确 * 频率范围为16Hz~1000,000Hz * Input : u16 Frequency:输入所需要的采样频率 * * Output : None * Return : None *******************************************************************************/ void ADC_Sample_Frequency_Set(u32 Frequency) { TIM_Cmd(TIM2, DISABLE);//先停止TIM2时钟,以准备下面的设置 /* ----------------------------------------------------------------------- TIM2 配置: 产生TIM2_CC2时钟控制信号用于控制ADC采样 TIM2CLK = 72 MHz TIM2 ARR Register = 35 => TIM3 Frequency = (TIM3 counter clock/(ARR + 1))/2 TIM2 Frequency = 1000 KHz. ----------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 35; //APR寄存器 TIM_TimeBaseStructure.TIM_Prescaler = 1000000/Frequency-1; //预分频值,用来调整频率,分频系数=1000khz/(prescaler+1) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM_OCMode_Toggle Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_Channel = TIM_Channel_2; TIM_OCInitStructure.TIM_Pulse = 35; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInit(TIM2, &TIM_OCInitStructure);
//TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); /*---------------------------------------*/ //TIM_ARRPreloadConfig(TIM2, ENABLE);
/* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); } |