你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

为何STM32F103VET6 ADC采样时间与理论相差太大?

[复制链接]
胤幻1988 提问时间:2016-3-23 14:26 /

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求解??
收藏 评论0 发布时间:2016-3-23 14:26

举报

0个回答

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版