QG8:Vary PWM from ADC reads

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

QG8:Vary PWM from ADC reads

Jump to solution
2,259 Views
abicash
Contributor III

Hello

 

I am trying to vary the PWM duty-cycle based on an ADC value.PWM frequency is 16khz

What i am trying to achieve is keep an output current constant by driving MOSFETs through a QG8.An ADC channel measures this current value.

What i see is that the duty-cycle remains unchanged even when ADC values change.

 

I think i am doing a very basic mistake , someone please correct me..writing init and ISR codes here

 

#define TIMER_OVERFLOW            60 // us

 

interrupt 7 void TimerCH1 (void)

{

  // Stops Timer1

  TPMSC = TIMER_STOP;

  

   if(current_adjust>512) // 1.5v corresponds to 5A

          {

            duty_cycle_variation--;

            if(duty_cycle_variation<=1)duty_cycle_variation=1;

          }

                 

           if(current_adjust<512)

          {

            duty_cycle_variation++;

            if(duty_cycle_variation>=100)duty_cycle_variation=100;

           }

  TPMC1V = duty_cycle_variation;

 

  // Restarts Timer1

  TPMSC = TIMER_START; 

}

 

 

 

void Timer1_init(void)

{

  // Timer1 period 

      TPMMOD = TIMER_OVERFLOW; //15ms

 

//Initial duty cycle 

    TPMC1V=0;

 

  // Selects PWM Low-true pulses in the Timer1 Channel0 (PTA0/TPM1CH0)

  TPMC1SC = 0x028; //flag=0|ch_int_dis=0|MSnBA=10=edge aligned PWM|ELSBA=01=set o/p on compare|00

  // Starts Timer1                                                 ELSBA=10=clr o/p on compare

  //TPMSC = TIMER_START;  //0,TOIE=1,CPWMS=0,CLKSAB=01 PS2-0=011(div/8=1us)

     

}

 

Someone please help

 

Thanks and regards


Labels (1)
0 Kudos
1 Solution
1,598 Views
bigmac
Specialist III

Hello,

There are a few factors that you need to take into account -

  1. For the 'HCS08 device, PWM mode for the TPM module is buffered.  Changes to the TPMC1V register do not need to occur within an ISR - the duty will be automatically updated just prior to the next TPM overflow.  Certainly the TPM module should not be disabled and re-enabled, as you are doing.
  2. Since your TPMMOD value is set to 60, this means that the TPMC1V operating range will be 0 to 61.  Any value above 60 will result in 100 percent duty.
  3. If you require that the update of the PWM duty be synchronised to each new ADC reading, this means that the ADC reading will require to be competed and processed within somewhat less than the PWM period.  To achieve this you would need to reduce your PWM frequency (this will also increase the PWM resolution).  Presumably the ADC resolution would be 8-bits.

One possible approach to synchronise the ADC and PWM operation would be to utilise the TPM overflow interrupt.  Within the ISR code, the previous ADC conversion would be read, and a new ADC conversion started.  The result just obtained would then be processed to update the TPMC1V register.  Since the actual PWM duty would udate just prior to the next overflow, the control would lag by at least one PWM period.  However, you would need substantial filtering, over many PWM periods, to sense the average load current.

Assume you were using a bus frequency of 10 MHz and an ADC clock of 5 MHz.  With short sampling interval, the ADC conversion time would be equivalent 45 bus cycles.  To this you would need to add the number of cycles required to enter the ISR, plus the cycles for reading of the previous result and starting the new conversion.  The minimum PWM period should be somewhat greater than this value, provided the additional cycles to complete and exit the ISR does not exceed 45 cycles.

It is also possible that the occurrence of other interrupts may affect the stability of your control system.

Regards,

Mac

View solution in original post

0 Kudos
12 Replies
1,599 Views
bigmac
Specialist III

Hello,

There are a few factors that you need to take into account -

  1. For the 'HCS08 device, PWM mode for the TPM module is buffered.  Changes to the TPMC1V register do not need to occur within an ISR - the duty will be automatically updated just prior to the next TPM overflow.  Certainly the TPM module should not be disabled and re-enabled, as you are doing.
  2. Since your TPMMOD value is set to 60, this means that the TPMC1V operating range will be 0 to 61.  Any value above 60 will result in 100 percent duty.
  3. If you require that the update of the PWM duty be synchronised to each new ADC reading, this means that the ADC reading will require to be competed and processed within somewhat less than the PWM period.  To achieve this you would need to reduce your PWM frequency (this will also increase the PWM resolution).  Presumably the ADC resolution would be 8-bits.

One possible approach to synchronise the ADC and PWM operation would be to utilise the TPM overflow interrupt.  Within the ISR code, the previous ADC conversion would be read, and a new ADC conversion started.  The result just obtained would then be processed to update the TPMC1V register.  Since the actual PWM duty would udate just prior to the next overflow, the control would lag by at least one PWM period.  However, you would need substantial filtering, over many PWM periods, to sense the average load current.

Assume you were using a bus frequency of 10 MHz and an ADC clock of 5 MHz.  With short sampling interval, the ADC conversion time would be equivalent 45 bus cycles.  To this you would need to add the number of cycles required to enter the ISR, plus the cycles for reading of the previous result and starting the new conversion.  The minimum PWM period should be somewhat greater than this value, provided the additional cycles to complete and exit the ISR does not exceed 45 cycles.

It is also possible that the occurrence of other interrupts may affect the stability of your control system.

Regards,

Mac

0 Kudos
1,598 Views
iansmusical
Contributor V

Hello Mac,

Not meaning to hijack this thread but could I get you to explain this comment you made in your answer please?

    "To achieve this you would need to reduce your PWM frequency (this will also increase the PWM resolution)."

Is there anywhere I could refer to about this to gain a better understanding in preparation of using the TPM in PWM mode for an RGB LED project I'm about to start.

Thank you,

Ian

0 Kudos
1,597 Views
abicash
Contributor III

Hello Ian

What Mac means is

Increase TPMMOD (overflow value) so that effectively frequency is reduced

0 Kudos
1,598 Views
iansmusical
Contributor V

Hi Abhijit,

Thanks for the reply and yes I can see how increasing TPMMOD will reduce the frequency but how is the PWM resolution calculated/changed? As I understand it's a 16 bit timer but if the TPMMOD is 255 max then the PWM resolution is 8 bits... is it that simple!?

Thanks,

Ian

0 Kudos
1,598 Views
bigmac
Specialist III

Hello Ian,

The TPM module uses a 16-bit counter, with the ability to adjust the modulo value to a smaller value.  For PWM operation, the modulo value TPMMOD, in conjunction with the TPM prescale value and the bus frequency, will determine the PWM frequency.  The PWM period is given by (TPMMOD + 1) * prescale / fbus.

This means that the maximum count is TPMMOD, and the counter will again become zero on the next TPM clock.  The PWM duty is given by TPMCnV / (TPMMOD + 1).

Regards,

Mac

0 Kudos
1,598 Views
iansmusical
Contributor V

Hi Mac,

Thank you for the explanation, much appreciated. Can you clarify how I calculate the PWM resolution that you mentioned about increasing to Abhijit. My guess is that a TPMMOD value of 255 would deliver an 8 bit resolution or is it not that simple?

Thanks,

Ian

0 Kudos
1,598 Views
bigmac
Specialist III

Hello Ian,

The step increment in duty is given by 1/(TPMMOD + 1).  The OP was using a TPMMOD value of 60, with a prescale factor of 8.  My previous comment suggested that the prescale value could be set to 1, and the TPMMOD value increased to 487, so as to produce exactly the same PWM frequency.  This would result in the step increment being reduced by a factor of 8, i.e. 1/488 instead of 1/61.

Regards,

Mac

0 Kudos
1,598 Views
abicash
Contributor III

Hi Mac

Thanks for replying!

I have done some changes according to your suggestion.

I am measuring 4 ADC values (8 samples each) a 16x2 LCD and other interrupts as well.So the loop is bound to be sluggish

I do not expect instantaneous correction in PWM since i am trying to charge a battery and it isn't hazardous.

What i want to achieve is driving a source from a MOSFET to a battery and another load.The other load demands  much more current than the battery.

I want to keep the battery charging at 10A and provide the load with whatever current it demands.So i want to keep the dutycycle under check till battery demands 10A current and when load demands more current duty cycle has to be increased

I will write some snippets here...

ADC init

void Init_ADC(void)

      { 

         ADCSC1  = 0x1F;           // No ADC channel selected during config

       //  ADCCFG  = 0xF8;           // Bus clk, 10-bit, long sampling, clock/2 & low power

         ADCCFG  = 0x09;           // Bus clk, 10-bit, short sampling, clock/2 & high speed

         ADCSC2  = 0x00;           // S/w trigger, no compare

      

         APCTL1_ADPC7  = 1   ;     // Pin I/O disabled for ADP7

         APCTL1_ADPC6  = 1   ;     // Pin I/O disabled for ADP6

         APCTL1_ADPC5  = 1   ;     // Pin I/O disabled for ADP5

         APCTL1_ADPC4  = 1   ;     // Pin I/O disabled for ADP4

      }

interrupt 7 void TimerCH1 (void)
{
  // Stops Timer1
  TPMSC = TIMER_STOP;
   ADCSC1_test= ADCSC1; //to unharm other ADC reads which r out of this ISR
   ADCSC1 = 0x07 ;
   while (!ADCSC1_COCO);
  current_adjust=ADCR;

  if(current_adjust<=4) current_adjust=4; //min duty

   TPMC1V = current_adjust;
   ADCSC1= ADCSC1_test ; //to retain other ADC readings
  // Restarts Timer1
  TPMSC = TIMER_START; 
}

void Timer1_init(void)

{

  // Timer1 period 

      TPMMOD = TIMER_OVERFLOW; //200us

//Initial duty cycle 

    TPMC1V=0;

  // Selects PWM Low-true pulses in the Timer1 Channel0 (PTA0/TPM1CH0)

  TPMC1SC = 0x024; //flag=0|ch_int_dis=0|MSnBA=10=edge aligned PWM|ELSBA=01=set o/p on compare|00

  // Starts Timer1                                                 ELSBA=10=clr o/p on compare

  //TPMSC = TIMER_START;  //0,TOIE=1,CPWMS=0,CLKSAB=01 PS2-0=011(div/8=1us)

   

}

Your suggestion to keep TPM enabled does not provide time for other peripherals, so am forced to disable it in ISR.



0 Kudos
1,598 Views
bigmac
Specialist III

Hello Abhijit,

Abhijit Jagtap wrote:

Your suggestion to keep TPM enabled does not provide time for other peripherals, so am forced to disable it in ISR.

I do not understand your concern.  When the TPM module is operating in PWM mode, the output is quite independent of, and does not affect the operation of any other peripheral module.  The PWM channel interrupt would usually remain disabled.  When ready to update the duty value, simply write the new value to the TPM channel register (TPMC1V) and the change of waveform will be automatically synchronised, as previously explained.  In fact, disabling and re-enabling the TPM module may potentially disrupt the PWM waveform because the normal "coherency" mechanism. would be temporarily disabled.

Since you have no synchronisation issues between the ADC operation and the PWM waveform, the only reason you might have the TPM overflow interrupt enabled would be for general timing purposes.

You're averaging of more than one reading for each ADC channel is presumably to reduce noise fluctuations.  To reduce the effect of mains hum, you could equally space the ADC samples for each channel, so that the average value would apply over a 20ms period.

I notice that you have a prescale setting of 8.  I suggest that you use a prescale setting of 1, and multiply the TPMMOD value by 8.  This will increase the PWM resolution by the same factor.

It is unclear how many ADC channels that you actually require.  You appear to have four enabled (channels 4 to 7).  However, I would suggest that you simultaneously write to all bits of the APCTL1 register, rather than one bit at a time.  This will improve the efficiency of your code (fewer bytes and fewer cycles).

Regards,

Mac

0 Kudos
1,598 Views
abicash
Contributor III

Hello Mac

"When the TPM module is operating in PWM mode, the output is quite independent of, and does not affect the operation of any other peripheral module"


This is not happening.I have to force shut it in the ISR , change the duty and restart the timer, only then will it work.

Not working means that i get the least duty cycle and as i see in the True time simulator , no other variables are being updated.(same thing happens when i am not connecting the debugger)

I tried thus

read ADC value;

check for limits;

increase or decrease duty cycle depending on set values;

check limits for max and min duty;

write to TPMC1V in ISR;


I have selected

TPMMOD = 1024;

TPMSC= 0x48;// tried with 0x49


I repeat , the duty cycle variation works only when i stop and start timer in isr

The only issue here is than i cannot reach Duty cycle above 90%, here waveform becomes unstable.

Can you please help??

Message was edited by: Abhijit Jagtap Forgot to mention one more thing. I have changed TPMC1SC = 0x028;//from 0x24 i get waves as attached (with different time bases) you can see an unwanted SET o/p when o/p should be low... cant understand why this is happening......

0 Kudos
1,598 Views
bigmac
Specialist III

Hello,

I suggest that you attach your project to this thread so that others may test.

Using the overflow interrupt, presumably on every overflow, I would expect that there would be a minimum allowable duty dependent on the latency and execution time of the ISR.  To minimize the execution time, only the update of the TPMC1V value should be done within the ISR - the limit checks, etc. could be done within the main loop.

Regards,

Mac

0 Kudos
1,598 Views
abicash
Contributor III

Hello Mac

I figured it out.

I wasn't reading and resetting the TOF flag!!

Now it works as expected :smileyhappy:

Thanks and Regards

Abhijit

0 Kudos