本帖最后由 单片机_电子爱好者 于 2018-8-30 13:50 编辑 这几天一直在搞stm32f0的芯片,在使用stm的高级定时器tim输出pwm时,正常配置输出正常,但是如果每隔一定时间(人为控制)对TIM1的PWM输出初始化,就会有可能PWM输出不了,一旦输出不了,就再也不能输出,必须重新上电才可以,不知道什么原因造成的?麻烦又遇到的人或者高手指导下,谢谢 (上一次对TIM16初始化也造成了TIM1 pwm输出有问题,和上面情况类似,后来只对tim16初始化一次就好了,一直不知道为什么,今天又遇到了,很奇怪) 初始化函数如下(keil5的编码没有改,注释全部乱码了): void TIM1_PWM_Config(void) { TIM_TimeBaseInitTypeDef TIM_Time1BaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; uint16_t TimerPeriod = 0; /* TIM1 µÄÅäÖà --------------------------------------------------- TIM1 ÊäÈëʱÖÓ(TIM1CLK) ÉèÖÃΪ APB2 ʱÖÓ (PCLK2) => TIM1CLK = PCLK2 = SystemCoreClock TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock Ϊ48 MHz */ TimerPeriod = (SystemCoreClock / DEF_PWMFRE); /* TIM1 ʱÖÓʹÄÜ */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); // /* TIM1 ʹÄÜ*/ // TIM_Cmd(TIM1, DISABLE); /* Time ¶¨Ê±»ù´¡ÉèÖÃ*/ TIM_Time1BaseStructure.TIM_Prescaler = 0; TIM_Time1BaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; /* ÉèÖöÔÆëģʽ Time TIM_CounterMode_Up¶¨Ê±ÉèÖÃΪÉÏÉýÑؼÆËãģʽ*/ TIM_Time1BaseStructure.TIM_Period = TimerPeriod;//PWM_PERIOD TIM_Time1BaseStructure.TIM_ClockDivision = 0; TIM_Time1BaseStructure.TIM_RepetitionCounter = 0; // Öظ´¼ÆÊýÉèÖà TIM_TimeBaseInit(TIM1, &TIM_Time1BaseStructure); /* ƵµÀ1,2,3,4µÄPWM ģʽÉèÖà */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable ;//TIM_OutputState_Enable; //PWMÊä³öʹÄÜλ TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable ;//TIM_OutputNState_Enable; //»¥²¹PWMÊä³öʹÄÜλ TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //PWM 1ΪÓÐЧµçƽ ¿ÉÉèÖõçƽ·´×ª TIM_OCPolarity_Low TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //PWM»¥²¹ 0ΪÎÞЧµçƽ ¿ÉÉèÖõçƽ·´×ª TIM_OCPolarity_Low TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OCInitStructure.TIM_Pulse = 0; //¸³Õ¼¿Õ±ÈÖµ TIM_OC1Init(TIM1, &TIM_OCInitStructure);//ʹÄÜƵµÀ1ÅäÖà TIM_OCInitStructure.TIM_Pulse = 0; //¸³Õ¼¿Õ±ÈÖµ TIM_OC2Init(TIM1, &TIM_OCInitStructure);//ʹÄÜƵµÀ2ÅäÖà TIM_OCInitStructure.TIM_Pulse = 0; //¸³Õ¼¿Õ±ÈÖµ TIM_OC3Init(TIM1, &TIM_OCInitStructure);//ʹÄÜƵµÀ3ÅäÖà //------ʹÄܱȽÏËÄͨµÀ------------------------------------ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable ;//TIM_OutputState_Enable; // //TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable ; //ʹÓÃADC_ExternalTrigConv_T1_CC4´¥·¢ÐèÒª´ò¿ªcc4Êä³ö²ÅÄÜ´¥·¢ADC TIM_OCInitStructure.TIM_Pulse = PWM_PERIOD_30P; TIM_OC4Init(TIM1, &TIM_OCInitStructure); //TIM_ITConfig(TIM1,TIM_IT_CC4, ENABLE); //TIM1 ±È½ÏËÄÖÐ¶Ï TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);//Ñ¡ÔñTRGOÊä³ö TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable); // ½ûÖ¹OC4Ԥװֵ //------ÅäÖÃTIME1 BREAK PB12¹¦ÄÜ----------------------------------- RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_Init(GPIOB , &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_2); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 48; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; //TIM_BreakPolarity_Low //TIM_AutomaticOutput_Enable ɲ³µºó£¬É²³µÊäÈëµçƽ±äΪÎÞЧºó£¬ÏÂÒ»¸öÂö³åÖÜÆÚ£¬×Ô¶¯»Ö¸´Âö³åÊä³ö //TIM_AutomaticOutput_Disable ɲ³µºó£¬Âö³åÊä³öÓÀ¾Ã½ûÖ¹£¬³ý·ÇÊÖ¶¯µ÷ÓÃTIM_CtrlPWMOutputs(TIM1, ENABLE)£¬·ñÔò²»ÄÜÆô¶¯pwm TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_ITConfig(TIM1,TIM_IT_Break, ENABLE); //TIME1 COM?? //TIM_CCPreloadControl(TIM1, ENABLE); TIM_ITConfig(TIM1,TIM_IT_Update, DISABLE); //TIME1 COM?? NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //ËÀÇøʱ¼äÉèÖà 0.93us TIM1->BDTR|=0x002D; //-------------------------------------------------------- /* TIM1 ʹÄÜ*/ TIM_Cmd(TIM1, ENABLE); /* TIM1 Ö÷Êä³öʹÄÜ */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }发一下中断函数: void TIM1_CC_IRQHandler() { if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) // CC4比较中断 { ...和tim1操作没有关系代码..... TIM_ClearITPendingBit(TIM1, TIM_IT_CC4 ); } } 在网上找到遇到类似问题的帖子 http://bbs.21ic.com/icview-350027-1-1.html 我的问题是多次初始化之后三路PWM中有一路输出不了,并且总是同一路,在线仿真观测改路的OC寄存器,发现和其他路设置相同,没有不一样的地方 |
运行中要初始化定时器,应该先关闭定时器吧?
TIM_Cmd(TIM1, DISABLE);
评分
查看全部评分
比如用到了其他中断,但是未清除,肯定有问题
评分
查看全部评分
评分
查看全部评分
void TIM1_PWM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_Time1BaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t TimerPeriod = 0;
/* TIM1 的配置 ---------------------------------------------------
TIM1 输入时钟(TIM1CLK) 设置为 APB2 时钟 (PCLK2)
=> TIM1CLK = PCLK2 = SystemCoreClock
TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
SystemCoreClock 为48 MHz */
TIM_DeInit(TIM1); // 初始化TIM1
//TimerPeriod = (SystemCoreClock / DEF_PWMFRE);
TimerPeriod = (48000000 / DEF_PWMFRE);
/* TIM1 时钟使能 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);
/* TIM1 使能*/
TIM_Cmd(TIM1, DISABLE);
/* Time 定时基础设置*/
TIM_Time1BaseStructure.TIM_Prescaler = 0;
TIM_Time1BaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; /* 设置对齐模式 Time TIM_CounterMode_Up定时设置为上升沿计算模式*/
TIM_Time1BaseStructure.TIM_Period = TimerPeriod;//PWM_PERIOD
TIM_Time1BaseStructure.TIM_ClockDivision = 0;
TIM_Time1BaseStructure.TIM_RepetitionCounter = 0; // 重复计数设置
TIM_TimeBaseInit(TIM1, &TIM_Time1BaseStructure);
/* 频道1,2,3,4的PWM 模式设置 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable ;//TIM_OutputState_Enable; //PWM输出使能位
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable ;//TIM_OutputNState_Enable; //互补PWM输出使能位
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //PWM 1为有效电平 可设置电平反转 TIM_OCPolarity_Low
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //PWM互补 0为无效电平 可设置电平反转 TIM_OCPolarity_Low
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OCInitStructure.TIM_Pulse = 0; //赋占空比值
TIM_OC1Init(TIM1, &TIM_OCInitStructure);//使能频道1配置
TIM_OCInitStructure.TIM_Pulse = 0; //赋占空比值
TIM_OC2Init(TIM1, &TIM_OCInitStructure);//使能频道2配置
TIM_OCInitStructure.TIM_Pulse = 0; //赋占空比值
TIM_OC3Init(TIM1, &TIM_OCInitStructure);//使能频道3配置
//------使能比较四通道------------------------------------
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable ;//TIM_OutputState_Enable; //
//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable ; //使用ADC_ExternalTrigConv_T1_CC4触发需要打开cc4输出才能触发ADC
TIM_OCInitStructure.TIM_Pulse = PWM_PERIOD_30P;
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
//TIM_ITConfig(TIM1,TIM_IT_CC4, ENABLE); //TIM1 比较四中断
TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);//选择TRGO输出
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable); // 禁止OC4预装值
//------配置TIME1 BREAK PB12功能-----------------------------------
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOB , &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_2);
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 48;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; //TIM_BreakPolarity_Low
//TIM_AutomaticOutput_Enable 刹车后,刹车输入电平变为无效后,下一个脉冲周期,自动恢复脉冲输出
//TIM_AutomaticOutput_Disable 刹车后,脉冲输出永久禁止,除非手动调用TIM_CtrlPWMOutputs(TIM1, ENABLE),否则不能启动pwm
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_ITConfig(TIM1,TIM_IT_Break, ENABLE); //TIME1 COM??
//TIM_CCPreloadControl(TIM1, ENABLE);
TIM_ITConfig(TIM1,TIM_IT_Update, DISABLE); //TIME1 COM??
NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//死区时间设置 0.93us
TIM1->BDTR|=0x002D;
//--------------------------------------------------------
/* TIM1 使能*/
TIM_Cmd(TIM1, ENABLE);
/* TIM1 主输出使能 */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
我试过加TIM_Cmd(TIM1, DISABLE);一样的有问题,我加了TIM_DeInit(TIM1); 都没有什么用
谢谢,改了字体,不乱码了,看着有点别扭,改成UTF-8比较好,就是转来转去麻烦,还是KEIL4好使
void TIM1_CC_IRQHandler()
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) // CC4比较中断
{
....中间代码省略(没有设计到TIM1操作的代码)....
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4 );
}
}
在网上要搜到差不多类似情况的帖子
http://bbs.21ic.com/icview-350027-1-1.html
我的情况是三路PWM有一路输出不了,而且每次都是同一路,仿真时该路的OC寄存器设置都正常
void TIM1_CC_IRQHandler()
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET) // CC4比较中断
{
...和tim1操作没有关系代码.....
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4 );
}
}
在网上找到遇到类似问题的帖子 http://bbs.21ic.com/icview-350027-1-1.html
我的问题是多次初始化之后三路PWM中有一路输出不了,并且总是同一路,在线仿真观测改路的OC寄存器,发现和其他路设置相同,没有不一样的地方