AnsweredAssumed Answered

ADuC7126 PWM is glitchy in standard mode

Question asked by Igor_K on Jul 3, 2014
Latest reply on Aug 29, 2014 by EckartH

We have a controller based on ADuC7026, and we created a new design based on ADuC7126.

We use all ADCs and all 4 DACs, but we needed a couple more for diagnostic, so we use PWM to create 2 additional analog diagnostic signals using LPF R-C 2nd order filter. Everything works fine with ADuC7026, we use port 3.0 as PWM0H and Port 3.2 as PWM1H.

We have all code ported to ADuC7126, but have a problem, I believe with PWM hardware block inside ADuC7126 or with the way their registers are updated:

In the standard mode, sometimes PWM output fails to drop for one period (stays high). which shows after R-C as glitch "up".

Below is test signal as sine of 50 Hz, created by PWM and LPF filter: Blue trace is PWM output, yellow - after LPF.

IMG_1377.JPG

IMG_1376.JPG

In the H-Bridge mode, the is no glitches. I would use H-bridge mode, but I cannot change port lines: I can only use P3.0 and P3.2,

which become PWM0 and PWM2 (in ADuC7126 definitions, in ADuc7026 they are called PWM0H and PWM1H).

Well, in H-bridge mode only PWM0 & PWM1  OR  PWM2 & PWM3 can be active at any given moment, so I have only one or another test signal, not both.

I think the absence of glitches in H-bridge mode is due to I have to use Bit_3 LCOMP as syncro, and only then internal PWM registers are updated, according to data sheet: "Bit 3 LCOMP: Set to 1 by the user to load the internal compare registers with the values in PWMxCOMx on the next transition of the PWM timer from 0x00 to 0x01. Cleared by the user to use the values previously stored in the internal compare registers."

By the way, I cannot see this bit set - it probably cleared automatically after update, which datasheet fail to mention

PROBLEM:

In standard mode update happens immediately, and I suspect there is a collision of a sort when CPU writes to PWMxCOMx and PWM reads it simultaneously. This never happen with ADuC7026, the SAME code works fine.


QUESTION: IS HERE A BETTER WAY TO RELIABLY UPDATE PWM in STANDARD mode?

Thanks,

Igor


For reference, below is a code:

Initialization:

#define PWM_RESOLUTION_BITS  9 //bits

void initPWM(void)

{

PWM0LEN = (1<<PWM_RESOLUTION_BITS); // PWM switching frequency of 20.4 kHz, 10bit resolution, when PWM0LEN = 0x0400
PWM1LEN = (1<<PWM_RESOLUTION_BITS); // PWM switching frequency of 40.64 kHz, 9 bit resolution, when PWM0LEN = 0x0200
PWM2LEN = (1<<PWM_RESOLUTION_BITS);
PWM0COM0 = 0x00;//controls PWM start of Duty Cycle, value larger than PWMxLEN has no effect
PWM1COM0 = 0x00;
PWM2COM0 = 0x00;

// We are going to change PWMxCOM1 to control duty cicle

//PWM0COM2 = 0; //no effect on our PWM 0,2,4, only on PWM1,3,5 which we are not using

// Configure Port Pins

GP3CON = 0x00000101; // P3.0 and P3.2 - PWM outputs

#ifdef USE_H_BRIDGE_MODE_FOR_ONLY_BNC0

PWMCON0 = Bit_0|Bit_1|Bit_2|Bit_9; // PWM H-Bridge mode, UCLK/2, PWM0 & PWM1 OUTPUTS are enabled, H-Bridge work is ehabled

#else  //use both BNCs but with spikes

//PWM Standard mode, UCLK/2,
PWMCON0 = Bit_0; // NOT STABLE, misses sometimes "off" state by one period which gives spike up after filtering

}

PWM update, happens on timer interrupt each 1 ms, uses DACbuf[ ] where external function creates diagnostic signal:

void PWM_output(int PWMch) //PWMch must be 0,1,2

{

///******* !!!! PWM0COM1  must be smaller than PWM0LEN if PWM0COM0 =0 *******!!

// duty cycle = PWM0COM1 / PWM0LEN

  register unsigned int PWM_out;

  PWM_out = DACbuff[PWMch]; //Read externally created valye, sine, for example

  PWM_out = PWM_out >>(17 - PWM_RESOLUTION_BITS); //reduce resolution from DAC (16 bits) to PWM (9 bits)

  *((unsigned long *)(PWM0COM1_ADR + (PWMch<<4))) = PWM_out; //addresses = 0xFFFF0F84,0xFFFF0F94,0xFFFF0FA4

#ifdef USE_H_BRIDGE_MODE_FOR_ONLY_BNC0

  PWMCON0 = Bit_0|Bit_1|Bit_2|Bit_3|Bit_9; //PWM H-Bridge mode, UCLK/2, PWM0 & PWM1 OUTPUTS are enabled, H-Bridge work is ehabled, set sync bit 3 LCOMP

#endif

}

 

Outcomes