View difference between Paste ID: F0ipbdNN and RV0tsMFz
SHOW: | | - or go back to the newest paste.
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-
 17    1   PB5 =   LED12               *1
52+
 15    1   PB3 =   LED12
53-
 18    1   PB6 =   LED13               *1
53+
 16    1   PB4 =   LED13
54-
 19    1   PB7 =   LED14               *1
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 LED7_PD4  (4) //These 4 are new to the program
78+
79
80
#define LED7_PD4  (4)
81
#define LED8_PD5  (5)
82
#define LED9_PD6  (6)
83
#define LED10_PB1 (1)
84-
#define LED12_PB5  (5)
84+
#define LED12_PB3 (3)
85-
#define LED13_PB6  (6)
85+
#define LED13_PB4 (4)
86-
#define LED14_PB7  (7)
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-
  // the button is pressed when bit is clear
170+
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-
void program_left_turn_mode(void) {
184+
185-
   /* Opposite '~', actually turns the following LEDs OFF */
185+
186-
   PORTA &= ~(LED_ON(LED3_PA1) | LED_ON(LED4_PA0));
186+
187
188-
   PORTA &= 0xFF & (LED_OFF(LED3_PA1) | LED_OFF(LED4_PA0));
188+
189
190-
   PORTB &= ~(LED_ON(LED14_PB7) | LED_ON(LED12_PB5));
190+
191-
   PORTD &= ~(LED_ON(LED6_PD3) | LED_ON(LED5_PD2) | LED_ON(LED2_PD1) | LED_ON(LED1_PD0));
191+
192
      all_LEDs_ON();
193
      delay_us(CONST_DIM_DELAY_ON);
194-
void program_brake_mode(void) {
194+
195-
   /* Opposite '~', actually turns the following LEDs OFF */
195+
196-
   PORTA &= ~(LED_ON(LED3_PA1) | LED_ON(LED4_PA0));
196+
197
198
}
199-
void program_right_turn_mode (void) {
199+
void program_outer_leds (int circle) {
200-
   /* Opposite '~', actually turns the following LEDs OFF */
200+
201-
   PORTA &= ~(LED_ON(LED3_PA1) | LED_ON(LED4_PA0));
201+
   /* The outer circle of LEDs are made up of the following eight:
202-
   PORTB &= ~(LED_ON(LED14_PB7) | LED_ON(LED13_PB6) | LED_ON(LED12_PB5) | LED_ON(LED11_PB2));
202+
      LED9_PD6    1  00000001
203-
   PORTD &= ~(LED_ON(LED6_PD3) | LED_ON(LED2_PD1));
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-
void program_break_loop (int timer_val) {
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-
      program_brake_mode();
224+
         {
225
            case 1
226
               PORTD |= LED_ON(LED9_PD6);
227
               break;
228
            case 2
229
               PORTB |= LED_ON(LED10_PB1);
230-
void program_left_turn_loop (int timer_val) {
230+
               break;
231
            case 3
232
               PORTB |= LED_ON(LED11_PB2);
233
               break;
234
            case 4
235
               PORTB |= LED_ON(LED12_PB3);
236-
      program_left_turn_mode();
236+
               break;
237
            case 5
238
               PORTB |= LED_ON(LED13_PB4);
239
               break;
240
            case 6
241
               PORTB |= LED_ON(LED14_PB5);
242-
void program_right_turn_loop (int timer_val) {
242+
               break;
243
            case 7
244
               PORTB |= LED_ON(LED15_PB6);
245
               break;
246
            case 8
247
               PORTB |= LED_ON(LED16_PB7);
248-
      program_right_turn_mode();
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-
  /* ---------------------------------------------------------------- */
261+
      LED1_PD0   1  00000001
262-
  /*                            Initialization                        */
262+
      LED2_PD1   2  00000010
263-
  /* ---------------------------------------------------------------- */
263+
      LED3_PA1   3  00000100
264
      LED4_PA0   4  00001000
265-
  //Initialize all ports
265+
      LED5_PD2   5  00010000
266-
//  DDRA =  0b00000011; //A0, A1
266+
      LED6_PD3   6  00100000
267-
//  DDRB =  0b11111111;
267+
      LED7_PD4   7  01000000
268-
//  DDRD =  0b11111111;
268+
      LED8_PD5   8  10000000
269-
  DDRA =  (OUTPUT_LED<<LED4_PA0) | (OUTPUT_LED<<LED3_PA1);
269+
    */
270-
  DDRB =  (INPUT_SW<<INPUT_PB0) | (OUTPUT_LED<<LED10_PB1) | (OUTPUT_LED<<LED11_PB2) | (OUTPUT_LED<<LED12_PB5) | (OUTPUT_LED<<LED13_PB6) | (OUTPUT_LED<<LED14_PB7);
270+
271-
  DDRD =  (OUTPUT_LED<<LED1_PD0) | (OUTPUT_LED<<LED2_PD1) | (OUTPUT_LED<<LED5_PD2) | (OUTPUT_LED<<LED6_PD3) | (OUTPUT_LED<<LED7_PD4) | (OUTPUT_LED<<LED8_PD5) | (OUTPUT_LED<<LED9_PD6);
271+
   //start with circle off
272
   PORTD |= LED_OFF(LED1_PD0) | LED_OFF(LED2_PD1) | LED_OFF(LED5_PD2) |
273-
  all_LEDs_OFF();
273+
            LED_OFF(LED6_PD3) | LED_OFF(LED7_PD4) | LED_OFF(LED8_PD5);
274
   PORTA |= LED_OFF(LED3_PA1) | LED_OFF(LED4_PA0);
275-
/* ---------------------------------------------------------------- */
275+
276-
/*                              Main Loop                           */
276+
   //turn on the leds requested in the byte passed in
277-
/* ---------------------------------------------------------------- */
277+
   for ( int i=0; circle != 0, i < 8; i++ )
278
   {
279-
  while(1)
279+
      if ( circle && (1<<i) )
280
      {
281
         switch (i)
282-
//1)    Dim
282+
         {
283-
      //1 - All dim nothing happens (resting natural state)
283+
            case 1
284
               PORTD |= LED_ON(LED1_PD0);
285-
      program_all_dim_loop(6000);
285+
               break;
286
            case 2
287-
//2)    Left Turn
287+
               PORTD |= LED_ON(LED2_PD1);
288-
      //2 - left turn, all dim, 2 will blink at ½ sec for 10 sec.
288+
               break;
289
            case 3
290-
      while(program_ms_counter < 10000)
290+
               PORTA |= LED_ON(LED3_PA1);
291
               break;
292-
         program_left_turn_loop(program_ms_counter+500);
292+
            case 4
293-
         program_all_dim_loop  (program_ms_counter+500);
293+
               PORTA |= LED_ON(LED4_PA0);
294
               break;
295-
      //then dim for 1 sec
295+
            case 5
296-
      program_all_dim_loop(11000);
296+
               PORTD |= LED_ON(LED5_PD2);
297
               break;
298-
//3)    Dim (4 sec)
298+
            case 6
299-
      //4 - All dim nothing happens (resting natural state)
299+
               PORTD |= LED_ON(LED6_PD3);
300
               break;
301-
      program_all_dim_loop(4000);
301+
            case 7
302
               PORTD |= LED_ON(LED7_PD4);
303-
//4)    Brakes
303+
               break;
304-
      //3 – brakes get bright (8 LED’s) for 4 sec then dim for 1sec for 12 seconds
304+
            case 8
305
               PORTD |= LED_ON(LED8_PD5);
306-
      while(program_ms_counter < 12000)
306+
               break;
307
            default
308-
         program_break_loop  (program_ms_counter+4000);
308+
               //should never hit
309-
         program_all_dim_loop(program_ms_counter+1000);
309+
               circle = 0;
310
               break;
311
         } //end switch
312-
//5)    Dim (4 Sec)
312+
      } // end if
313-
      //4 - All dim nothing happens (resting natural state)
313+
   } // end loop
314
}
315-
      program_all_dim_loop(4000);
315+
316
void program_turn_on_sequence_inner(int speed) {
317-
//6)    Right Turn
317+
   int circle_placeholder=0;
318-
      //5 – right turn, all dim, 2 will blink at ½ sec for 10 sec. 
318+
319
   //turn on each led in circle, in sequence
320-
      while(program_ms_counter < 10000)
320+
   for(int i=0; i<16, circle_placeholder<=0b11111111; i++)
321
   {
322-
         program_right_turn_loop(program_ms_counter+500);
322+
      circle_placeholder |= 1<<i;
323-
         program_all_dim_loop   (program_ms_counter+500);
323+
      program_inner_leds(circle_placeholder);
324
      delay_us(speed);
325-
      //then dim for 1 sec.
325+
326-
      program_all_dim_loop(11000);
326+
327
328-
//7)    Dim (4 sec)
328+
void program_turn_on_sequence_outer(int speed) {
329-
      //4 - All dim nothing happens (resting natural state)
329+
   int circle_placeholder=0;
330
331-
      program_all_dim_loop(4000);
331+
   //turn on each led in circle, in sequence
332
   for(int i=0; i<16, circle_placeholder<=0b11111111; i++)
333-
//8)    Brakes
333+
334-
      //6 – brakes get bright (8 LED’s) for 4 sec then dim for 1sec for 12 seconds
334+
      circle_placeholder |= 1<<i;
335
      program_outer_leds(circle_placeholder);
336-
      while(program_ms_counter < 12000)
336+
      delay_us(speed);
337
   }
338-
         program_break_loop  (program_ms_counter+4000);
338+
339-
         program_all_dim_loop(program_ms_counter+1000);
339+
340
341
342-
//9)    Loop
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
}