请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32使用标准库存在bug?还是我使用不对?

[复制链接]
单片机_电子爱好者 提问时间:2018-8-28 19:55 /
本帖最后由 单片机_电子爱好者 于 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寄存器,发现和其他路设置相同,没有不一样的地方





收藏 评论8 发布时间:2018-8-28 19:55

举报

8个回答
wenyangzeng 回答时间:2018-8-28 21:46:28
是否bug不该过早定论。
运行中要初始化定时器,应该先关闭定时器吧?
TIM_Cmd(TIM1, DISABLE);

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

tyhjrwx2011 回答时间:2018-8-28 23:13:31
只有初始化代码,没有对应中断处理函数的代码,也不知道你“人为控制”怎么设置的初始化,分析起来有点难度呀

比如用到了其他中断,但是未清除,肯定有问题

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

feixiang20 回答时间:2018-8-29 02:20:02
在keil–edit–configuration中encoding改为chinese-GB2312

评分

参与人数 1蝴蝶豆 +1 收起 理由
zero99 + 1

查看全部评分

单片机_电子爱好者 回答时间:2018-8-30 13:33:29
今天改了下字体再把初始函数发一下(字体没有乱码就是看着有点别扭)
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);       
}
单片机_电子爱好者 回答时间:2018-8-30 13:34:49
wenyangzeng 发表于 2018-8-28 21:46
是否bug不该过早定论。
运行中要初始化定时器,应该先关闭定时器吧?
TIM_Cmd(TIM1, DISABLE); ...

我试过加TIM_Cmd(TIM1, DISABLE);一样的有问题,我加了TIM_DeInit(TIM1);  都没有什么用
单片机_电子爱好者 回答时间:2018-8-30 13:37:35
feixiang20 发表于 2018-8-29 02:20
在keil–edit–configuration中encoding改为chinese-GB2312

谢谢,改了字体,不乱码了,看着有点别扭,改成UTF-8比较好,就是转来转去麻烦,还是KEIL4好使
单片机_电子爱好者 回答时间:2018-8-30 13:43:56
中断函数也发一下
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寄存器设置都正常
单片机_电子爱好者 回答时间:2018-8-30 13:49:24
发一下中断函数:
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寄存器,发现和其他路设置相同,没有不一样的地方

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版