请教各位大哥一个问题:我用f103的定时器2捕捉外部脉冲,计算出频率后,再用定时器3输出相应频率的PWM波,PWM输出前几个周期....

2019-10-14 23:50发布


思路是:timer2采集外部脉冲,计算出脉冲频率后,按照3.125倍的关系转换为相应的频率,重新装载timer3的预装在寄存器,然后用timer3输出此频率的PWM。存在的问题是:timer3输出前几个周期的PWM是乱的,不正确的,我仿真了一下,感觉是timer3以初始化就开始输出,但此事频率还没计算出。
请求各位大哥帮帮忙!!!


u8 Cap_time;u8 Recev_OK;u8 Capture_state=0;u16 Capture_value=0;extern u16 pulse_value[2];//timer2输入捕捉初始化 void TIM2_Cap_Init(void){                 GPIO_InitTypeDefGPIO_InitStructure;         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;         TIM_ICInitTypeDef  TIM2_ICInitStructure;     NVIC_InitTypeDef NVIC_InitStructure;          RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);    //使能TIM2时钟        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能GPIOA时钟                  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;             GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;            GPIO_Init(GPIOA,&GPIO_InitStructure);         GPIO_ResetBits(GPIOA,GPIO_Pin_1);                                                   //PA0 下拉                  //初始化定时器2 TIM2           TIM_TimeBaseStructure.TIM_Period= 15999; //设定计数器自动重装值 72000000*(0XFFFF)/(7199+1)=6.5s         TIM_TimeBaseStructure.TIM_Prescaler=7199;   //预分频器            TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim         TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;  //TIM向上计数模式         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位           //初始化TIM5输入捕获参数         TIM2_ICInitStructure.TIM_Channel= TIM_Channel_2; //CC2S=01      选择输入端 IC2映射到TI2       TIM2_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;    //上升沿捕获       TIM2_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI; //映射到TI2       TIM2_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;  //配置输入分频,不分频        TIM2_ICInitStructure.TIM_ICFilter =0x00;//IC1F=0000 配置输入滤波器不滤波       TIM_ICInit(TIM2,&TIM2_ICInitStructure);                  //中断分组初始化         NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;  //TIM2中断         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;  //先占优先级2         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;  //从优先级0         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //IRQ通道被使能         NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器                 TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允许时间更新中断和CC2IE捕获中断                    TIM_Cmd(TIM2,ENABLE );     //使能定时器2  } ////重新配置TIM2的预装载值//void TIM2_Cap_Config(u16 arr)//{// TIM2->ARR=arr; //}/*********************************************************                         Capture_state    |     bit7         |bit6|              bit5~0             |     捕捉完成标记  捕获到高电平标记    捕获过程中溢出的次数 **********************************************************/void TIM2_IRQHandler(void){ if((Capture_state&0x80)==0)  {     if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)     {         if(Capture_state&0x60)  //已经第一次捕获到高电平,且第一次标志位已经置1           {              if((Capture_state&0x1F)==0x1F)              {                 Capture_state|=0x80;                 Capture_value=0xFFFF;            }              else                   Capture_state++;                      }           else         TIM3_PWM_Config(15999);   //如果输入捕捉的秒冲的周期超过预装载寄存器的最大值0xFFFF,则取0xFFFF           TIM_SetCompare2(TIM3,0);                     }      if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)      {         if((Capture_state&0x60))  //同上           {              Capture_state|=0x80;  //捕获一个完整的周期              Capture_value=TIM_GetCapture2(TIM2);           }          else          {              Capture_state=0;              Capture_value=0;              Capture_state|=0x60;   //  第一次捕捉高电平标志置1,第一次置1              TIM_SetCounter(TIM2,0);           //TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);              //TIM_Cmd(TIM3, ENABLE);                                }                        }    }     TIM_ClearITPendingBit(TIM2,TIM_IT_CC2|TIM_IT_Update);} void TIM3_PWM_Init(void){           GPIO_InitTypeDefGPIO_InitStructure;         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;         TIM_OCInitTypeDef  TIM_OCInitStructure;                   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);    //使能定时器3时钟        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟                  //GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE); //Timer3部分重映射  TIM3_CH2->PB5           //设置该引脚为复用输出功能,输出TIM3 CH2PWM脉冲波形    GPIOA.7         GPIO_InitStructure.GPIO_Pin= GPIO_Pin_7; //TIM_CH2         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;  //复用推挽输出         GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;         GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO        //初始化TIM3         TIM_TimeBaseStructure.TIM_Period= 4999; //设置在下一个更新()事件装入活动的自动重装载寄存器周期的值         TIM_TimeBaseStructure.TIM_Prescaler=7199; //设置用来作为TIMx时钟频率除数的预分频值         TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim         TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;  //TIM向上计数模式         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位                  //初始化TIM3Channel2 PWM模式                TIM_OCInitStructure.TIM_OCMode= TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2        TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable; //比较输出使能         TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低         //TIM_OCInitStructure.TIM_Pulse=25000;         TIM_OC2Init(TIM3,&TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3OC2          TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);  //使能TIM3CCR2上的预装载寄存器          TIM_Cmd(TIM3,ENABLE);  //使能TIM3                  //TIM_SetCompare2(TIM3,psc);//设置占空比        //TIM3->CCR2=psc;   } //预装载值重新配置void TIM3_PWM_Config(u16 arr ){       TIM3->ARR=arr; } #include "timer.h"#include "gpio.h"#include "usart.h"#include "wwdg.h"#include <stdio.h> //extern volatile u8 gTick; //u32 gTick_feeddog;volatile u32 pulse_freq; u32 Arr_Value; u32 Arr_out;u16 Pulse_out; u8 tr,wr;extern u8 Recev_OK;extern u8 Capture_state;extern u32 Capture_value;//volatile u16 ARR_TIME;extern void TIM3_PWM_Config(u16 arr );extern void delay_ms(u16 ntime); int main(void){        //    ARR_TIME=60000;         //SysTick_Config(SystemCoreClock / 100);    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组22位抢占优先级,2位响应优先级    GPIO_init();    uart_init();    TIM2_Cap_Init();    TIM3_PWM_Init();     TIM4_Init();    WWDG_Init();    wr=WWDG->CFR&0x7F; //取出窗口值 while(1)         {//        ARR_TIME-=100;//        if(ARR_TIME<100)//         ARR_TIME=60000;//        //         TIM4_PWM_Config(ARR_TIME );//         TIM_SetCompare2(TIM4,ARR_TIME/2);            //         delay_ms(1000);                    tr=WWDG->CR&0x7F; //实时取出计数寄存器值                       if(Capture_state&0x80)           {                            pulse_freq=(Capture_state&0x1F);              pulse_freq*=65536;              pulse_freq+=Capture_value;           //  printf("PWM1:%d ms ",pulse_freq/10);              Arr_Value=pulse_freq*8/25;              Arr_out=Arr_Value-1;              Pulse_out=(u16)(Arr_Value*16/25);              if(Arr_Value>0xFFFF)              {                       TIM3_PWM_Config(0xFFFF);   //如果输入捕捉的秒冲的周期超过预装载寄存器的最大值0xFFFF,则取0xFFFF                   TIM_SetCompare2(TIM3,0xFFFF>>1);                   //TIM3_PWM_Init();              }              else              {              //  printf("PWM1:%d ms ",Arr_out/10);                 TIM3_PWM_Config(Arr_out);                 TIM_SetCompare2(TIM3,Pulse_out);              }           Capture_state=0;                                   }           //wwdg计数器计数值小于窗口寄存器值,则进行喂狗           // (0x7F-0x4F)*0.91ms=43.68ms, 43.68ms喂狗一次           if(tr<wr)           {             WWDG_Set_Counter(0x7F);             printf("开始喂狗! ");           }                                            }         }
0条回答

一周热门 更多>