各位大神下午好,我在使用STM32F051调试定时器触发ADC时无意间发现一个问题,使用TIM15作为触发,时间为1ms,当采集一个20KHZ的PWM信号时(不要纠结为什么用AD采集,无意间发现的这个问题),然后使用DAC将采集到的量输出,意思就是DAC跟踪ADC,发现DAC输出变为1HZ,但是占空比和PWM信号是一样的,但是使用ADC采集其他电压信号(我认为是变化比较慢的)时DAC跟踪输出是正常的,以下是测量的波形
图1:ADC管脚(PC5)PWM的波形
图2:DAC输出的波形
图3:可以看出DAC输出时每1ms值会变化一次,但是根据PWM信号频率是20KHZ 周期为50us,DAC的输出应该是上下跳动的而不是这种阶梯似的波形
以下为部分初始化代码
void Cfg_Time_TGO(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
TIM_TimeBaseStruct.TIM_ClockDivision =TIM_CKD_DIV4;
TIM_TimeBaseStruct.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseStruct.TIM_Prescaler =48-1;
TIM_TimeBaseStruct.TIM_Period =1000-1;
TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStruct);
TIM_SelectOutputTrigger(TIM15,TIM_TRGOSource_Update);
TIM_ClearFlag(TIM15,TIM_FLAG_Update);
TIM_Cmd(TIM15, ENABLE);
}
void Cfg_ADC_INss(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
ADC_DeInit(ADC1);
DMA_DeInit(DMA1_Channel1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1 ; //¿ØÖƵçѹ Êä³öµçѹ
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 ; //¿ØÖƵçѹ Êä³öµçѹ
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //
ADC_StructInit(&ADC_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode =DISABLE;
ADC_InitStruct.ADC_DataAlign =ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConvEdge =ADC_ExternalTrigConvEdge_Rising;
ADC_InitStruct.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T15_TRGO;
//ADC_InitStruct.ADC_ExternalTrigConvEdge =ADC_ExternalTrigConvEdge_None;
ADC_InitStruct.ADC_Resolution =ADC_Resolution_12b;
ADC_InitStruct.ADC_ScanDirection =ADC_ScanDirection_Backward;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_OverrunModeCmd(ADC1,ENABLE);
ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_239_5Cycles);
ADC_ChannelConfig(ADC1, ADC_Channel_15 , ADC_SampleTime_239_5Cycles);
ADC_GetCalibrationFactor(ADC1);
ADC_Cmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
ADC_StartOfConversion(ADC1);
DMA_DeInit(DMA1_Channel1);//Ñ¡ÔñƵµÀ
DMA_InitStruct.DMA_PeripheralBaseAddr =(uint32_t)((uint16_t *)ADC1_DR_Address);//ÉèÖÃÍâÉèµØÖ·
DMA_InitStruct.DMA_MemoryBaseAddr =(uint32_t)((uint16_t *)ADC_DR);//ÉèÖÃÄÚ´æÓ³Éä
DMA_InitStruct.DMA_PeripheralBaseAddr =ADC1_DR_Address;//ÉèÖÃÍâÉèµØÖ·
DMA_InitStruct.DMA_MemoryBaseAddr =(uint32_t)&ADC_DR;//ÉèÖÃÄÚ´æÓ³Éä
DMA_InitStruct.DMA_DIR =DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize =2;//»º³åΪ
DMA_InitStruct.DMA_PeripheralInc =DMA_PeripheralInc_Disable;//¹ØÍâÉèµØÖ·¼ÆÊý
DMA_InitStruct.DMA_MemoryInc =DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;//°ë×Ö
DMA_InitStruct.DMA_Mode =DMA_Mode_Circular;//Ñ»·Ä£Ê½
DMA_InitStruct.DMA_Priority =DMA_Priority_High;//¸ßÓÅÏȼ¶
DMA_InitStruct.DMA_M2M =DMA_M2M_Disable;//¹ØÄÚ´æµ½ÄÚ´æ
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
DMA_Cmd(DMA1_Channel1, ENABLE);//ƵµÀʹÄÜ
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);//ÅäÖà DMA Ñ»·Ä£Ê½
ADC_DMACmd(ADC1, ENABLE);
DMA_ITConfig (DMA1_Channel1,DMA_IT_TC,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel=DMA1_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=0;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void DMA1_Channel1_IRQHandler(void)
{
DMA_ClearFlag(DMA1_FLAG_TC1);
dmadone = 1;
}
int main()
{
Cfg_Time_TGO();
Cfg_ADC_INss();
while(1)
{
if (dmadone!=0)
{
DAC_SetChannel1Data(DAC_Align_12b_R,ADC_DR[1]);
}
}
}
|