Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Variable PWM on multiple GPIO

Status
Not open for further replies.

kanni1303

Full Member level 3
Full Member level 3
Joined
Jun 29, 2012
Messages
164
Helped
12
Reputation
24
Reaction score
11
Trophy points
1,298
Location
Chennai, Tamil Nadu, India
Activity points
2,718
Hi all,
I want to generate variable PWM (to blink LED fade in and fade out) on multiple GPIO pins. With this I could able to get, but the signal generated is sequential. Like A -> B -> C -> D. I want all these should go in parallel. I know that if I use PWM then I can get it. But my requirement is to generate on maximum pins possible :bang:(on all pins with different variable PWM not grouped as ports).

I tried with 18f4550 nad 16f877a - where I get 30 pins

Code:
           for (dutyCycle1 = 0; dutyCycle1 < period1; dutyCycle1++) {
                PORTA = 0x3E;
                for (itr = 0; itr < (period1 - dutyCycle1); itr++);
                PORTA = 0x00;
                for (itr = 0; itr < (dutyCycle1); itr++);
            }
            PORTA = 0x00;
            for (dutyCycle1 = 0; dutyCycle1 < period1; dutyCycle1++) {
                PORTB = 0x00;
                for (itr = 0; itr < (period1 - dutyCycle1); itr++);
                PORTB = 0xFF;
                for (itr = 0; itr < (dutyCycle1); itr++);
            }
            PORTB = 0xFF;
            for (dutyCycle1 = 0; dutyCycle1 < period1; dutyCycle1++) {
                PORTC = 0x00;
                for (itr = 0; itr < (period1 - dutyCycle1); itr++);
                PORTC = 0xFF;
                for (itr = 0; itr < (dutyCycle1); itr++);
            }
            PORTC = 0xFF;
            for (dutyCycle1 = 0; dutyCycle1 < period1; dutyCycle1++) {
                PORTD = 0x00;
                for (itr = 0; itr < (period1 - dutyCycle1); itr++);
                PORTD = 0xFF;
                for (itr = 0; itr < (dutyCycle1); itr++);
            }
            PORTD = 0xFF;
 
Last edited:

Hi,

Usually you do this in an USR with fixed timing.

In any case you need all PWM generating code within one single (while) loop.
****

Wait: All your PWM have identical duty cycle? --> then just one while loop and update all ports at the same time.
(But it makes no sense to me)

Klaus
 

This approach is totaly wrong. PWM consist of one single timer and multiple comparison registers. You need to increment variable in ISR and compare the value with all predefined duty cycle variable. Crossing zero should force all channel to 0.
 

If all the pins carry the same signal it does seem more appropriate to use the PWM module and distribute the single signal several times.

I did a bit-banged 10-channel PWM project to simulate a fire in a log stove a few years ago. It drives 10 LEDs, each from one random brightness to another random brightness, calculating new target values each time the target is reached. I've attached it if it is any use to you. The principle is to regularly reset the pins then after a short time flip them. The time to flip decides the PWM width. With a mixture of white, yellow and red LEDs buried under logs it actually looks quite like a real fire.

It was written for MPLAB but is plain asm so it should easily port to other assemblers or MPLABX.

Brian.
 

Attachments

  • flame_887A.asm.zip
    2.2 KB · Views: 107

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top