[综合信息] 华大HC32F460KETA TIMER6输出三路PWM配置问题

[复制链接]
2565|7
 楼主| SingleYork2021 发表于 2021-11-17 15:02 | 显示全部楼层 |阅读模式
本帖最后由 SingleYork2021 于 2021-11-17 15:02 编辑

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

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

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

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

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

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

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

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

  51.     NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);                            //Clear Pending
  52.     NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_03);           //Set priority
  53.     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输出没有影响:

  1.     stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable
  2.     stcTIM6PWMxCfg.enPerc     = Timer6PWMxCompareKeep;                      //PWMA port output keep former level when CNTER value match PERAR
  3.     stcTIM6PWMxCfg.enCmpc     = Timer6PWMxCompareInv;                       //PWMA port output inverse level when CNTER value match with GCMAR
  4.     stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;                       //PWMA output status is decide by STACA STPCA when CNTER start and stop
  5.     stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER start
  6.     stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;                       //PWMA port output set low level when CNTER stop
  7.     stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;
  8.     Timer6_PortOutputConfig(M4_TMR61, Timer6PWMA, &stcTIM6PWMxCfg);
  9.     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的话,是否直接去掉死区配置那部分的代码,按照如下设置就可以了?(因板子寄给别人测试了,暂时没办法验证,所以先咨询一下,回头改下做研究)
  1.     /*---------------------------------------------------*/


  2.     stcTIM6BaseCntCfg.enCntMode   = Timer6CntTriangularModeA;               //Triangular wave mode

  3.     stcTIM6BaseCntCfg.enCntDir    = Timer6CntDirUp;                         //Counter counting up

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

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



  6.     u16Period_1  = u32Pclk0/(TIMER6_PWM1B_Out_Fre*2);

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


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

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

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


  11.     /*PWMA/PWMB output buf config*/

  12.     stcGCMPBufCfg.bEnGcmpTransBuf    = true;

  13.     stcGCMPBufCfg.enGcmpBufTransType = Timer6GcmpPrdSingleBuf;              //Single buffer transfer

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


  15.     stcTIM6PWMxCfg.bOutEn     = true;                                       //Output enable

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

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

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

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

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

  21.     stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;

  22.     Timer6_PortOutputConfig(M4_TMR61, Timer6PWMB, &stcTIM6PWMxCfg);

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


  24.     /*config interrupt*/

  25.     /* Enable timer61 under flow interrupt */

  26.     Timer6_ConfigIrq(M4_TMR61, Timer6INTENUDF, true);


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

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

  29.     stcIrqRegiConf.pfnCallback = &Timer61_UnderFlow_CallBack;               //Callback function

  30.     enIrqRegistration(&stcIrqRegiConf);                                     //Registration IRQ


  31.     NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);                            //Clear Pending

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

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

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

  2. 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等是什么意思,所以感觉一头雾水,还请帮忙解答一下,谢谢!


01.png
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
43817619aed2030332.png

如果单路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     //


HC11425 发表于 2021-11-22 10:39 | 显示全部楼层
何不使用TIME4呢   TIMER4是使用在电机应用  我有应用代码  中心对齐或者边沿对齐
华大一级代理商  131 6807 9092 喻生
 楼主| SingleYork2021 发表于 2021-11-23 14:00 | 显示全部楼层
martinhu 发表于 2021-11-22 09:13
首先,如果你用的是CHB通道输出PWM,那么这里的比较寄存器应该是用的GCMBR和GCMDR(单次缓存)
要修改CHB占 ...

#技术资源# 好的,回答的非常仔细,感谢!
 楼主| SingleYork2021 发表于 2021-11-23 14:01 | 显示全部楼层
HC11425 发表于 2021-11-22 10:39
何不使用TIME4呢   TIMER4是使用在电机应用  我有应用代码  中心对齐或者边沿对齐
华大一级代理商  131 680 ...

第一次使用,也不是很懂,硬件已经设计成TIMER6了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

12

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部