PWM for LED dimming unusual behavior

PWM for LED dimming unusual behavior

Postby Keno » Mon Dec 07, 2020 7:57 pm

I made a function, where PWM signal is generated at the output (PORTD) without usage of PWM control registers inside PIC microcontroller. In order to slowly dim LED connected at the output, I was trying to increase the time needed for pulse to advance from 0% of one period to 100% of one period of square wave, while having square wave frequency constant. Everything should go as planned, except that value, that is being passed into "pwm" function, somehow resets, when going from 655 to 666 (that is, when duty cycle is at 65%). After this event, value being passed to "pwm" function proceeds from 0. Where as it should not reset at transition from 655 to 656 but at transition from 1000 to 1001.

main.png (150.11 KiB) Viewed 278 times

As for the program itself, it should work like so:
- second parameter passed into "pwrm" function is the duty cycle (in %) which changes from 0 to 100
- with variable "width" the time needed for duty cycle to advance from 0% to 100% is controlled (width = 100 represents fastest time and everything above that is considered gradually slower time from 0% to 100%)
- expression "((j*100)/width)" serves as step variable inside "while" loop inside "pwr" function:
- if "width = 100", step is increased every increment of "j"
- if "width = 1000", step is increased every 10 increments of "j", etc.
- PORTD is passed into function via as its address, whereas in function "pwm", this address is operated via pointer variable "lat"

As for the problem itself, I could only assume two possibilities: either data type of second parameter of function "pwm" is incorrect or there is some unknown limitation within PIC microprocessor (PIC18F452 is the one I currently use).

This is, how the program should operate:
This is, how the program currently operates:


(150 Bytes) Downloaded 16 times

(4.62 KiB) Downloaded 15 times
Posts: 9
Joined: Sat Nov 07, 2020 10:15 am
PIC experience: EE Student

Re: PWM for LED dimming unusual behavior

Postby AussieSusan » Tue Dec 08, 2020 2:28 am

Consider the case where 'j' is 655 and executes the '(j*100)/width' statement. 'j'*100 would be 65500 and then divided by 1000 becomes 65.
Now consider 'j' = 656. (j*100) is 65600 BUT all the compiler knows is that 'j' is an unsigned int which has a maximum value of 65535. Therefore the multiplication overflows and the value becomes 64. 64/1000 is 0.
Verified identity
Posts: 144
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: PWM for LED dimming unusual behavior

Postby ric » Mon Dec 21, 2020 1:34 am

As above. Change
Code: Select all
unsigned int j;

Code: Select all
unsigned long j;

and it will work as intended.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
Verified identity
Posts: 590
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Return to CCP, ECCP and PWM

Who is online

Users browsing this forum: No registered users and 1 guest