[技术问答] 定时器0和定时器3同时使用,出现定时器3无法正常工作

[复制链接]
2781|13
手机看帖
扫描二维码
随时随地手机跟帖
Tobbie|  楼主 | 2021-10-20 17:01 | 显示全部楼层 |阅读模式
以下定时器配置,基本是例程,问题:两定时器同时启动run程序后,只有定时器1运行,定时器3没反应,将定时器0,run函数注释后两定时器工作,但没法调整pwm
//Timer3 配置
void App_Timer3Cfg(uint16_t u16Period)
{
    uint16_t                    u16ArrValue;
    uint16_t                    u16CntValue;
    stc_tim3_mode0_cfg_t     stcTim3BaseCfg;

    //结构体初始化清零
    DDL_ZERO_STRUCT(stcTim3BaseCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Base Timer外设时钟使能

    stcTim3BaseCfg.enWorkMode = Tim3WorkMode0;              //定时器模式
    stcTim3BaseCfg.enCT       = Tim3Timer;                  //定时器功能,计数时钟为内部PCLK
    stcTim3BaseCfg.enPRS      = Tim3PCLKDiv16;              //PCLK/16
    stcTim3BaseCfg.enCntMode  = Tim316bitArrMode;           //自动重载16位计数器/定时器
    stcTim3BaseCfg.bEnTog     = FALSE;
    stcTim3BaseCfg.bEnGate    = FALSE;
    stcTim3BaseCfg.enGateP    = Tim3GatePositive;

    Tim3_Mode0_Init(&stcTim3BaseCfg);                       //TIM3 的模式0功能初始化

    u16ArrValue = 0x10000 - u16Period ;

    Tim3_M0_ARRSet(u16ArrValue);                            //设置重载值(ARR = 0x10000 - 周期)

    u16CntValue = 0x10000 - u16Period;

    Tim3_M0_Cnt16Set(u16CntValue);                          //设置计数初值

    Tim3_ClearIntFlag(Tim3UevIrq);                          //清中断标志
    Tim3_Mode0_EnableIrq();                                 //使能TIM3中断(模式0时只有一个中断)
    EnableNvic(TIM3_IRQn, IrqLevel0, TRUE);                 //TIM3 开中断
               
               
}
void Tim3_IRQHandler(void)
{
    //Timer3 模式0 计时溢出中断
    if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
    {                          
        Get_Timer();//程序任务运行时间获取
        Tim3_ClearIntFlag(Tim3UevIrq);  //Timer3模式0 中断标志清除
     }
}

/***************************************************************************
*   函 数 名: App_Timer0Cfg
*   功能说明: 定时器0初始化
*   形    参:
*   返 回 值:
*   说    明:
***************************************************************************/
void App_Timer0Cfg(uint16_t u16Period, uint16_t u16CHxACompare, uint16_t u16CHxBCompare)
{
    uint16_t                   u16CntValue;
    uint8_t                    u8ValidPeriod;
    stc_bt_mode23_cfg_t        stcBtBaseCfg;
    stc_bt_m23_compare_cfg_t   stcBtPortCmpCfg;

    //结构体初始化清零
//    DDL_ZERO_STRUCT(stcBtBaseCfg);
//    DDL_ZERO_STRUCT(stcBtPortCmpCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE);   //Base Timer外设时钟

    stcBtBaseCfg.enWorkMode    = BtWorkMode3;              //三角波模式
    stcBtBaseCfg.enCT          = BtTimer;                  //定时器功能,计数时钟为内部PCLK
    stcBtBaseCfg.enPRS         = BtPCLKDiv1;               //PCLK
    //stcBtBaseCfg.enCntDir    = BtCntUp;                  //向上计数,在三角波模式中只读
    stcBtBaseCfg.enPWMTypeSel  = BtIndependentPWM;         //独立输出PWM     //BtComplementaryPWM;
    stcBtBaseCfg.enPWM2sSel    = BtSinglePointCmp;         //单点比较功能
    stcBtBaseCfg.bOneShot      = FALSE;                    //循环计数
    stcBtBaseCfg.bURSSel       = FALSE;                    //上下溢更新

    Bt_Mode23_Init(TIM0, &stcBtBaseCfg);                   //TIM0 模式23功能初始化

    Bt_M23_ARRSet(TIM0, u16Period, TRUE);                  //设置重载值,并使能缓存

    Bt_M23_CCR_Set(TIM0, BtCCR0A, u16CHxACompare);         //设置比较值A

    Bt_M23_CCR_Set(TIM0, BtCCR0B, u16CHxBCompare);         //设置比较值B

    stcBtPortCmpCfg.enCH0ACmpCtrl   = BtPWMMode2;          //OCREFA输出控制OCMA:PWM模式2
    stcBtPortCmpCfg.enCH0APolarity  = BtPortPositive;      //正常输出
    stcBtPortCmpCfg.bCh0ACmpBufEn   = TRUE;                //A通道缓存控制
    stcBtPortCmpCfg.enCh0ACmpIntSel = BtCmpIntNone;        //A通道比较控制:无

    stcBtPortCmpCfg.enCH0BCmpCtrl   = BtPWMMode2;          //OCREFB输出控制OCMB:PWM模式2
    stcBtPortCmpCfg.enCH0BPolarity  = BtPortPositive;      //正常输出
    stcBtPortCmpCfg.bCH0BCmpBufEn   = TRUE;                //B通道缓存控
    stcBtPortCmpCfg.enCH0BCmpIntSel = BtCmpIntNone;        //B通道比较控制:无

    Bt_M23_PortOutput_Cfg(TIM0, &stcBtPortCmpCfg);         //比较输出端口控制

    u8ValidPeriod = 1;                                     //事件更新周期设置,0表示三角波波每半周期更新一次,每+1代表延迟半个周期
    Bt_M23_SetValidPeriod(TIM0,u8ValidPeriod);             //间隔周期设置

    u16CntValue = 0;
    Bt_M23_Cnt16Set(TIM0, u16CntValue);                    //设置计数初值

    Bt_ClearAllIntFlag(TIM0);                              //清中断标志
    Bt_Mode23_EnableIrq(TIM0,BtUevIrq);                    //使能TIM0 UEV更新中断
    EnableNvic(TIM0_IRQn, IrqLevel3, TRUE);                //TIM0中断使能
                                       
}
96708616fd9ab9a4b0.png
56957616fda1027a78.png


使用特权

评论回复
martinhu| | 2021-10-21 13:46 | 显示全部楼层
这两个函数注释之后,Timer0为社么还能运行???

33286170fe96ca6f9.png

使用特权

评论回复
Tobbie|  楼主 | 2021-10-21 15:15 | 显示全部楼层
martinhu 发表于 2021-10-21 13:46
这两个函数注释之后,Timer0为社么还能运行???

我也想知道,现象就是我的电机还在转,示波器测出io有pwm输出

使用特权

评论回复

评论

martinhu 2021-10-21 18:01 回复TA
@Tobbie :要看什么电机了 
Tobbie 2021-10-21 16:26 回复TA
@martinhu :timer0有两路独立输出pwm,不能用吗 
martinhu 2021-10-21 16:04 回复TA
你用timer0驱动电机? 
Tobbie|  楼主 | 2021-10-21 16:40 | 显示全部楼层
Tobbie 发表于 2021-10-21 15:15
我也想知道,现象就是我的电机还在转,示波器测出io有pwm输出

搞错了,没有pwm输出,IO拉高而已

使用特权

评论回复

评论

Tobbie 2021-10-21 23:21 回复TA
@martinhu :链接:https://pan.baidu.com/s/1UH0vqtREX91Y3X7YjVd9Aw 提取码:8888 论坛上传还不熟悉,放网盘了,帮忙看下 
martinhu 2021-10-21 18:02 回复TA
整个工程发出来看看 
martinhu| | 2021-10-22 09:23 | 显示全部楼层
编译过不了
450856172128e9bb81.png

使用特权

评论回复
Tobbie|  楼主 | 2021-10-22 10:07 | 显示全部楼层

你加这段代码进去看下,这边运行没报错的
typedef unsigned           int u8;
typedef unsigned           int u16;
typedef unsigned           int u32;

492161721bd04b043.png 5407361721c87b9087.png

使用特权

评论回复
martinhu| | 2021-10-22 10:26 | 显示全部楼层

放开楼主注释的Timer0启动的104,105行,Timer0和Timer3都能运行啊,
timer3中断正常,timer0也能输出PWM
507696172209da19c3.png
86744617220b4561b1.png
620046172211941d65.png

使用特权

评论回复
Tobbie|  楼主 | 2021-10-23 13:52 | 显示全部楼层
martinhu 发表于 2021-10-22 10:26
放开楼主注释的Timer0启动的104,105行,Timer0和Timer3都能运行啊,
timer3中断正常,timer0也能输出PWM
...

感谢

使用特权

评论回复
Tobbie|  楼主 | 2021-10-23 15:53 | 显示全部楼层
已找到问题,这里开了更新中断,没有清除对应标志位,导致一直卡在定时器0的中断函数
712916173bedee7b9c.png

使用特权

评论回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则