I am working on MC56F84763 DSC with TWR56F8400 evaluation board. I am using the PWMA module to generate pulses with 100 µs low pulse and varying high pulse (max value 66 µs).
The following steps are performed to generate the pulses:
1) PWMA_Init() function: Initializes PWMA_0A, PWMA_1A, PWMA_2A and PWMA_3A submodules to generate 4 output pulses: Inverted polarity used. Independent PWM channels.
PWMA output enabled.
Debug mode enabled.
INIT value initialized to zero.
VAL0, VAL1, VAL2, VAL4 and VAL5 are initialized to zero.
VAL3 is initialized to 0x7D which corrosponds to 100 µs. (1.25MHz clock)
2) PWMA Enable: Enables the PWMA.
RUN and LDOK bits are set for the selected submodule.
Val1 interrupt is enabled.
3) PWMA ISR routine: For each of the submodules, the ISR is written which loads the new value for the high pulse.
Disable interrupts.
Verify that LDOK is cleared.
Write the new value to the VAL1 register.
Set the LDOK value.
Enable interrupts.
4) PWMA Disable: Disables the PWMA.
Clears the RUN bit.
Disables the PWMA interrupts.
While testing this PWMA module, I observed that the interrupt flags for all the VALx registers are set in the PWMA status register except the VAL3 flag during the first iteration. After the first iteration, all the flags remain set.
Also, if the interrupt is set on VAL3 value, the ISR is not generated as the counter does not start unless the VAL1 value is written. Is this correct? With the above code, the step pulses are generated correctly except for the first iteration, there is a small pulse of about 4 µs (low to high pulse) observed which increases as the value of VAL2 is increased (Currently kept as zero).
Is my understanding wrong? Please help.
Find attached the excepted PWMA output timing diagram.
Hi, Pradnya,
Regarding your question about the VAL1 register, as you know, the PWM counter counts tick from INIT value to VAL1 value, you should assign a value for the VAL1 register before you set the RUN bit in MCTRL register to run the PWM module, otherwise, the PWM counter PWMA_SMnCNT may run astray. Regarding the question that the CMPF3 bit in PWMA_SMnSTS can not be set, as you know that when the PWM counter reaches up to VALx, the corresponding CMPF bits in PWMA_SMnSTS will be set, so condition that the CMPF3 bit can be set is the VAL3 value is less than VAL1 so that the PWM counter can recahes up to VAL3 when it counts from INIT to VAL1. If you want to generate interrupt, you have to set the corresponding CMPIE bit in PWMA_SMnINTEN register.
Note that the PWM counter counts tick from INIT to VAL1, all VALx from VAL0,VAL2,VAL3,VAL4,VAL5 should be less than or equals to VAL1. When the PWM counter reach up to VAL2, the PWMA_0A pin will be high, when the PWM counter reaches up to VAL3, the PWMA_0A pin will become Low.
Hope it can help you
BR
XiangJun Rong
Thanks for your reply.
My main concern is that even if I set an interrupt on VAL3 using the interrupt enable register,I always see that interrupt flags for other VALx registers are set in the status register. Also, when I try to clear this status register by writing a one, it does not clear the flags. Please help how can this be handled.
Hi,Pradnya,
Regarding your question, I have tested on my TWR-8400 board, it seems I can not clear the CMPF bits in PWMA_SM0STS register either as you see in the screenshot, but I think it is an issue of debugger of CW tools rather than the PWM module itself. I use the following code, but I can not enter the asm(nop); although I set a break point, which means that the CMPF bit0 is cleared really.
PWMA_SM0STS|=0x3F;
if(PWMA_SM0STS&0x01)
{
asm(nop); //set a break point here
}
I attach the screenshot, hope it can helkp you.
In conclusion, the CMPF bits are cleared by writing 1 to the respective bit, but the debugger shows wrong message.
BR
XiangJun Rong
Thanks for your response.
I tried checking for CMPF bit 3 as follows, after clearing the status register:
if(PWMA_SM0STS&0x08)
{
asm(nop); //set a break point here
}
But it keeps coming to the breakpoint. Can you please explain about the PWM module initialization you did for this? Is there anything else which needs to be taken care?
Regards
Pradnya
Hi, Pradnya,
I suggest you clear the status register in the reload interrupt.
I atatch an example code, hope it can help you to fix the issue.
On my code, I can not enter the asm(nop);, it is okay.
PWMA_SM0STS|=0x3F;
if(PWMA_SM0STS&0x01)
{
asm(nop); //set a break point here
}
BR
XiangJun Rong
#pragma interrupt on
void PWM_RELOAD_ISR(void)
{
//clear the RF flag in PWM_SM0STS
PWMA_SM0STS|=0x1000; //writting 1 to clear the RF bit
#ifdef TEST
PWMA_SM0STS|=0x3F;
if(PWMA_SM0STS&0x01)
{
asm(nop); //set a break point here
}
#endif
if(changeFlag)
{
PWMA_SM0VAL2=0xFA00; //25% duty cycle
PWMA_SM0VAL3=0x400;
PWMA_SM0VAL4=0xFA00; //25% duty cycle
PWMA_SM0VAL5=0x400;
}
else
{
PWMA_SM0VAL2=0xF800; //0xF800; //50% duty cycle
PWMA_SM0VAL3=0x800; //0x800;
PWMA_SM0VAL4=0xF800; //0xF800; //50% duty cycle
PWMA_SM0VAL5=0x800; //0x800;
}
changeFlag=!changeFlag;
while(PWMA_MCTRL&0x0003) {}
// PWMA_MCTRL|=0x0030; //clear the LDOK bits
PWMA_MCTRL|=0x0001;
asm(nop);
//clear the flag
}
Thanks a lot for the code. It was of great help.
I am able to generate pulses with 100us low level and 66us high level.
I tried this using 1.25 MHz IP bus clock as the PWM clock and observed a high default state, then 10 pulses (after which I disable the PWM) and thus the PWM output goes back to high state. Note that I am using inverted polarity.
However, when I run this code with 1.25 MHz timer connected to PWM as external clock source (internally connected using crossbar), I observed that the default PWM output state is intermittent and does not always go back to high state after the PWM is disabled.
For example: During the first iteration, I get PWM high default state, which goes back to high state after 10 pulses.
Second iteration, I get PWM high default state, which goes LOW after 10 pulses.
Third iteration, PWM starts with LOW state (as per the last previous PWM state at which it was disabled) and then remains low after 10 pulses.
Thus the correct behavior is not seen consistently and changes if the PWM disable changes the default level of the PWM output.
For PWM disable, i just clear the RUN bit of the corresponding sub-module used. Are there any other dependencies which is causing this change in the PWM output polarity? I assume that the timer module used as the external clock for PWM should not create such change in polarity as its a free running timer. Please provide your suggestions.
Hi,
I read your description carefully, it seems that you want to use the PWM as a divider, is it right? I suggest you write a report and draw a diagram to describe what you want to do so that we can provide help for you.
BR
XiangJun Rong
Hello,
I am generating PWM pulses using PWMA_0A, PWMA_1A, PWMA_2A and PWMA_3A modules which are required for motor controller application.
I am using Timer_0_A module to generate 1.25 MHz clock, which is used as a PWM external clock with the divider as one. Thus PWM runs at 1.25 MHz frequency.
For the pulse generation the pulses should be of T period with 100 us low pulse and T-100us high pulse. Thus the period needs to be varied based on the value T,but the low pulse should be 100us.
Based on the number of pulses required, the corresponding PWM module is disabled after the number of pulse count reaches zero ( Just a variable is used to keep a track of this). Please find attached the expected timing diagram.
Hi, Pradnya,
If you want to have the 100us low pulse and varied high pulse, obviously, the T period must be changed. I suggest you enable reloading interrupt, in the reload interrupt routine, you can change the PWMA_SMnVAL1 register value to change the period.
If you disable the PWM by clearing the RUN bit, I suppose that the PWM pin is in high impedance state, external pull-up or pull-down resistors can determine the logic of the PWM pins.
Hope it can help you
BR
Xuangjun Rong