Advertisement
dlwestab

Tiny Lights 1.11

Mar 22nd, 2013
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Copyright 2012 D Westaby
  3.  
  4. ----------------------------------------------------------------------
  5.    Generic Pattern for Attiny2313
  6. ----------------------------------------------------------------------
  7. Title:      Generic_Lighting.c
  8. Author:     Dustin Westaby
  9. Date Created:   September 8, 2012
  10. Date Modified:   March 21, 2013
  11.  
  12. Compiled with AVR-GCC WinAVR
  13.  
  14. Connection reference by Alex Weber:
  15. http://tinkerlog.com/2009/06/18/microcontroller-cheat-sheet/
  16.  
  17. ----------------------------------------------------------------------
  18.     Fuses:
  19. ----------------------------------------------------------------------
  20.  BrownOut Disabled
  21.  CKDIV8
  22.  Int RC Osc 8Mhz + 64ms
  23.  
  24. ----------------------------------------------------------------------
  25.     Inputs:
  26. ----------------------------------------------------------------------
  27.  pin  i/o  port    circuit trace       notes
  28. ----------------------------------------------------------------------
  29.   1    0   PA2 =   RESET               Momentary Switch to ground
  30.  10        GND =   Ground
  31.  12    0   PB0 =   B0                  Momentary Switch to ground
  32.  20        VCC =   +V Battery
  33.  
  34. Note: Momentary switches need pullup 10k resisters
  35.  
  36. ----------------------------------------------------------------------
  37.     Ouputs:
  38. ----------------------------------------------------------------------
  39.  pin  i/o  port    circuit trace       notes
  40. ----------------------------------------------------------------------
  41.   2    1   PD0 =   LED1                *1
  42.   3    1   PD1 =   LED2                *1
  43.   4    1   PA1 =   LED3                *1
  44.   5    1   PA0 =   LED4                *1
  45.   6    1   PD2 =   LED5
  46.   7    1   PD3 =   LED6
  47.   8    1   PD4 =   LED7
  48.   9    1   PD5 =   LED8
  49.  11    1   PD6 =   LED9
  50.  13    1   PB1 =   LED10
  51.  14    1   PB2 =   LED11
  52.  15    1   PB3 =   LED12
  53.  16    1   PB4 =   LED13
  54.  17    1   PB5 =   LED14               *1
  55.  18    1   PB6 =   LED15               *1
  56.  19    1   PB7 =   LED16               *1
  57.  
  58. Note *1 - LED connected will disable pin's alternate functions
  59.           = external osc
  60.           = serial
  61.           = programming
  62.           Use a resister to isolate these.
  63.  
  64. */
  65.  
  66. //--------------------------------------
  67. //          Global Variables           |
  68. //--------------------------------------
  69. // 8 MHz Internal Oscillator DIV8 (used for delay subroutines)
  70. // One CPU Cycle = 1us
  71. #define F_CPU 8000000UL/8
  72.  
  73. #define LED1_PD0  (0)
  74. #define LED2_PD1  (1)
  75. #define LED3_PA1  (1)
  76. #define LED4_PA0  (0)
  77. #define LED5_PD2  (2)
  78. #define LED6_PD3  (3)
  79.  
  80. #define LED7_PD4  (4)
  81. #define LED8_PD5  (5)
  82. #define LED9_PD6  (6)
  83. #define LED10_PB1 (1)
  84. #define LED12_PB3 (3)
  85. #define LED13_PB4 (4)
  86.  
  87. #define LED11_PB2  (2)
  88. #define LED14_PB5  (5)
  89. #define LED15_PB6  (6)
  90. #define LED16_PB7  (7)
  91.  
  92. #define INPUT_PB0 (0)
  93.  
  94. #define CONST_DIM_DELAY_ON  (200)
  95. #define CONST_DIM_DELAY_OFF (4000)
  96.  
  97. /* This value is used to count us of delay and convert to ms
  98.    Due to other cpu processing: "1ms of delay" < "1000us of delay" */
  99. //#define TIME_CONVERSION_VAL (50) //actual number should be 150 (am running faster)
  100. #define TIME_CONVERSION_VAL (150)
  101.  
  102. #define OFF (0)
  103. #define ON  (1)
  104.  
  105. #define LED_ON(led_position)  (ON<<led_position)
  106. #define LED_OFF(led_position) (OFF<<led_position)
  107.  
  108. #define INPUT_SW   (0)
  109. #define OUTPUT_LED (1)
  110.  
  111. int program_ms_counter;
  112. int program_counter_us; //used for tracking time elapsed
  113.  
  114. //--------------------------------------
  115. //              Includes               |
  116. //--------------------------------------
  117. #include <avr/io.h>
  118. #include <util/delay.h>
  119.  
  120. //--------------------------------------
  121. //          Delay Subroutines          |
  122. //--------------------------------------
  123. //These functions are from the delay.h include, the calls to delay functions
  124. //are re-written here to allow for longer waits.
  125. void delay_ms(uint16_t ms) {
  126.         program_ms_counter+=ms;
  127.         while ( ms )
  128.         {
  129.                 _delay_ms(1);
  130.                 ms--;
  131.         }
  132. }
  133. void delay_us(uint16_t us) {
  134.   program_counter_us+=us;
  135.   while ( us )
  136.   {
  137.     _delay_us(1);
  138.     us--;
  139.   }
  140.  
  141.   while(program_counter_us>=TIME_CONVERSION_VAL)
  142.   {
  143.           program_ms_counter++;
  144.           program_counter_us-=TIME_CONVERSION_VAL;
  145.   }
  146. }
  147.  
  148. //--------------------------------------
  149. //         Common Subroutines          |
  150. //--------------------------------------
  151.  
  152. void reset_ms_us_counters(void) {
  153.    program_ms_counter=0;
  154.    program_counter_us=0;
  155. }
  156.  
  157. void all_LEDs_ON(void) {
  158.    PORTA = 0xFF;
  159.    PORTB = 0xFF;
  160.    PORTD = 0xFF;
  161. }
  162.  
  163. void all_LEDs_OFF(void) {
  164.    PORTA = ~(0x03);
  165.    PORTB = ~(0xFF);
  166.    PORTD = ~(0xFF);
  167. }
  168.  
  169. //--------------------------------------
  170. //          Switch Debounce            |
  171. //--------------------------------------
  172. int button_is_pressed()
  173. {
  174.   // the button is pressed when bit is clear (ground)
  175.   if (bit_is_clear(PINB, PB0))
  176.   {
  177.     delay_ms(25);
  178.     if (bit_is_clear(PINB, PB0)) return 1;
  179.   }
  180.  
  181.   return 0;
  182. }
  183.  
  184. //--------------------------------------
  185. //        Specific Subroutines         |
  186. //--------------------------------------
  187.  
  188. void program_all_dim_loop (int timer_val) {
  189.  
  190.    while(program_ms_counter < timer_val)
  191.    {
  192.       all_LEDs_ON();
  193.       delay_us(CONST_DIM_DELAY_ON);
  194.       all_LEDs_OFF();
  195.       delay_us(CONST_DIM_DELAY_OFF);
  196.    }
  197.  
  198. }
  199. void program_outer_leds (int circle) {
  200.  
  201.    /* The outer circle of LEDs are made up of the following eight:
  202.       LED9_PD6    1  00000001
  203.       LED10_PB1   2  00000010
  204.       LED11_PB2   3  00000100
  205.       LED12_PB3   4  00001000
  206.       LED13_PB4   5  00010000
  207.       LED14_PB5   6  00100000
  208.       LED15_PB6   7  01000000
  209.       LED16_PB7   8  10000000
  210.     */
  211.  
  212.    //start with circle off
  213.    PORTB |= LED_OFF(LED10_PB1) | LED_OFF(LED11_PB2) | LED_OFF(LED12_PB3) |
  214.             LED_OFF(LED13_PB4) | LED_OFF(LED14_PB5) | LED_OFF(LED15_PB6) |
  215.             LED_OFF(LED16_PB7);
  216.    PORTD |= LED_OFF(LED9_PD6);
  217.  
  218.    //turn on the leds requested in the byte passed in
  219.    for ( int i=0; circle != 0, i < 8; i++ )
  220.    {
  221.       if ( circle && (1<<i) )
  222.       {
  223.          switch (i)
  224.          {
  225.             case 1
  226.                PORTD |= LED_ON(LED9_PD6);
  227.                break;
  228.             case 2
  229.                PORTB |= LED_ON(LED10_PB1);
  230.                break;
  231.             case 3
  232.                PORTB |= LED_ON(LED11_PB2);
  233.                break;
  234.             case 4
  235.                PORTB |= LED_ON(LED12_PB3);
  236.                break;
  237.             case 5
  238.                PORTB |= LED_ON(LED13_PB4);
  239.                break;
  240.             case 6
  241.                PORTB |= LED_ON(LED14_PB5);
  242.                break;
  243.             case 7
  244.                PORTB |= LED_ON(LED15_PB6);
  245.                break;
  246.             case 8
  247.                PORTB |= LED_ON(LED16_PB7);
  248.                break;
  249.             default
  250.                //should never hit
  251.                circle = 0;
  252.                break;
  253.          } //end switch
  254.       } // end if
  255.    } // end loop
  256. }
  257.  
  258. void program_inner_leds (int circle) {
  259.  
  260.    /* The inner circle of LEDs are made up of the following eight:
  261.       LED1_PD0   1  00000001
  262.       LED2_PD1   2  00000010
  263.       LED3_PA1   3  00000100
  264.       LED4_PA0   4  00001000
  265.       LED5_PD2   5  00010000
  266.       LED6_PD3   6  00100000
  267.       LED7_PD4   7  01000000
  268.       LED8_PD5   8  10000000
  269.     */
  270.  
  271.    //start with circle off
  272.    PORTD |= LED_OFF(LED1_PD0) | LED_OFF(LED2_PD1) | LED_OFF(LED5_PD2) |
  273.             LED_OFF(LED6_PD3) | LED_OFF(LED7_PD4) | LED_OFF(LED8_PD5);
  274.    PORTA |= LED_OFF(LED3_PA1) | LED_OFF(LED4_PA0);
  275.  
  276.    //turn on the leds requested in the byte passed in
  277.    for ( int i=0; circle != 0, i < 8; i++ )
  278.    {
  279.       if ( circle && (1<<i) )
  280.       {
  281.          switch (i)
  282.          {
  283.             case 1
  284.                PORTD |= LED_ON(LED1_PD0);
  285.                break;
  286.             case 2
  287.                PORTD |= LED_ON(LED2_PD1);
  288.                break;
  289.             case 3
  290.                PORTA |= LED_ON(LED3_PA1);
  291.                break;
  292.             case 4
  293.                PORTA |= LED_ON(LED4_PA0);
  294.                break;
  295.             case 5
  296.                PORTD |= LED_ON(LED5_PD2);
  297.                break;
  298.             case 6
  299.                PORTD |= LED_ON(LED6_PD3);
  300.                break;
  301.             case 7
  302.                PORTD |= LED_ON(LED7_PD4);
  303.                break;
  304.             case 8
  305.                PORTD |= LED_ON(LED8_PD5);
  306.                break;
  307.             default
  308.                //should never hit
  309.                circle = 0;
  310.                break;
  311.          } //end switch
  312.       } // end if
  313.    } // end loop
  314. }
  315.  
  316. void program_turn_on_sequence_inner(int speed) {
  317.    int circle_placeholder=0;
  318.  
  319.    //turn on each led in circle, in sequence
  320.    for(int i=0; i<16, circle_placeholder<=0b11111111; i++)
  321.    {
  322.       circle_placeholder |= 1<<i;
  323.       program_inner_leds(circle_placeholder);
  324.       delay_us(speed);
  325.    }
  326. }
  327.  
  328. void program_turn_on_sequence_outer(int speed) {
  329.    int circle_placeholder=0;
  330.  
  331.    //turn on each led in circle, in sequence
  332.    for(int i=0; i<16, circle_placeholder<=0b11111111; i++)
  333.    {
  334.       circle_placeholder |= 1<<i;
  335.       program_outer_leds(circle_placeholder);
  336.       delay_us(speed);
  337.    }
  338. }
  339.  
  340.  
  341.  
  342. //--------------------------------------
  343. //               Main                  |
  344. //--------------------------------------
  345. int main (void)
  346. {
  347.  
  348.    /* ---------------------------------------------------------------- */
  349.    /*                            Initialization                        */
  350.    /* ---------------------------------------------------------------- */
  351.  
  352.    //Initialize all ports
  353.    DDRA =  (OUTPUT_LED<<LED4_PA0)  | (OUTPUT_LED<<LED3_PA1);
  354.    DDRB =  (INPUT_SW<<INPUT_PB0)   | (OUTPUT_LED<<LED10_PB1) | (OUTPUT_LED<<LED11_PB2) |
  355.           (OUTPUT_LED<<LED14_PB5) | (OUTPUT_LED<<LED15_PB6) | (OUTPUT_LED<<LED16_PB7);
  356.    DDRD =  (OUTPUT_LED<<LED1_PD0)  | (OUTPUT_LED<<LED2_PD1)  | (OUTPUT_LED<<LED5_PD2) |
  357.           (OUTPUT_LED<<LED6_PD3)  | (OUTPUT_LED<<LED7_PD4)  | (OUTPUT_LED<<LED8_PD5) |
  358.           (OUTPUT_LED<<LED9_PD6);
  359.  
  360.    //clean state
  361.    all_LEDs_OFF();
  362.    reset_ms_us_counters();
  363.  
  364.    //Turn on each led in sequence to ignite, 20ms between animations
  365.    program_turn_on_sequence_inner(20000);
  366.    program_turn_on_sequence_outer(20000);
  367.  
  368.    //dim down after powerup, 6ms
  369.    program_all_dim_loop(46000);
  370.  
  371.    /* ---------------------------------------------------------------- */
  372.    /*                              Main Loop                           */
  373.    /* ---------------------------------------------------------------- */
  374.  
  375.    while(1)
  376.    {
  377.       reset_ms_us_counters();
  378.  
  379.       // do this loop while waiting for button press
  380.       while(!button_is_pressed())
  381.       {
  382.         //minimize delays in here, delays could miss a button press
  383.  
  384.         //Dim (0.4 seconds)
  385.         program_all_dim_loop(400);
  386.  
  387.       }
  388.  
  389.      //button was pressed
  390.      //do stuff
  391.  
  392.    }
  393.  
  394.   while(1);                 // Ending infinite loop (just in case)
  395.  
  396. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement