本帖最后由 jinglixixi 于 2021-1-28 10:45 编辑
“BUG可能就摆在你面前”
前段时间,有个朋友在做PWM调节LED灯的测试,本来开发板是配有例程的,编译下载后即可看到效果。
无奈这哥们儿好奇心突发说,你不是显示屏功能移植的高手吗,来把这个PWM调节的输出引脚移到其他的引脚上,我对他讲:显示屏的移植也是有条件的,移植之所以成功是因为我能以I/O口来模拟各种接口通讯获得的。你要把PWM换到其它引脚来输出,这只能在它允许的输出通道上来实现。
后来他查了下资料说,用TIM1计时器控制PWM输出有3个通道,你把它换到其它2个通道吧,我只能去试一试。
它的主程序十分简单,内容如下:
- int main(void)
- {
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n",SystemCoreClock);
- TIM1_PWMOut_Init( 899, 0, 500 );
- while(1);
- }
复制代码在主程序是无从下手了,只能去看所调用的函数,其内容如下: - void TIM1_PWMOut_Init( u16 arr, u16 psc, u16 ccp )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init( GPIOA, &GPIO_InitStructure );
- TIM_TimeBaseInitStructure.TIM_Period = arr;
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
- #if (PWM_MODE == PWM_MODE1)
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- #elif (PWM_MODE == PWM_MODE2)
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
- #endif
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse = ccp;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OC1Init( TIM1, &TIM_OCInitStructure );
- TIM_CtrlPWMOutputs(TIM1, ENABLE );
- TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
- TIM_ARRPreloadConfig( TIM1, ENABLE );
- TIM_Cmd( TIM1, ENABLE );
- }
复制代码由程序可以看出,它是以CH1的PA8来输出PWM调节的,要换到CH2或CH3,也就是换到PA9或PA10。 这是好改的,将GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;改: GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9; 或 GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10; 即可。
但是,这只说明你让PA9或PA10使能为了I/O口,至于TIM1是否往那送,就是另一个问题了。你需要让TIM1工作在CH2或CH3上才行。 看遍了整个函数也没见到关于CH1的影子,也就无从轻易地改为CH2或CH3这么容易。 再仔细读程序就有些端倪,看看TIM_OC1Init(TIM1, &TIM_OCInitStructure );中有1的影子,把它改了,换成2。 在往下看还有个带1的,把它也该了,换成:TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable ); 这回应该没问题了吧? 将程序编译下载后,让人傻眼了,LED灯毫无变化,你猜为什么?
哈哈,答案会放在下一期“通往解bug的路上”给出。
|