Hi all,
Ok, so I have been using the PWM bean in CW10.6 for a QD4 micro and SetRatio16 to create a hopefully accurate PWM signal. Recently we found the bean performs a right shift (ActualRatio.Value >> 8) internal to the generated code so the PWM resolution is only 8-bits instead. Can the QD4 be set to output at higher than 8-bit PWM duty cycle? Is this a limitation of the bean I chose or is there something else that prevents this?
Thanks,
D
Hello,
The SetRatio16 method (of PWM component) sets a new duty-cycle ratio. Ratio is expressed as a 16-bit unsigned integer number. 0 - FFFF value is proportional to ratio 0 - 100%.
If you want to use the maximal precision of the TPM device you must use maximal value of the timer counter module value (0xFFFF), i.e. when the TPM timer count from 0 to 0xFFFF the SetRatio16 method writes the 16bits value directly to the compare register of the used channel. for example, if the timer counter module register is initialized to 0xFF the maximal value of the compare register is also 0xFF. See the following example for the default QD4 project in CW MCU 10.6:
Add the PWM component in the project and open the timing dialog of the Period property, select the clock source and prescaler and select the maximal value of the Init. Value:
The PWM_Init contains following initialization value of timer counter modulo register value:
void PWM1_Init(void)
{
/* TPMSC: TOF=0,TOIE=0,CPWMS=0,CLKSB=0,CLKSA=0,PS2=0,PS1=0,PS0=0 */
setReg8(TPMSC, 0x00U); /* Disable device */
/* TPMC0SC: CH0F=0,CH0IE=0,MS0B=1,MS0A=1,ELS0B=1,ELS0A=1,??=0,??=0 */
setReg8(TPMC0SC, 0x3CU); /* Set up PWM mode with output signal level low */
ActualRatio.Value = 0x9C40U; /* Store initial value of the ratio */
/* TPMMOD: BIT15=1,BIT14=1,BIT13=1,BIT12=1,BIT11=1,BIT10=1,BIT9=1,BIT8=1,BIT7=1,BIT6=1,BIT5=1,BIT4=1,BIT3=1,BIT2=1,BIT1=1,BIT0=1 */
setReg16(TPMMOD, 0xFFFFU); /* Set modulo register */
SetRatio(); /* Calculate and set up new values of the compare according to the selected speed CPU mode */
/* TPMSC: TOF=0,TOIE=0,CPWMS=0,CLKSB=0,CLKSA=1,PS2=0,PS1=0,PS0=0 */
setReg8(TPMSC, 0x08U); /* Run the counter (set CLKSB:CLKSA) */
}
And the SetRatio16 methods contains following code:
byte PWM1_SetRatio16(word Ratio)
{
ActualRatio.Value = Ratio; /* Store new value of the ratio */
SetRatio(); /* Calculate and set up new appropriate values of the compare and modulo registers */
return ERR_OK; /* OK */
}
static void SetRatio(void)
{
if (ActualRatio.Value == 0xFFFFU) { /* Duty = 100%? */
TPMC0V = 0xFFFFU; /* Store new value to the compare reg. */
} else {
TPMC0V = (word)(ActualRatio.Value >> 0); /* Calculate new compare value according to the given ratio */
}
}
Best Regards,
Marek Neuzil
Marek,
I think I am running into a clock limit of the QD4 device. I have TPMBusClk and Prescale 1 like you have shown. I would like the PWM set with a 64us period and the ratio at 16-bit (TPMMOD 65536 or 0xFFFFU). When I try adjusting the minimal timer ticks to 65536 I get an error message that timing value cannot be set, actually with the 64us period I see the TPMMOD value is set 256 0xFFU), any minimal timer ticks above 256 displays the same error message. The only way to increase TPMMOD is to decrease the period (which I cannot do.) I found in the CPU portion the Bus Freq Divider was set to 2, changing this to 1 has doubled the TPMMOD value to 512. I am testing with this value now.
Thanks for your reply,
D