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