思路是: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 CH2的PWM脉冲波形 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); //使能TIM3在CCR2上的预装载寄存器 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);//设置中断优先级分组为组2:2位抢占优先级,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("开始喂狗!
"); } } }
一周热门 更多>