
本帖最后由 firstlege 于 2015-1-21 16:40 编辑 在用STM32f103zet6时用了外部内存 启用了FSMC,结果TIM4的channel2就不能输出PWM了 头疼!怎么办呢? 想了一天有了点思路 并完成实现 这个方法也可以让任何一个IO口成为了PWM的输出口 1、思路原理:PWM无非是将一个引脚设置为输出高或低,输出高或低的时间是由比较器作出的,counter的值高于比较器的值引脚输出一个电平,counter的值低于比较器的值引脚输出一个电平,输出什么电平由你的设置决定。 2、实现必要:在STM32中可以设置比较器中断,这是最关键的。这也让实现成为可能。 说到这大家应该知道我想怎么做了吧 , 对,就是复用比较器的中断来实现。 3、具体实现: 3.1首先配置好TIM4 采用了中央计数模式 其它的简单设置一下,主要是设置开启中断。 如果你想要其它的设置 再看参考手册吧。 void TIM4_PWM_Cfg(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_DeInit (TIM4); TIM_TimeBaseInitStruct.TIM_Period = 3999;//计数值 这个数值与中断中对应。 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned3; TIM_TimeBaseInitStruct.TIM_Prescaler = 17;//18预分频 主频72M TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;// 时钟不分频 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); TIM_SetCounter(TIM4,0x0); TIM_ITConfig(TIM4,TIM_IT_CC2,ENABLE);//设置2channel中断 //初始化TIM4 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC1 // TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC2' TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC3 TIM_OC4Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4OC4 // TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; //比较输出使能 // TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2' TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的预装载寄存器 // TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR2上的预装载寄存器 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR3上的预装载寄存器 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR4上的预装载寄存器 TIM_Cmd(TIM4,ENABLE); } 3.2 中断中要做的事 注意的是:如果比较器值设置高于cnt的最大值时 溢出时也会中断, PWM是输出的是设定的电平 我这里采取了不改变操作 void TIM4_Interrupt(void) { extern CPU_INT16U CompreValue;// 用这个函数设置的比较值 TIM_SetCompare2(TIM4,CompreValue); CPU_INT16U Tcounter ; Tcounter = TIM_GetCounter(TIM4); if((TIM_GetITStatus(TIM4,TIM_IT_CC2) == SET) ) { if(LED_CompreValue[1] < 3900 ) // 4000 - 100 { if(Tcounter > LED_CompreValue[1]) { LED_ON;//设置引脚高电平 } else { LED_OFF; } } } TIM_ClearITPendingBit(TIM4,TIM_IT_CC2); TIM_ClearFlag(TIM4,TIM_FLAG_CC2); } 这里是祥实现的一个方法 50是当你设置为3950到4000时这个时候就会有溢出了中断产生了 在溢出中断时 我需要保持原来的电平 希望大家有更好的设置方法 4、最后 希望大家能多给的意见 怎么实现理简单 |
![]() |