Go Down

Topic: ShiftPWM support topic. Latest update: Schematics, high power LED's, LED strips (Read 83 times) previous topic - next topic

elcojacobs


Hey,

I think you could do it much faster with SPI.
There's a little trick when calculating the bitvalues
You can calc every bit with only 5 cycles and without branching
you can just use the carry flag result from the cp instruction and shift it to a register, like this:


ldd value
cp value, counter
rol register

(I think the carry flag is set when the counter is greater than the value, so this is exactly what you need for pwm)
So after executing this 8 times you got 8 values packed to one byte. you can now send this with the spi.

when you put your PWM Values in an array you can generate a whole byte with this code:

ldi r20, 8
label:

ld r21, X+
cp r21, counter
rol r22

dec r20
brne label

>> at this point you have a calculated a whole byte (in reg22) with 1+8*(2+2+1+1)+7*2+1 = 1+8*6+14+1 = 64 cycles

(I have not tested it so this might not be completely right but I think you get the idea)



Very nice way to do it. I don't like to use assembly directly in my code, so any idea which c statement would result in a rol instruction?

elcojacobs

There are more issues with using a 1280. Because the memory is 16 bit wide, extra instructions are added. I can only look at the assembly now, but I'll try to get my hands on a 1280.

jimclermonts

Thanks for posting this Elco, was just working on something similar  8)

whoami

Thank for share.
I currently do something like this but in avr studio. using tpic6b595 rather than 74hc595.
please check adafruit HL1606-LED stripPWM. HL1606 use SPI way like 74hc595.

MexWave

Hi Elco,

I've #defined F_CPU to 8E6, rebuilt and re-uploaded and have exactly the same result, so it appears you're right that there's something else  ;)

You asked for the output from the serial monitor:
Load of interrupt: 0.1252302646
Clock cycles per interrupt: 264.51
Interrupt frequency: 7575.00 Hz
PWM frequency: 75.00 Hz
Timer1 in use for highest precision.
Include servo.h to use timer2.
OCR1A: 2111
Prescaler: 1
The output was identical whether I #defined F_CPU or not.

I also tried including servo.h to see what difference it made (hey, I'm clutching at straws ;) ) and got the following:
Load of interrupt: 0.1250287890
Clock cycles per interrupt: 264.09
Interrupt frequency: 7575.00 Hz
PWM frequency: 75.00 Hz
Timer2 in use, because Timer1 is used by servo library.
OCR2A: 65
Presclaler: 32
Again, it was identical whether or not I #defined F_CPU.

Is there any more information I can supply that would be useful or interesting?  I also have some TLC5940s sat around if you're interested in any kind of comparison?

Thanks,

Mark

Go Up