打印
[综合信息]

华大HC32F460KETA TIMER6输出三路PWM配置问题

[复制链接]
1981|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 SingleYork2021 于 2021-11-17 15:02 编辑

想用HC32F460KETA TIMER6输出三路PWM,使用到的是TIMER6_1_PWMB、TIMER6_2_PWMB、TIMER6_3_PWMB,其中部分配置代码如下:

    /*---------------------------------------------------*/
   
    stcTIM6BaseCntCfg.enCntMode   = Timer6CntTriangularModeA;               //Triangular wave mode
    stcTIM6BaseCntCfg.enCntDir    = Timer6CntDirUp;                         //Counter counting up
    stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv1;                         //Count clock: pclk 168M
    Timer6_Init(M4_TMR61, &stcTIM6BaseCntCfg);                              //timer6 PWM frequency, count mode and clk config

    u16Period_1  = u32Pclk0/(TIMER6_PWM1B_Out_Fre*2);
    Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1);                 //period set

    u16Compare_1 = u16Period_1/2;                                           //50%占空比
//    Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, u16Compare_1);   //Set General Compare RegisterA Value
    Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, u16Compare_1);   //Set General Compare RegisterC Value as buffer register of GCMAR
   
    /*PWMA/PWMB output buf config*/
    stcGCMPBufCfg.bEnGcmpTransBuf    = true;
    stcGCMPBufCfg.enGcmpBufTransType = Timer6GcmpPrdSingleBuf;              //Single buffer transfer
    Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg);             //GCMAR buffer transfer set
    Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg);             //GCMBR buffer transfer set
   
//    stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable
//    stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep;                      //PWMA port output keep former level when CNTER value match PERAR
//    stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv;                       //PWMA port output inverse level when CNTER value match with GCMAR
//    stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;                       //PWMA output status is decide by STACA STPCA when CNTER start and stop
//    stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER start
//    stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER stop
//    stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;
//    Timer6_PortOutputConfig(M4_TMR61, Timer6PWMA, &stcTIM6PWMxCfg);
//    Timer6_SetFunc(M4_TMR61, Timer6PWMA, Timer6ModeCompareOutput);          //Compare output function

    stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable
    stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep;                      //PWMB port output keep former level when CNTER value match PERAR
    stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv;                       //PWMB port output inverse level when CNTER value match with GCMBR
    stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;                       //PWMB output status is decide by STACB STPCB when CNTER start and stop
    stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutHigh;                      //PWMB port output set high level when CNTER start
    stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;                       //PWMB port output set low level when CNTER stop
    stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;
    Timer6_PortOutputConfig(M4_TMR61, Timer6PWMB, &stcTIM6PWMxCfg);
    Timer6_SetFunc(M4_TMR61, Timer6PWMB, Timer6ModeCompareOutput);          //Compare output function

    Timer6_SetDeadTimeValue(M4_TMR61, Timer6DeadTimUpAR, 0u);               //Set dead time value (up count)

    stcDeadTimeCfg.bEnDeadtime     = true;                                  //Enable Hardware DeadTime
    stcDeadTimeCfg.bEnDtBufUp      = false;                                 //Disable buffer transfer
    stcDeadTimeCfg.bEnDtBufDwn     = false;                                 //Disable buffer transfer
    stcDeadTimeCfg.bEnDtEqualUpDwn = true;                                  //Make the down count dead time value equal to the up count dead time setting
    Timer6_ConfigDeadTime(M4_TMR61, &stcDeadTimeCfg);                       //Hardware dead time function config
   
    /*config interrupt*/
    /* Enable timer61 under flow interrupt */
    Timer6_ConfigIrq(M4_TMR61, Timer6INTENUDF, true);

    stcIrqRegiConf.enIRQn      = Int018_IRQn;                               //Register INT_TMR62_GUDF Int to Vect.No.019
    stcIrqRegiConf.enIntSrc    = INT_TMR61_GUDF;                            //Select Event interrupt function
    stcIrqRegiConf.pfnCallback = &Timer61_UnderFlow_CallBack;               //Callback function
    enIrqRegistration(&stcIrqRegiConf);                                     //Registration IRQ

    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);                            //Clear Pending
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);           //Set priority
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);                                  //Enable NVIC
有几个地方不太明白:

1、Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1); 这里为什么要设置Timer6PeriodA,看到库配置里面还有Timer6PeriodB和Timer6PeriodC可选,这里有什么特别含义吗?手册上实在没看懂!

2、下面这两个配置:
Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg);             //GCMAR buffer transfer set

Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg);             //GCMBR buffer transfer set
如果我只是使用PWMB的话,第一句“Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg); ”是否可以去掉?我试过直接去掉,但是输出PWM就有问题了,跟我配置的不一样,是不是还需要修改其他地方?我试了屏蔽下面这部分代码,对PWMB输出没有影响:

    stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable
    stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep;                      //PWMA port output keep former level when CNTER value match PERAR
    stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv;                       //PWMA port output inverse level when CNTER value match with GCMAR
    stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;                       //PWMA output status is decide by STACA STPCA when CNTER start and stop
    stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER start
    stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER stop
    stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;
    Timer6_PortOutputConfig(M4_TMR61, Timer6PWMA, &stcTIM6PWMxCfg);
    Timer6_SetFunc(M4_TMR61, Timer6PWMA, Timer6ModeCompareOutput);          //Compare output function





使用特权

评论回复
沙发
SingleYork2021|  楼主 | 2021-11-17 15:12 | 只看该作者
有没有大佬能帮忙看下,谢谢!

使用特权

评论回复
板凳
martinhu| | 2021-11-18 13:55 | 只看该作者
1、Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1); 这里为什么要设置Timer6PeriodA,看到库配置里面还有Timer6PeriodB和Timer6PeriodC可选,这里有什么特别含义吗?手册上实在没看懂!
Timer6PeriodA,这个是直接的周期寄存器,Timer6PeriodB和Timer6PeriodC是周期的一级缓存和二级缓存寄存器,
如果使能了一级缓存,就需要设置Timer6PeriodB,这样在特定的缓存传输点,数据从Timer6PeriodB--->Timer6PeriodA;而且每次更改周期的时候,需要改写寄存器Timer6PeriodB;
如果使能的是二级缓存,就需要设置Timer6PeriodBTimer6PeriodC,那么在特定的传输点,数据从Timer6PeriodC--->Timer6PeriodB  -->Timer6PeriodA;需要经历两次缓存传输才能起作用。而且每次更改周期的时候,需要改写寄存器Timer6PeriodC;

2、下面这两个配置:
Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg);             //GCMAR buffer transfer set

Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg);             //GCMBR buffer transfer set
如果我只是使用PWMB的话,第一句“Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMA, &stcGCMPBufCfg); ”是否可以去掉?我试过直接去掉,但是输出PWM就有问题了,跟我配置的不一样,是不是还需要修改其他地方?我试了屏蔽下面这部分代码,对PWMB输出没有影响

因为你使能了死区功能,使用死区功能的时候,CHA和CHB默认互补输出,只要设置GCMAR,或者GCMAR的缓存寄存器GCMCR、GCMER(根据使能一级或者二级缓存而定,原理周期缓存功能)。
如果楼主只是单纯输出一路PWM,就不要设置硬件死区功能。

使用特权

评论回复
地板
SingleYork2021|  楼主 | 2021-11-19 15:08 | 只看该作者
martinhu 发表于 2021-11-18 13:55
1、Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1); 这里为什么要设置Timer6PeriodA,看到库配置 ...

首先,感谢您的这么仔细的回答,如您所说的话,我如果只需要输出PWMB的话,是否直接去掉死区配置那部分的代码,按照如下设置就可以了?(因板子寄给别人测试了,暂时没办法验证,所以先咨询一下,回头改下做研究)
    /*---------------------------------------------------*/


    stcTIM6BaseCntCfg.enCntMode   = Timer6CntTriangularModeA;               //Triangular wave mode

    stcTIM6BaseCntCfg.enCntDir    = Timer6CntDirUp;                         //Counter counting up

    stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv1;                         //Count clock: pclk 168M

    Timer6_Init(M4_TMR61, &stcTIM6BaseCntCfg);                              //timer6 PWM frequency, count mode and clk config



    u16Period_1  = u32Pclk0/(TIMER6_PWM1B_Out_Fre*2);

    Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1);                 //period set


    u16Compare_1 = u16Period_1/2;                                           //50%占空比

Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, u16Compare_1);   //Set General Compare RegisterA Value

    Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, u16Compare_1);   //Set General Compare RegisterC Value as buffer register of GCMAR


    /*PWMA/PWMB output buf config*/

    stcGCMPBufCfg.bEnGcmpTransBuf    = true;

    stcGCMPBufCfg.enGcmpBufTransType = Timer6GcmpPrdSingleBuf;              //Single buffer transfer

    Timer6_SetGeneralBuf(M4_TMR61, Timer6PWMB, &stcGCMPBufCfg);             //GCMBR buffer transfer set


    stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable

    stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep;                      //PWMB port output keep former level when CNTER value match PERAR

    stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv;                       //PWMB port output inverse level when CNTER value match with GCMBR

    stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;                       //PWMB output status is decide by STACB STPCB when CNTER start and stop

    stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutHigh;                      //PWMB port output set high level when CNTER start

    stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;                       //PWMB port output set low level when CNTER stop

    stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;

    Timer6_PortOutputConfig(M4_TMR61, Timer6PWMB, &stcTIM6PWMxCfg);

    Timer6_SetFunc(M4_TMR61, Timer6PWMB, Timer6ModeCompareOutput);          //Compare output function


    /*config interrupt*/

    /* Enable timer61 under flow interrupt */

    Timer6_ConfigIrq(M4_TMR61, Timer6INTENUDF, true);


    stcIrqRegiConf.enIRQn      = Int018_IRQn;                               //Register INT_TMR62_GUDF Int to Vect.No.019

    stcIrqRegiConf.enIntSrc    = INT_TMR61_GUDF;                            //Select Event interrupt function

    stcIrqRegiConf.pfnCallback = &Timer61_UnderFlow_CallBack;               //Callback function

    enIrqRegistration(&stcIrqRegiConf);                                     //Registration IRQ


    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);                            //Clear Pending

    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);           //Set priority

    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);                                  //Enable NVIC
另外,还有一个地方不是很明白,就是两面两端代码:

 Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareA, u16Compare_1); //Set General Compare RegisterA Value

Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareC, u16Compare_1); //Set General Compare RegisterC Value as buffer register of GCMAR
看了手册,这个地方有Timer6GenCompareA、Timer6GenCompareB、Timer6GenCompareC、Timer6GenCompareD等几个寄存器,但是手册上的波形,也没具体说明A、B、C、D等是什么意思,所以感觉一头雾水,还请帮忙解答一下,谢谢!



使用特权

评论回复
5
martinhu| | 2021-11-22 09:13 | 只看该作者
本帖最后由 martinhu 于 2021-11-22 09:14 编辑

首先,如果你用的是CHB通道输出PWM,那么这里的比较寄存器应该是用的GCMBR和GCMDR(单次缓存)
要修改CHB占空比的时候,就设置GCMDR寄存器。
这功能用户手册上有,你可以再看看。
Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareB, u16Compare_1);   //Set General Compare RegisterA Value
Timer6_SetGeneralCmpValue(M4_TMR61, Timer6GenCompareD, u16Compare_1);   //Set General Compare RegisterC Value as buffer register of GCMAR


如果单路PWM,你需要使用三角波模式Timer6CntTriangularModeA,比较逻辑就是下面这个,
注意,如果半路停止定时器,一定要清零计数器,否则有效电平可以发送变化
stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep; //PWMB port output keep former level when CNTER value match PERAR
stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv; //PWMB port output inverse level when CNTER value match with GCMBR

如果单路PWM,仅仅是PWM,不需要中心对齐,那么用锯齿波模式就可以了。电平比较翻转逻辑可以改成输出高或者输出低。
stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareHigh; //Timer6PWMxCompareLow      //
stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareLow;  //Timer6PWMxCompareHigh     //


使用特权

评论回复
6
HC11425| | 2021-11-22 10:39 | 只看该作者
何不使用TIME4呢   TIMER4是使用在电机应用  我有应用代码  中心对齐或者边沿对齐
华大一级代理商  131 6807 9092 喻生

使用特权

评论回复
7
SingleYork2021|  楼主 | 2021-11-23 14:00 | 只看该作者
martinhu 发表于 2021-11-22 09:13
首先,如果你用的是CHB通道输出PWM,那么这里的比较寄存器应该是用的GCMBR和GCMDR(单次缓存)
要修改CHB占 ...

#技术资源# 好的,回答的非常仔细,感谢!

使用特权

评论回复
8
SingleYork2021|  楼主 | 2021-11-23 14:01 | 只看该作者
HC11425 发表于 2021-11-22 10:39
何不使用TIME4呢   TIMER4是使用在电机应用  我有应用代码  中心对齐或者边沿对齐
华大一级代理商  131 680 ...

第一次使用,也不是很懂,硬件已经设计成TIMER6了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

12

帖子

0

粉丝