Author Topic: PWM ERROR? Can't find the error in my code?  (Read 2590 times)

0 Members and 1 Guest are viewing this topic.

Offline sgonzalezpTopic starter

  • Newbie
  • Posts: 7
PWM ERROR? Can't find the error in my code?
« on: October 08, 2012, 10:07:24 pm »
Code: [Select]

#include <p18f4550.h>
#include <delays.h>

#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB
#pragma config WDT = OFF //Disable watchdog timer

#define LEDPin LATAbits.LATA0 //Define LEDPin as PORT A Pin 1 or Pin 2 on Schem
#define LEDTris TRISAbits.TRISA0 //Define LEDTris as TRISA Pin 1
#define LEDPin1 LATAbits.LATA1
#define LEDTris1 TRISAbits.TRISA1
#define LEDPin2 LATAbits.LATA2
#define LEDTris2 TRISAbits.TRISA2

void main()
{
LEDTris = 0;//Set LED Pin data direction to OUTPUT
LEDPin = 0;//Set LED Pin
        LEDTris1 = 0;
        LEDPin1 = 0;
        LEDTris2 = 0;
        LEDPin2 = 0;
       

 

while(1)
{
            //LED 1 PWM
for(int i=0; i<200; i++)
                {
                LEDPin = ~LEDPin;//Toggle LED Pin
Delay10TCYx(i);//Delay 250K cycles (1 second at 1MHz since each instruction takes 4 cycles)
                LEDPin = ~LEDPin;
                Delay10TCYx(200-i);
                }

                for (int i=0;i<200; i++)
                {
                    Delay10TCYx(200-i);
                    LEDPin = ~LEDPin;
                    Delay10TCYx(i);
                    LEDPin = ~LEDPin;
                }

                //LED 2 PWM
                for(int i=0;i<200; i++)
                {
                LEDPin1 = ~LEDPin1;//Toggle LED Pin
Delay10TCYx(i);//Delay 250K cycles (1 second at 1MHz since each instruction takes 4 cycles)
                LEDPin1 = ~LEDPin1;
                Delay10TCYx(200-i);
                }

                for (int i=0;i<200; i++)
                {
                    Delay10TCYx(200-i);
                    LEDPin1 = ~LEDPin1;
                    Delay10TCYx(i);
                    LEDPin1 = ~LEDPin1;
                }

                //LED Pin 3
                for(int i=0;i<200; i++)
                {
                LEDPin2 = ~LEDPin2;//Toggle LED Pin
Delay10TCYx(i);//Delay 250K cycles (1 second at 1MHz since each instruction takes 4 cycles)
                LEDPin2 = ~LEDPin2;
                Delay10TCYx(200-i);
                }

                for (int i=0;i<200; i++)
                {
                    Delay10TCYx(200-i);
                    LEDPin2 = ~LEDPin2;
                    Delay10TCYx(i);
                    LEDPin2 = ~LEDPin2;
                }
         }
        }
       

I appreciate the help in advance! :)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 10180
  • Country: nz
Re: PWM ERROR? Can't find the error in my code?
« Reply #1 on: October 08, 2012, 11:15:00 pm »
The first problem i can see is that your using loop delays. (Delay10TCYx)

Delays using a loop that just wastes cycles only work for doing one thing at a time.
The usefulness of delay loops is quite limited and you should really only use them for debugging or stuff that happens in sequence.

The reason why they're bad is because the MCU can only do one thing at a time.
So if it's looping waiting for X counts before continuing all other code is waiting.
This including the code for your other LEDS and waiting for them causes major timing issue for the pwm.

So each LED PWM delay interferes with the delay for the other LEDS.

What you need to do is use an interrupt/hardware timer.
Setup one of the hardware timers to trigger an interrupt on overflow and set it's clock so the overflow happens every 100ns.
You can fine tune when it overflows by chancing the timers count register so it starts counting from a number above 0 (to make it overflow more quickly)

Around 100us is good because if you use 100 pwm steps you are left with a repeat rate of 0.01ms (100Hz) which is fine for flicker free led pwm.

Then, inside the interrupt handler, put something like this (see below)
The interrupt handler will automatically execute this code every 100ns no matter what's happening inside void main.

There are 4 variables,
-ledtick (which store the tick count)
-pwmLED1value/2/3 (which contains whatever pwm value you'd like between 0% and 100% brightness.

Code: [Select]
// Tick variable housekeeping
// 99 is used here because we want an led pwm value of 100 to keep the led on forever.
ledtick++;
if (ledtick > 99) ledtick= 0;

// PWM for LED1
if (pwmLED1value > ledtick)  LED1 = on else LED1 = off;

// PWM for LED2
if (pwmLED2value > ledtick)  LED2 = on else LED2 = off;

// PWM for LED3
if (pwmLED3value > ledtick)  LED3 = on else LED3 = off;

//Optional, (fine tune to get 100us)
HardwareTimerCountRegister = 50;

(Ideally all the code should be in void main but for now inside the interrupt handler is fine.)

You could simplify that even further if you used 0-255 for the pwm range instead of 0-100.
Then you could drop the ledtick variable and just read the hardware 8bit timer register instead.
« Last Edit: October 09, 2012, 11:11:28 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11701
  • Country: my
  • reassessing directives...
Re: PWM ERROR? Can't find the error in my code?
« Reply #2 on: October 09, 2012, 02:06:43 am »
at least you provide the verbose report of the compiler if its syntactic error. or if its a semantic, whats the symptom?
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline KedasProbe

  • Frequent Contributor
  • **
  • Posts: 655
  • Country: be
Re: PWM ERROR? Can't find the error in my code?
« Reply #3 on: October 09, 2012, 08:56:13 am »
Around 100ns is good because if you use 100 pwm steps you are left with a repeat rate of 0.01ms (100Hz) which is fine for flicker free led pwm.
s, ms, µs, ns ...
Not everything that counts can be measured. Not everything that can be measured counts.
[W. Bruce Cameron]
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 10180
  • Country: nz
Re: PWM ERROR? Can't find the error in my code?
« Reply #4 on: October 09, 2012, 11:11:03 am »
Yeah, ops.
Mistake fixed in original post.

It's because it goes m,n in the alphabet. confuses me sometimes.
« Last Edit: October 09, 2012, 11:12:56 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf