华大HC32F460KETA TIMER6输出三路PWM配置问题
本帖最后由 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
有没有大佬能帮忙看下,谢谢! 1、Timer6_SetPeriod(M4_TMR61, Timer6PeriodA, u16Period_1); 这里为什么要设置Timer6PeriodA,看到库配置里面还有Timer6PeriodB和Timer6PeriodC可选,这里有什么特别含义吗?手册上实在没看懂!
Timer6PeriodA,这个是直接的周期寄存器,Timer6PeriodB和Timer6PeriodC是周期的一级缓存和二级缓存寄存器,
如果使能了一级缓存,就需要设置Timer6PeriodB,这样在特定的缓存传输点,数据从Timer6PeriodB--->Timer6PeriodA;而且每次更改周期的时候,需要改写寄存器Timer6PeriodB;
如果使能的是二级缓存,就需要设置Timer6PeriodB和Timer6PeriodC,那么在特定的传输点,数据从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,就不要设置硬件死区功能。
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等是什么意思,所以感觉一头雾水,还请帮忙解答一下,谢谢!
本帖最后由 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 //
何不使用TIME4呢 TIMER4是使用在电机应用我有应用代码中心对齐或者边沿对齐
华大一级代理商131 6807 9092 喻生 martinhu 发表于 2021-11-22 09:13
首先,如果你用的是CHB通道输出PWM,那么这里的比较寄存器应该是用的GCMBR和GCMDR(单次缓存)
要修改CHB占 ...
#技术资源# 好的,回答的非常仔细,感谢! HC11425 发表于 2021-11-22 10:39
何不使用TIME4呢 TIMER4是使用在电机应用我有应用代码中心对齐或者边沿对齐
华大一级代理商131 680 ...
第一次使用,也不是很懂,硬件已经设计成TIMER6了{:lol:}
页:
[1]