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 | } |