本帖最后由 siatliuliu 于 2011-8-3 10:36 编辑
平台:火牛开发板STM32F103VBT6 MDK3.8
功能:
1.TIM1 PWM2方式产生频率变化的脉冲
2.TIM2定时每5ms 在更新中断中改变TIM1的频率(ARR),打印出TIM1在上一个5ms周期里的脉冲数。
现象及问题:
通过示波器可以看到:TIM1输出脉冲每隔5ms 频率按设定的频率变化,问题是计数不准确(如下)。
第n周期 第1&2方式脉冲数 第3方式脉冲数 理论脉冲数 TIM1频率
nStep : 1, pulseNum : 6 506 10 2k
nStep : 2, pulseNum : 11 21 20 4k
nStep : 3, pulseNum : 21 46 40 8k
nStep : 4, pulseNum : 42 92 80 16k
nStep : 5, pulseNum : 47 128 90 18k
nStep : 6, pulseNum : 52 142 100 20k
nStep : 7 ,pulseNum : 78 187 150 30k
nStep : 8, pulseNum : 104 263 200 40k
nStep : 9, pulseNum : 125 337 250 50k
nStep : 0, pulseNum : 250 680 500 100k
计数方式:
1.在TIM1的更新中断里计数(算不上严格意义上的计数,只是验证一下)
/* * @file TIM/
/stm32f10x_it.c **************************************************************/
#include "stm32f10x_it.h"
//对应频率:2k, 4k, 8k, 16k, 18k, 20k, 30k, 40k, 50k, 100k
uint16_t ARR_Buffer[10] = {36000, 18000, 9000, 4500, 4000, 3600, 2400, 1800, 1440, 720};
u32 nStep= 0 ;
u32 pulseNum = 0;
//TIM1 计脉冲数
void TIM1_UP_IRQHandler(void)
{ if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update );
pulseNum++; //计脉冲数
}
}
//TIM2 5ms中断计时, 更改TIM1频率,打印上一阶段脉冲数
void TIM2_IRQHandler(void){
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
TIM1->CCR1 = ARR_Buffer[nStep] / 2; //更改TIM1占空比
TIM1->ARR = ARR_Buffer[nStep]; //更改TIM1脉冲频率
printf("\nnStep : %d,pulseNum : %d\n", nStep, pulseNum); //打印上个5ms TIM1的脉冲数
pulseNum = 0; //脉冲数清零
nStep++;
if(nStep >9) //10个一循环
nStep = 0;
}
}
/* main.c *********************************************************************************/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
ErrorStatus HSEStartUpStatus;
int main(void)
{
/* System Clocks Configuration */
RCC_Configuration();
/* GPIO Configuration */
GPIO_Configuration();
NVIC_Configuration();
/*USART Configuration */
COM_Init();
/* TIM1 Peripheral Configuration --------------------------------------------*/
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 36000;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Channel 3 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 18000;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
//TIM2产生5ms中断计时。
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = 7199;
TIM_TimeBaseStructure.TIM_Prescaler = 24;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_CCPreloadControl(TIM1, ENABLE);
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM2, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
while (1)
{}
}
方式2:输入捕获计数。TIM1 Chanel1 接至 TIM2 Channel2, TIM2 Channel2 在输入捕获中断中计数
在TIM2_IRQHandler()中加入下面代码
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{ TIM_ClearITPendingBit(TIM2, TIM_IT_CC2 );
pulseNum++;
}
方式3:外部时钟模式2.TIM1 Channel1作为TIM3的外部时钟。
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x00;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SetCounter(TIM3, 0);
/****************************** stm32f10x_it.c **********************************/
void TIM2_IRQHandler(void){
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
pulseNum = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
printf("\nnStep : %d,pulseNum : %d\n", nStep, pulseNum);
TIM1->CCR1 = ARR_Buffer[nStep] / 2;
TIM1->ARR = ARR_Buffer[nStep];
TIM_GenerateEvent(TIM1, TIM_EventSource_Update);
nStep++;
if(nStep >9)
nStep = 0;
}
|
|