Go Down

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

retrolefty

Quote
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.


Hum, I think you have a misconception about the 1280 Vs 328 chips. Both have the same number of instructions, same memory widths. 1280 just has more memory size in length, not width for flash, sram, eeprom, more I/O pins, more timers, more serial ports, etc. But both use the same AVR 8 bit instruction set.

Lefty


ken_zein

#26
Jul 22, 2011, 01:47 am Last Edit: Jul 22, 2011, 04:05 am by ken_zein Reason: 1
First of all, AWESOME!!! You saved me tons of work, I just started working on a project like this one. I tried the example on 10 RGB LEDs with 4 registers, and I encounter some serious flickering on two of my LEDs, and two others (the ones connected to the last register) don't seem to work at all. They go on and off at random, and always all the inputs go at the same time and at full power. Has anyone encountered anything similar? Any ideas? Also, the serial monitor always says the load is 0.

UPDATE: I figured out the two that don't work, it was a faulty jumper wire. That seems to have cured the flickering as well, although maybe not completely.

Also, I can look up the assembly language by checking the datasheet, but where can I learn about using C (libraries, functions, keywords, etc.)?

Hernandi

:) You can do bit shift in C with >> and << operator!
int X;
X = 0x1; // hex
X = X << 2; // move bits 2 places left
or
X = X >> 7; // moves bits 7 bits right

But I really think you can just use XOR and AND instructions togheter to achive bit change for each one of 8 bits inside the serialized word. I use this a lot with PIC (sorry, I used to program in ASM pic and now using arduino too)

You can use A,B,C,D as variables that control each bit time (like on time).
and aa,bb,cc,dd as as timer variable for each pin
A,B,C and aa,bb,cc may be nibbles, this way you can store 2 information peer byte.

byte counter;
if(counter == 0){
   resetAllPins and send out();
   fillZeroAll aa,bb,cc,dd counters;
   send_ZERO_DataToSPI and SET START BIT at SPI
}else{
   (aa XOR counter)? out = out AND aaPinBit // if they are equal, them result is ZERO and so i change the pinBit
   (bb XOR counter)? out = out AND bbPinBit //
   sendDataToSPI and SET START BIT at SPI
}
counter ++;
if (counter >100) counter =0; // reset counter - I supose use 100 levels for each PWM out, but you can use less; that depend of
   // int frequency and what you want

Surely you have to create a for loop to change all the 8 bits
Also you have to create a simple way to generate aaPinBit, bbPinBit, ccPinBit, and so on, but
there are some elegant way to do this.
I this you can achive good results.
You maybe dont need to use BIT ROT operators (>> and <<)
Pehaps to create the __PinBin you should use (>> <<);
but i supose that will be better to use some pre-calculated data that create __PinBit and take care of witch bit you are using with reference to witch of the ~500 out that you are testing.
YOu can achive great performance with ASM. Dont get woried about it.
It is easy after you get in touch. And you will enjoy the results!
Sorry my poor english.
Good luck.
I realy delight with your work.
With is you blog or page?

whoami

try below. I use in my application

ISR(TIMER0_COMPA_vect)
{
   uint8_t i = 0, d;
   // write out data out
   i=0;
   for (i=0; i< sizeof(rgbPWM); i+= 2*3)   // device by 2 RGB of each 74HC595 and RGB 3 LED 1 free port
   {
      d = 0;
      if (rgbPWM[i+0] > pwm) d |= 0x80;
      if (rgbPWM[i+1] > pwm) d |= 0x40;
      if (rgbPWM[i+2] > pwm) d |= 0x20;
      if (rgbPWM[i+3] > pwm) d |= 0x08;
      if (rgbPWM[i+4] > pwm) d |= 0x04;
      if (rgbPWM[i+5] > pwm) d |= 0x02;

       while(!(SPSR & _BV(SPIF)));    // check that previous completed
      SPDR = d;                  // send new data
   }

   while(!(SPSR & _BV(SPIF)));         // make sure completed

   // latch
   LOAD_PORT |= (1<<LOAD_BIT);         // set 1
   LOAD_PORT &= ~(1<<LOAD_BIT);      // set 1->0

   pwm++;                        // increment pwm
   if (pwm >= MAXBRIGHTNESS)
      pwm=0;                     // reset pwm
}

Hernandi

I think you can change > by XOR and maybe save some CPU cicles
like
     if (rgbPWM[i+0] XOR pwm) d |= 0x80; // means rgbPWM[i+0] == pwm

But you need to use the start cicle to reset all pins.(count 0)
and save 'd' out between ISR_Calls

Go Up