Page 1 of 1

PWM for LED dimming unusual behavior

PostPosted: Mon Dec 07, 2020 7:57 pm
by Keno
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
main.png (150.11 KiB) Viewed 2185 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: https://vimeo.com/488207207
This is, how the program currently operates: https://vimeo.com/488207746

Keno

main_B.c
(150 Bytes) Downloaded 210 times

header.h
(4.62 KiB) Downloaded 196 times

Re: PWM for LED dimming unusual behavior

PostPosted: Tue Dec 08, 2020 2:28 am
by AussieSusan
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.
Susan

Re: PWM for LED dimming unusual behavior

PostPosted: Mon Dec 21, 2020 1:34 am
by ric
As above. Change
Code: Select all
unsigned int j;

to
Code: Select all
unsigned long j;

and it will work as intended.