STM32F103VET6 为什么采样要花很长时间,跟理论完全不符合,求助。。。 我是用TIM2的T2_CC2输出PWM作为ADC采样的时钟,并且DMA储存数据,具体如下: 一些外设的配置: /******************************************************************************* * 函数名称:USART_Configuration() * 函数功能:USART 配置 * 入口参数:无 * 出口参数:无 * 返 回 值:无 *******************************************************************************/ void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; /* 波特率:9600 */ USART_InitStructure.USART_WordLength = USART_WordLength_8b; /* 数据位:8 */ USART_InitStructure.USART_StopBits = USART_StopBits_1; /* 停止位:1 */ USART_InitStructure.USART_Parity = USART_Parity_No; /* 无校验 */ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; /* 无硬件握手 */ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* 二线模式 */ /* Configure the USART1,3 */ USART_Init(USART1, &USART_InitStructure); USART_Init(USART3, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* 允许接收中断 */ //USART_ITConfig(USART1, USART_IT_TC, ENABLE); /* 允许发送完成中断 */ USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); /* 允许接收中断 */ //USART_ITConfig(USART3, USART_IT_TC, ENABLE); /* 允许发送完成中断 V1.5 */ /* Enable USART1,3 */ USART_Cmd(USART1, ENABLE); USART_Cmd(USART3, ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC); USART_ClearFlag(USART3,USART_FLAG_TC); } /******************************************************************************* * 函数名称:ADC_Configuration() * 函数功能:ADC 配置 * 入口参数:无 * 出口参数:无 * 返 回 值:无 *******************************************************************************/ void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /* 独立模式 */ ADC_InitStructure.ADC_ScanConvMode = DISABLE; /* 不使用扫描模式 */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* 不使用连续转换模式 */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; /* 触发模式:T2_CC2 */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* 数据右对齐 */ ADC_InitStructure.ADC_NbrOfChannel = 1; /* 1通道 */ ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel2 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ 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)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); } /******************************************************************************* * 函数名称:TIM2_Config() * 函数功能:定时器2配置 OC2输出ADC CLK * 入口参数:Prescaler 预分频值 Period 计数值 * 出口参数:无 * 返 回 值:无 *******************************************************************************/ void TIM2_Config(uint16_t Prescaler,uint16_t Period) { uint16_t Pulse; /*TIME2 挂载在APB1=SYSCLK/2=72M/2=36M*/ TIM_CtrlPWMOutputs(TIM2, DISABLE); /*但APB1的预分频数为2,所以TIM2_Clk=36*2=72M*/ TIM_Cmd(TIM2, DISABLE); if(Prescaler) Prescaler-=1; Pulse = Period/2; if(Period) Period-=1; /*中断时间=(TIM_Prescaler+1)*(TIM_Period+1)/TIM_Fre*/ /* Time Base configuration */ /*本次预分频数为1 Tim2Clk=72M*/ TIM_TimeBaseStructure.TIM_Prescaler = Prescaler; /*时钟预分频数 APB1_Sysclk/(Prescaler+1)*/ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数模式*/ TIM_TimeBaseStructure.TIM_Period = Period; /*自动重装寄存器的值*/ TIM_TimeBaseStructure.TIM_ClockDivision = 0; /*采样分频 采样分频DIV1 不变*/ TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Channel 2 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_Pulse = Pulse; TIM_OC2Init(TIM2, &TIM_OCInitStructure); /* TIM2 IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); /* TIM2 counter enable */ TIM_Cmd(TIM2, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM2, ENABLE); } /******************************************************************************* * 函数名称:DMA_Configuration() * 函数功能:DMA 配置 * 入口参数:无 * 出口参数:无 * 返 回 值:无 *******************************************************************************/ void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 100; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); } 放在WHILE中的处理函数: for(i=0;i<3;i++) { /* 控制信号源和交叉开关 */ /*复位初始状态*/ SET_ON_SELECT_Reset(); /*SET_ON端复位*/ Delay_ms(2); SET_ON_SELECT_SWITCH('A',i); /*准备状态*/ Delay_ms(2); SET_ON_SELECT_SWITCH('B',i); /*执行状态*/ /* 采样 */ /* 采样速率设置 */ TIM2_Config(TAB_TIM_TIME[i].T1,TAB_TIM_TIME[i].T2); Delay_ms(My_DELAYTIME[i]); /* 采样并计算有效值 */ for(j=0;j<4;j++) { AD1_CH2_Value=0; for(k=0;k<50;k++) { while(!ADC_Flag); ADC_Flag=0; CH2_Value_Temp=ADC_ConvertedValue[k]; CH2_Value_Temp-=2048; AD1_CH2_Value+=(CH2_Value_Temp*CH2_Value_Temp); } AD1_CH2_Value/=50; AD1_CH2_Value=sqrt(AD1_CH2_Value); AD1_CH2_Temp[j]=AD1_CH2_Value; } } 这一段代码耗时间非常长。。。 定义了一个采样标志:ADC_Flag 它是在TIM2中断里面复位的: /******************************************************************************* * 函数名称:TIM2_IRQHandler() * 函数功能:TIM2中断处理,更新ADC采样标志 * 入口参数:无 * 出口参数:无 * 返 回 值:无 *******************************************************************************/ void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET){ TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); ADC_Flag=1; } } 其他定义的常量: STRUCT_TIM_DATA TAB_TIM_TIME[3]={{1,19175},{1,1340},{1,268}}; /* 采样定时器时间系数 分别对70HZ,2000HZ,5000HZ进行采样 */ uint16_t My_DELAYTIME[3]={20,10,10}; /* 延时时间 单位:mS 当波形产生后,要延时一段时间才能稳定*/ 我的采样思路是这样的:每种频率的正弦波,每个周期采50个点。。譬如70HZ来说:每个点采样的时间为:1/70/50s..则可以算出TIM2的配置: 中断时间=(TIM_Prescaler+1)*(TIM_Period+1)/TIM_Fre 设定采样频率未分频为1 则 1/70/50=1*TIM_Period/72M 得出 TIM_Period=20571; 但为了绝对在1个周期以内 TIM_Period取稍小的值 19175; 那么问题来了:实际上采样10个70HZ周期的最长时间也就是1/70*10=0.143S,但为什么实际上用用时远远不止呢?大概有600ms求解?? |