Advertisement
dragonflydiy

C Source code for 16 LED RGB blinkie (2014)

Oct 30th, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.47 KB | None | 0 0
  1.  
  2. // this tunes the accuracy of _delay_ms
  3. #define F_CPU 1000000
  4.  
  5. // common modules that we use in this program
  6. #include <avr/io.h>
  7. #include <avr/sleep.h>
  8. #include <avr/interrupt.h>
  9. #include <util/delay.h>
  10.  
  11. // these are the I/O lines that each LED is attached to.  Used in the interrupt driver.
  12. #define RED0IO   PA0
  13. #define GREEN0IO PA1
  14. #define BLUE0IO  PA2
  15. #define RED1IO   PA3
  16. #define GREEN1IO PA4
  17. #define BLUE1IO  PA7
  18.  
  19. #define SWITCH0  PA5
  20. #define SWITCH1  PA6
  21.  
  22.  
  23. // FULL ON = 32
  24. #define RED 0
  25. #define GREEN 1
  26. #define BLUE 2
  27. volatile char displaybuffer[16][3];
  28.  
  29.  
  30. /***********************************************************************************/
  31. // pattern subroutines here
  32. //
  33. // rules for writing pattern functions:
  34. // - call ExitCheck often, leave when it returns 1.  Putting large delays between ExitCheck()
  35. //   calls will result in bad button performance.
  36. // - you must set loops=0 at the beginning of your function so ExitCheck() knows how
  37. //   long you have been running.
  38. // - you can use loops yourself if you need to
  39. // - use _delay_ms() for timing
  40.  
  41. // this is used for timing patterns.  It gets incremented every time the display driver
  42. // completes a cycle.  Current value for 1 second defined below.
  43. // this is the number of hertz that the display is updating at also.
  44. volatile int loops = 0;
  45. #define ONESECOND 64
  46.  
  47. // button tracking - this counts up every 1/xxx of a second that the button is down.
  48. // when the count reaches defined values, things happen.
  49. // or for some functions, when the button is released, different things happen based on how long it was down
  50. int button0_down_count = 0;
  51. int button1_down_count = 0;
  52.  
  53. /***********************************************************************************/
  54. // update this to the max mode when you add more modes
  55. // should be one more than actual modes - the biggest one runs all patterns
  56. #define max_mode 20
  57. /***********************************************************************************/
  58. // These indicate which mode we should be running
  59. // the ISR changes button_mode immediately when the button is clicked
  60. // the main program notices that the two no longer match and switches modes
  61. volatile int button_mode = max_mode; // this is changed by the button within the ISR
  62. volatile int current_mode = max_mode; // this follows button_mode when the main code reacts
  63. volatile int shutdown_now = 0;
  64.  
  65.  
  66. /**********************************************************************/
  67. // use for millisecond delay. This is not terribly accurate, but probably good enough
  68. // accuracy to whatever the loop counter is
  69. // this will exit as soon as an exit condition is met.
  70. // if this returns 1, leave immediately.
  71. #define DELAY(x) if (Delay(x)) return
  72. int Delay(int ms)
  73. {
  74.     int mscount = 0;
  75.     while (mscount < ms)
  76.     {
  77.         _delay_ms(1);
  78.         if (button_mode != current_mode)
  79.             return 1;
  80.         if (shutdown_now)
  81.             return 1;
  82.         mscount++;
  83.     }
  84.     return 0;
  85. }
  86.  
  87. // set loops to 0 before beginning a function that will call this
  88. // mostly depricated, probably want to just use Delay() instead.
  89. int ExitCheck()
  90. {
  91.     if (button_mode != current_mode)
  92.         return 1;
  93.     if (loops > (ONESECOND*60))
  94.         return 1;
  95.     return 0;
  96. }
  97.  
  98.  
  99. /**********************************************************************/
  100. // utility functions
  101. int cddelay = 0; // hack because we have no default parameters in this C
  102. void ClearDisplay()
  103. {
  104.     for (int x=0; x<16; x++)
  105.     {
  106.         if (cddelay > 0)
  107.             DELAY(cddelay); // makes a clock wipe)
  108.         for (int color = 0; color < 3; color++)
  109.             displaybuffer[x][color] = 0;
  110.     }
  111. }
  112. void DimAll()
  113. {
  114.     for (int x=0; x<16; x++)
  115.         for (int color = 0; color < 3; color++)
  116.             if (displaybuffer[x][color] > 0)
  117.                 displaybuffer[x][color]--;
  118. }
  119.  
  120.  
  121. // original posted by odokemono on avrfreaks:
  122. //uint16_t rng16(uint16_t seed) {
  123. //  // Call four times with non-zero args to seed.
  124. //  // Period is greater than one quintillion.
  125. //  static uint32_t k=1148543851;
  126. //  static uint32_t i=1234567891;
  127. //  if(seed) {
  128. //    i=(i<<16)+((k<<16)>>16);
  129. //    k=(k<<16)+seed;
  130. //    return(0);
  131. //  }
  132. //  k=30903*(k&65535)+(k>>16);
  133. //  i=31083*(i&65535)+(i>>16);
  134. //  return(k+i);
  135. //}
  136.  
  137. uint16_t myrand() {
  138.   static uint32_t k=1148543851;
  139.   static uint32_t i=1234567891;
  140.  
  141.   k=30903*(k&65535)+(k>>16);
  142.   i=31083*(i&65535)+(i>>16);
  143.   return(k+i);
  144. }
  145.  
  146. /**********************************************************************/
  147. // call when mode switches, it will indicate the new mode for 1 second
  148. void ModeSwitchPattern()
  149. {
  150.     ClearDisplay();
  151.     for (int x=0; x<16; x++)
  152.     {
  153.         // max_mode is "rotate all modes" - display all the LEDs
  154.         if ((current_mode == max_mode) || (current_mode & (1<<x)) > 0)
  155.             displaybuffer[x][RED] = 15;
  156.         else
  157.             displaybuffer[x][RED] = 0;
  158.     }
  159.     loops = 0;
  160.     while (loops < ONESECOND)
  161.     {
  162.         if (ExitCheck())
  163.             return;
  164.     }
  165. }
  166.  
  167. // Input a value 0 to 255 to get a color value.
  168. // The colours are a transition r - g - b - back to r.
  169. // the /8 is because for this circuit, full on = 32
  170. void Wheel(int WheelPos, int LEDnum)
  171. {
  172.     if (WheelPos < 85)
  173.     {
  174.         displaybuffer[LEDnum][RED] = ((WheelPos * 3)/8);
  175.         displaybuffer[LEDnum][GREEN] = ((255 - WheelPos * 3)/8);
  176.         displaybuffer[LEDnum][BLUE]  = 0;
  177.     }
  178.     else if(WheelPos < 170)
  179.     {
  180.         WheelPos -= 85;
  181.         displaybuffer[LEDnum][RED] = ((255 - WheelPos * 3)/8);
  182.         displaybuffer[LEDnum][GREEN] = 0;
  183.         displaybuffer[LEDnum][BLUE] = ((WheelPos * 3)/8);
  184.     }
  185.     else
  186.     {
  187.         WheelPos -= 170;
  188.         displaybuffer[LEDnum][RED] = 0;
  189.         displaybuffer[LEDnum][GREEN] = ((WheelPos * 3)/8);
  190.         displaybuffer[LEDnum][BLUE] = ((255 - WheelPos * 3)/8);
  191.     }
  192. }
  193. void rainbow()
  194. {
  195.     int i, j;
  196.  
  197.     ClearDisplay();
  198.     loops = 0;
  199.     while (loops < 60 * ONESECOND)
  200.     {
  201.         for (j=0; j<256; j++)
  202.         {
  203.             for(i=0; i<16; i++)
  204.             {
  205.                 Wheel((i*8+j) & 255, i);
  206.             }
  207.             DELAY(10);
  208.         }
  209.     }
  210. }
  211.  
  212. void DumbCircle()
  213. {
  214.     ClearDisplay();
  215.     // add a prime number to the value every time around
  216.     int wheelpos = 0;
  217.     loops = 0;
  218.     while (loops < 60 * ONESECOND)
  219.     {
  220.         for (unsigned char x=0; x<16; x++)
  221.         {
  222.             Wheel(wheelpos, x);
  223.             DELAY(100);
  224.         }
  225.         wheelpos = (wheelpos+71)%256;
  226.     }
  227. }
  228.  
  229. void Chaser()
  230. {
  231.     ClearDisplay();
  232.     loops = 0;
  233.     int colors = 0;
  234.     while (loops < 60 * ONESECOND)
  235.     {
  236.         colors += 8;
  237.         if (colors++ > 255)
  238.             colors = 0;
  239.         for (int x=0; x<16; x++)
  240.         {
  241.             // dim each LED by 4 values for each color each round
  242.             for (int y=0; y<4; y++)
  243.             {
  244.                 DimAll();
  245.                 DELAY(20);
  246.             }
  247.            
  248.             // then set a new color
  249.             Wheel(colors, x);
  250.         }
  251.     }
  252. }
  253.  
  254.  
  255. void SlowColorChase()
  256. {
  257.     int i, j;
  258.  
  259.     ClearDisplay();
  260.     loops = 0;
  261.     int startpos = 0;
  262.     int foo = 0;
  263.     while (loops < 60 * ONESECOND)
  264.     {
  265.         for (j=0; j<256; j++)
  266.         {
  267.             Wheel((startpos*8+j) & 255, startpos);
  268.             int next = (startpos+1 % 16);
  269.             Wheel((next*8+j) & 255, next);
  270.  
  271.             DELAY(10);
  272.             if (foo++ == 100)
  273.             {
  274.                 displaybuffer[startpos][RED] = 0;
  275.                 displaybuffer[startpos][GREEN] = 0;
  276.                 displaybuffer[startpos][BLUE] = 0;
  277.                 foo = 0;
  278.                 startpos = (startpos+1)%16;
  279.             }
  280.         }
  281.     }
  282. }
  283.  
  284. void updownleftright()
  285. {
  286.     loops = 0;
  287.     int colorpos = 0;
  288.     int dir = 0;
  289.     int start = 0;
  290.     int two[2];
  291.     while (loops < 60 * ONESECOND)
  292.     {
  293.         ClearDisplay();
  294.         dir = (dir + 1) % 2;
  295.         colorpos = (colorpos + 37) % 256;
  296.         for (int x=0; x < 8; x++)
  297.         {
  298.             if (dir == 0) // up
  299.             {
  300.                 two[0] = 7 - x;
  301.                 two[1] = 8 + x;
  302.             }
  303.             if (dir == 1) // down
  304.             {
  305.                 two[0] = x;
  306.                 two[1] = 15 - x;
  307.             }
  308.             two[0] = (two[0] + start)%16;
  309.             two[1] = (two[1] + start)%16;
  310.             Wheel(colorpos, two[0]);
  311.             Wheel(colorpos, two[1]);
  312.  
  313.             DELAY(150);
  314.             ClearDisplay();
  315.         }
  316.         if (dir == 0)
  317.             start = (start+1) % 16;
  318.     }
  319. }
  320.  
  321.  
  322. void incspin()
  323. {
  324.     loops = 0;
  325.     int colorpos = 0;
  326.     int numon = 0;
  327.     int bigcount = 1;
  328.     ClearDisplay();
  329.     while (loops < 60 * ONESECOND)
  330.     {
  331.         for (int x=0; x<=numon; x++)
  332.         {
  333.             Wheel(colorpos, (bigcount+(16/(numon+1))*x)%16);
  334.         }
  335.         if (bigcount % 128 == 0)
  336.             numon = (numon + 1) % 2;
  337.         colorpos = (colorpos + 1) % 256;
  338.  
  339.         // dim each LED by 4 values for each color each round
  340.         for (int y=0; y<4+numon; y++)
  341.         {
  342.             DimAll();
  343.             DELAY(20);
  344.         }
  345. //      DELAY(750);
  346. //      ClearDisplay();
  347.         bigcount++;
  348.     }
  349. }
  350.  
  351.  
  352. void smiley()
  353. {
  354.     loops = 0;
  355.     ClearDisplay();
  356.     int leds[] = {1, 14, 4, 5,6,7,8,9,10,11, -1};
  357.     for (int x=0; leds[x] > 0; x++)
  358.     {
  359.         // yellow = ffff00
  360.         displaybuffer[leds[x]][RED] = 24;
  361.         displaybuffer[leds[x]][GREEN] = 32;
  362.     }
  363.     while (loops < 5 * ONESECOND)
  364.     {
  365.         DELAY(1000);
  366.     }
  367. }
  368.  
  369. void slowspin(int direction)
  370. {
  371.     loops = 0;
  372.     int delay=100;
  373.     int colorpos = 0;
  374.     int numon = 0;
  375.     int bigcount = 1;
  376.     ClearDisplay();
  377.     while (loops < 60 * ONESECOND)
  378.     {
  379.         for (int x=0; x<=numon; x++)
  380.         {
  381.             int lednum = (bigcount+(16/(numon+1))*x)%16;
  382.             if (direction < 0)
  383.                 lednum = 15-lednum;
  384.             Wheel(colorpos, lednum);
  385.         }
  386. //      if (bigcount % 128 == 0)
  387. //          numon = (numon + 1) % 2;
  388.         colorpos = (colorpos + 1) % 256;
  389.  
  390.         // dim each LED by 4 values for each color each round
  391.         for (int y=0; y<3; y++)
  392.         {
  393.             DimAll();
  394.             DELAY(delay);
  395.         }
  396. //      DELAY(750);
  397. //      ClearDisplay();
  398.         bigcount++;
  399.     }
  400. }
  401.  
  402. void quadwipe()
  403. {
  404.     int delay=200;
  405.     loops = 0;
  406.     int colorpos = 0;
  407.     int bigcount = 1;
  408.     ClearDisplay();
  409.     while (loops < 60 * ONESECOND)
  410.     {
  411.         for (int root = 4; root>0; root--)
  412.         {
  413.             for (int x=0; x<=4; x++)
  414.                 Wheel(colorpos, ((root-1+bigcount)+4*x)%16);
  415.             DELAY(delay);
  416.         }
  417.         for (int root = 4; root>0; root--)
  418.         {
  419.             for (int x=0; x<=4; x++)
  420.             {
  421.                 displaybuffer[((root-1+bigcount)+4*x)%16][RED] = 0;
  422.                 displaybuffer[((root-1+bigcount)+4*x)%16][GREEN] = 0;
  423.                 displaybuffer[((root-1+bigcount)+4*x)%16][BLUE] = 0;
  424.             }
  425.             if (root>1)
  426.                 DELAY(delay);
  427.         }
  428.         colorpos = (colorpos + 37) % 256;
  429.         bigcount++;
  430.     }
  431.    
  432. }
  433.  
  434. void sparkle(int fill)
  435. {
  436.     void addcolor(int lednum, int color, int value)
  437.     {
  438.         int cv = displaybuffer[lednum][color];
  439.         cv += value - 4; // slight preference for brightening
  440.         if (cv > 32)
  441.             cv = 32;
  442.         if (cv < 0)
  443.             cv = 0;
  444.         displaybuffer[lednum][color] = cv;
  445.     }
  446.     loops = 0;
  447.     int foo = 0;
  448.     while (loops < ONESECOND*60)
  449.     {
  450.         // find an led to flash on
  451.         int lednum = myrand() % 16;
  452.         addcolor(lednum, RED, myrand() % 16);
  453.         addcolor(lednum, GREEN, myrand() % 16);
  454.         addcolor(lednum, BLUE, myrand() % 16);
  455.  
  456.  
  457.         // if not filling, then dim every step, otherwise let it build up.
  458.         if (fill == 0)
  459.         {
  460.             int dimamt = myrand() % 4;
  461.             for (int x=0; x<dimamt; x++)
  462.             {
  463.                 DimAll();
  464.                 DELAY(150);
  465.             }
  466.         }
  467.         else
  468.         {
  469.             DELAY(250);
  470.             if ((foo++ % 75) == 0)
  471.             {
  472.                 cddelay = 100;
  473.                 ClearDisplay();
  474.                 cddelay = 0;
  475.             }
  476.         }
  477.     }
  478. }
  479.  
  480. void Quadrature()
  481. {
  482.     ClearDisplay();
  483.     loops = 0;
  484.     int colorpos = 0;
  485.     int state = 0;
  486.     while (loops < ONESECOND*60)
  487.     {
  488.         Wheel(colorpos, state);
  489.         Wheel(colorpos, 15-state);
  490.         Wheel(colorpos, 8+state);
  491.         Wheel(colorpos, 7-state);
  492.         state++;
  493.         if ((state == 4) || (state == 8))
  494.         {
  495.             colorpos = (colorpos+97)%256;
  496.         }
  497.         if (state == 8)
  498.             state = 0;
  499.         DimAll();
  500.         DELAY(300);
  501.     }
  502. }
  503.  
  504. void ColorPulse()
  505. {
  506.     loops = 0;
  507.     int wheelpos = myrand() % 256;
  508.     while (loops < ONESECOND*60)
  509.     {
  510.         wheelpos = (wheelpos + 157) % 256;
  511.         for (int x=0; x<16; x++)
  512.             Wheel(wheelpos, x);
  513.         for (int x=0; x<32; x++)
  514.         {
  515.             DELAY(20);
  516.             DimAll();
  517.         }
  518.         DELAY(1000);
  519.     }
  520. }
  521.  
  522.  
  523. void rndfill()
  524. {
  525.     loops = 0;
  526.     int color = 0;
  527.     while (loops < ONESECOND*60)
  528.     {
  529.         color = (color + 37) % 256;
  530.         for (int x=0; x<8; x++)
  531.         {
  532.             Wheel(color, 8+x);
  533.             Wheel(color, 7-x);
  534.             DELAY(100);
  535.         }
  536.     }
  537. }
  538.  
  539.  
  540. void rndspin()
  541. {
  542.     loops = 0;
  543.     while (loops < ONESECOND*60)
  544.     {
  545.         // pick a random spot and color and direction
  546.         int spot = myrand() % 32;
  547.         int dir = 1;
  548.         if (spot > 16)
  549.         {
  550.             spot -= 16;
  551.             dir = -1;
  552.         }
  553.         int color = myrand() % 256;
  554.  
  555.         for (int x=0; x<16; x++)
  556.         {
  557.             int pos = (x*dir) + spot;
  558.             if (pos < 0)
  559.                 pos += 16;
  560.             else if (pos > 15)
  561.                 pos -= 16;
  562.             Wheel(color, pos);
  563.             DELAY(50);
  564.         }
  565.         DELAY(100);
  566.     }
  567. }
  568.  
  569.  
  570. int countval = 0;
  571. void binarycount()
  572. {
  573.     ClearDisplay();
  574.     loops = 0;
  575.     while (loops < ONESECOND*60)
  576.     {
  577.         countval++;
  578.         if (countval > 65536)
  579.             countval = 0;
  580.         for (int x=0; x<16; x++)
  581.         {
  582.             if ((countval & (1<<x)) > 0)
  583.                 displaybuffer[x][RED] = 15;
  584.             else
  585.                 displaybuffer[x][RED] = 0;
  586.         }
  587.         DELAY(100);
  588.     }
  589. }
  590.  
  591.  
  592. void afspin()
  593. {
  594.     loops = 0;
  595.     int color = 0;
  596.     int start = 0;
  597.     int colorcount = 0;
  598.     while (loops < ONESECOND*60)
  599.     {
  600.         ClearDisplay();
  601.         for (int x=0; x<4; x++)
  602.             Wheel(color,(x*4+start)%16);
  603.         DELAY(200);
  604.         start--;
  605.         if (start < 0)
  606.             start = 3;
  607.         if (colorcount++ > 32)
  608.         {
  609.             color = (color+97)%256;
  610.             colorcount = 0;
  611.         }
  612.  
  613.     }
  614. }
  615.  
  616. int cired = 0;
  617. int cigreen = 0;
  618. int ciblue = 0;
  619. void clockish()
  620. {
  621.     loops = 0;
  622.     ClearDisplay();
  623.     while (loops < ONESECOND*60)
  624.     {
  625.         displaybuffer[cired][RED] = 0;
  626.         displaybuffer[cigreen][GREEN] = 0;
  627.         displaybuffer[ciblue][BLUE] = 0;
  628.  
  629.  
  630.         cired++;
  631.         if (cired > 15)
  632.         {
  633.             cired = 0;
  634.             cigreen++;
  635.             if (cigreen > 15)
  636.             {
  637.                 cigreen = 0;
  638.                 ciblue++;
  639.                 if (ciblue > 15)
  640.                     ciblue = 0;
  641.             }
  642.         }
  643.         displaybuffer[cired][RED] = 16;
  644.         displaybuffer[cigreen][GREEN] = 16;
  645.         displaybuffer[ciblue][BLUE] = 16;
  646.         DELAY(50);
  647.     }
  648. }
  649.  
  650.  
  651. // this is supposed to look like a Newton's cradle toy.  Not finished
  652. void Newton()
  653. {
  654.     ClearDisplay();
  655.     loops = 0;
  656.     for (int x=-5; x<5; x++)
  657.     {
  658.         for (int y=0; y<7; y++)
  659.         {
  660.             int z = x+y;
  661.             if (z>0 && y==0)
  662.                 displaybuffer[z-1][RED] = 0;
  663.             if (z>=0)
  664.                 displaybuffer[z][RED] = 32;
  665.             DELAY(150);
  666.         }
  667.     }
  668.     while (loops < ONESECOND*60)
  669.     {
  670.         DELAY(1000);
  671.         // raise right one
  672.         for (int x=5; x>2; x--)
  673.         {
  674.             displaybuffer[x][RED] = 0;
  675.             displaybuffer[x-1][RED] = 32;
  676.             DELAY(500);
  677.         }
  678.         // hold for a second
  679.         DELAY(1000);
  680.         int h=3;
  681.        
  682.     }
  683. }
  684.  
  685.  
  686.  
  687.  
  688.  
  689. void LEDTestPWM()
  690. {
  691.     for (int color=0; color<3; color++)
  692.     {
  693.         for (int LED = 0; LED < 16; LED++)
  694.         {
  695.             for (int val=0; val<32; val++)
  696.             {
  697.                 displaybuffer[LED][color] = val;
  698.                 _delay_ms(15);
  699.             }
  700.             for (int val=32; val>0; val--)
  701.             {
  702.                 displaybuffer[LED][color] = val-1;
  703.                 _delay_ms(15);
  704.             }
  705.         }
  706.     }
  707. }
  708.  
  709. /************************************************************************************
  710. ** this stuff is for writing to the serial shift register
  711. ************************************************************************************/
  712. // write a given byte out to the shift register (74HC595)
  713. #define SEROUT PB0
  714. #define SERCLK PB1
  715. void ShiftOutByte(unsigned char val)
  716. {
  717.     PORTB = 0;
  718.     DDRB = 1<<SEROUT | 1<<SERCLK;
  719.  
  720.     for (unsigned char x=0; x<8; x++)
  721.     {
  722.         // set or clear serial out bit
  723.         if (val & 0x80)
  724.             PORTB |= 1<<SEROUT;
  725.         else
  726.             PORTB &= ~(1<<SEROUT);
  727.         PORTB |= 1<<SERCLK;
  728.         PORTB &= ~(1<<SERCLK);
  729.         val <<= 1;
  730.     }
  731. }
  732.  
  733. // shift one bit in
  734. void ShiftOver(unsigned char val)
  735. {
  736.     DDRB = 1<<SEROUT | 1<<SERCLK;
  737.     if (val & 0x01)
  738.         PORTB |= 1<<SEROUT;
  739.     else
  740.         PORTB &= ~(1<<SEROUT);
  741.     PORTB |= 1<<SERCLK;
  742.     PORTB &= ~(1<<SERCLK);
  743. }
  744.  
  745.  
  746. // this is to run BEFORE the display driver is up and the interrupts are running
  747. // strictly bit bang, the CPU can be programmed during this phase because we haven't bumped
  748. // the CPU speed yet.
  749. void LEDTest()
  750. {
  751.     PORTA = 0;
  752.     DDRA = 1<<RED0IO | 1<<GREEN0IO | 1<<BLUE0IO | 1<<RED1IO | 1<<GREEN1IO | 1<<BLUE1IO;
  753.  
  754.  
  755.     unsigned char colors[] = {1<<RED0IO, 1<<RED1IO, 1<<GREEN0IO, 1<<GREEN1IO, 1<<BLUE0IO, 1<<BLUE1IO};
  756.  
  757.     for (int color = 0; color<6; color++)
  758.     {
  759.         PORTA = colors[color];
  760.         ShiftOutByte(0xfe);
  761.         for (int led=0; led < 8; led++)
  762.         {
  763.             _delay_ms(250);
  764.             ShiftOver(1);
  765.         }
  766.     }
  767. }
  768.  
  769.  
  770.  
  771.  
  772. void SetupDisplayInterrupt()
  773. {
  774. //  _delay_ms(1000); // once we change the clock speed, the device won't be programmable anymore, so give a second to do the programming
  775.  
  776.     cli(); // clear interrupt flag in SREG so we don't get interrupted here.
  777.     // Setup Timer 0
  778.    TCCR0A = 0; // normal mode
  779.    TCCR0B = (1 << CS00);  // system clock, no prescaler
  780.    TCNT0 = 0;           // Set timer count to initial value (not actually necessary)
  781.  
  782. // enable interrupts
  783.    TIMSK0 = (1<<TOIE0);     // Timer Interrupt Mask: Enable interrupt on Timer Overflow Interrupt Event 0
  784.    sei(); // set enable interrupts
  785.  
  786.    // speed up chip to 4MHz
  787.    CLKPR = 1<<CLKPCE; // Clock Prescale register - turn on bit Change Enable
  788.    CLKPR = 1<<CLKPS0; // divide (8mhz) by 4
  789. }
  790.  
  791.  
  792.  
  793.  
  794.  
  795. int main()
  796. {
  797.     // Set up basic I/O
  798.     // LEDs output, other pins input (switches)
  799.     DDRA = 1<<RED0IO | 1<<GREEN0IO | 1<<BLUE0IO | 1<<RED1IO | 1<<GREEN1IO | 1<<BLUE1IO;
  800.     PORTA = 1<<SWITCH0 | 1<<SWITCH1; // PA switch pull-ups on
  801.  
  802.     // begin state for shift register.
  803.     ShiftOutByte(0xFE);
  804.  
  805.  
  806.     // if top button is pressed on power up, go into programming mode - basically just wait forever
  807.     if ((PINA & 1<<SWITCH0) == 0) // button pressed = 0 on PB0
  808.     {
  809.         while (1)
  810.         {
  811.             PORTA = 1<<RED0IO;
  812.             _delay_ms(50);
  813.             PORTA = 0;
  814.             _delay_ms(1000);
  815.             PORTA = 1 << RED1IO;
  816.             _delay_ms(50);
  817.             PORTA = 0;
  818.             _delay_ms(1000);
  819.         }
  820.     }
  821.     // do one or the other to allow programming
  822. //  LEDTest(); // this is the raw one with no PWM - may be hard on the LEDs.
  823. //  _delay_ms(1000);
  824.  
  825.     int rotator = 0; // used for rotating all modes when in demo mode
  826.  
  827.     ClearDisplay();
  828.     SetupDisplayInterrupt();
  829.     // if bottom button is pressed on power up, do a LED test
  830.     if ((PINA & 1<<SWITCH1) == 0) // button pressed = 0 on PB0
  831.     {
  832.         while (1)
  833.         {
  834.             LEDTestPWM();
  835.         }
  836.     }
  837. //while (1)
  838. //clockish();
  839. //afspin();
  840. //binarycount();
  841.  
  842. //  LEDTEST();
  843. //  displaybuffer[0][0] = 31;
  844. //  while (1)
  845. //      LEDTestPWM();
  846. //  rainbow(10);
  847.  
  848.     // it'd be nice to figure out a way to actually make this be random
  849. //  seed = 0xfff - (TCNT0 | TCNT0<<8);
  850.     ClearDisplay();
  851.  
  852.  
  853.     while (1)
  854.     {
  855.         if (button_mode != current_mode)
  856.         {
  857.             current_mode = button_mode;
  858.             ModeSwitchPattern(); // this displays the current mode in binary for 1 second
  859.         }
  860.         else
  861.         {
  862.             int runmode;
  863.             if (current_mode == max_mode)
  864.             {
  865.                 runmode = rotator;
  866.                 rotator++;
  867.             }
  868.             else
  869.             {
  870.                 runmode = current_mode;
  871.             }
  872.             switch (runmode)
  873.             {
  874.             case 1:
  875.                 rainbow();
  876.                 break;
  877.             case 2:
  878.                 SlowColorChase();
  879.                 break;
  880.             case 3:
  881.                 Chaser();
  882.                 break;
  883.             case 4:
  884.                 DumbCircle();
  885.                 break;
  886.             case 5:
  887.                 updownleftright();
  888.                 break;
  889.             case 6:
  890.                 incspin();
  891.                 break;
  892.             case 7:
  893.                 sparkle(0);
  894.                 break;
  895.             case 8:
  896.                 slowspin(-1);
  897.                 break;
  898.             case 9:
  899.                 smiley();
  900.                 break;
  901.             case 10:
  902.                 quadwipe();
  903.                 break;
  904.             case 11:
  905.                 slowspin(1);
  906.                 break;
  907.             case 12:
  908.                 sparkle(1);
  909.                 break;
  910.             case 13:
  911.                 Quadrature();
  912.                 break;
  913.             case 14:
  914.                 ColorPulse();
  915.                 break;
  916.             case 15:
  917.                 rndspin();
  918.                 break;
  919.             case 16:
  920.                 rndfill();
  921.                 break;
  922.             case 17:
  923.                 clockish();
  924.                 break;
  925.             case 18:
  926.                 afspin();
  927.                 break;
  928.             case 19:
  929.                 binarycount();
  930.                 break;
  931.             }
  932.         }
  933.     }
  934.     return 0;
  935. }
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942. #define cyclecount 35
  943.  
  944. #define RED0   0
  945. #define GREEN0 1
  946. #define BLUE0  2
  947. #define RED1   3
  948. #define GREEN1 4
  949. #define BLUE1  5
  950.  
  951.  
  952. // Interrupt Service Routine
  953. // for Timer 0 Overflow
  954. ISR(TIM0_OVF_vect)
  955. {
  956.     static short loopcount=0;
  957.  
  958.     static unsigned char PWMCount = 0; // number of times we enter this function per PWM cycle (full brightness)
  959.     static short LEDNumberA, LEDNumberB; // points to the set of 3 in displaybuffer that we're on right now
  960.     static unsigned char compare[6];
  961.  
  962.     // these are the values we calculate each time for the next entrance
  963.     static unsigned char pinlevelA = 0;
  964.  
  965.     // this section disables specific LEDs as their PWM time expires
  966.     if (compare[RED0]   == PWMCount) { pinlevelA &= ~(1<<RED0IO);}
  967.     if (compare[GREEN0] == PWMCount) { pinlevelA &= ~(1<<GREEN0IO);}
  968.     if (compare[BLUE0]  == PWMCount) { pinlevelA &= ~(1<<BLUE0IO);}
  969.  
  970.     if (compare[RED1]   == PWMCount) { pinlevelA &= ~(1<<RED1IO);}
  971.     if (compare[GREEN1] == PWMCount) { pinlevelA &= ~(1<<GREEN1IO);}
  972.     if (compare[BLUE1]  == PWMCount) { pinlevelA &= ~(1<<BLUE1IO);}
  973.  
  974.  
  975.     PORTA = pinlevelA;
  976.  
  977.     ++PWMCount;
  978.  
  979.     TCNT0 = 128;            // Initial value = closer to 255 = we come in here more times per second
  980.  
  981.     if (PWMCount == cyclecount) // giving a little off time even at full on gives a little more dynamic range control
  982.         PWMCount = 0; // and drop down below to go to the next LED in the rotation
  983.     else
  984.         return;
  985.  
  986.  
  987.     // switch banks every full PWM cycle
  988.     // every 16, we drop down here.  PWMcount will be zero and values will get reloaded next round.
  989.     if (loopcount == 8)
  990.     {
  991.         // this is a good place to read the switch
  992.         // the switch is attached to PA5.  If it's low, the switch is pressed.
  993. //      PORTA = 1<<SWITCH0 + 1<<SWITCH1; // PA pull-ups on
  994.         if ((PINA & 1<<SWITCH0) == 0) // button pressed = 0 on PB0
  995.         {
  996.             // if button has been down for a long time, power off
  997.              button0_down_count++;
  998.              // increment once immediately, then 4 per second after one second depressed
  999.              if ((button0_down_count == 5) || (button0_down_count == ONESECOND))
  1000.              {
  1001.                  if (button_mode == max_mode)
  1002.                      button_mode = 1;
  1003.                  else
  1004.                      button_mode++;
  1005.  
  1006.                 if (button0_down_count == ONESECOND)
  1007.                     button0_down_count -= (ONESECOND/4); // repeat speed
  1008.              }
  1009.          } else {
  1010.              button0_down_count = 0;
  1011.             if ((PINA & 1<<SWITCH1) == 0) // button pressed = 0 on PB0
  1012.             {
  1013.                 // if button has been down for a long time, power off
  1014.                  button1_down_count++;
  1015.                  // increment once immediately, then 4 per second after one second depressed
  1016.                  if ((button1_down_count == 5) || (button1_down_count == ONESECOND))
  1017.                  {
  1018.                      if (button_mode == 1)
  1019.                          button_mode = max_mode;
  1020.                      else
  1021.                          button_mode--;
  1022.  
  1023.                     if (button1_down_count == ONESECOND)
  1024.                         button1_down_count -= (ONESECOND/4); // repeat speed
  1025.                 }
  1026.             }
  1027.             else
  1028.             {
  1029.                 button1_down_count = 0;
  1030.             }
  1031.          }
  1032.         loops++;    // this is used for rough timing
  1033.         loopcount = 0; // start cycle over after last LED
  1034.     }
  1035.  
  1036.     if (loopcount == 0)
  1037.     {
  1038.         ShiftOver(0);
  1039.     } else {
  1040.         ShiftOver(1);
  1041.     }
  1042.     LEDNumberA = loopcount;
  1043.     LEDNumberB = loopcount+8;
  1044.  
  1045.     pinlevelA = 1<<RED0IO | 1<<GREEN0IO | 1<<BLUE0IO | 1<<RED1IO | 1<<GREEN1IO | 1<<BLUE1IO
  1046.               | 1<<SWITCH0 | 1<<SWITCH1; // PA pull-ups on
  1047.  
  1048.     // Load the values for each LED at the beginning of the cycle for it.
  1049.     compare[RED0]   = displaybuffer[LEDNumberA][RED];
  1050.     compare[GREEN0] = displaybuffer[LEDNumberA][GREEN];
  1051.     compare[BLUE0]  = displaybuffer[LEDNumberA][BLUE];
  1052.  
  1053.     compare[RED1]   = displaybuffer[LEDNumberB][RED];
  1054.     compare[GREEN1] = displaybuffer[LEDNumberB][GREEN];
  1055.     compare[BLUE1]  = displaybuffer[LEDNumberB][BLUE];
  1056.  
  1057.     loopcount++;
  1058. }
  1059. RBG595.c
  1060. Open with
  1061. Displaying RBG595.c.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement