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求解??
|
|