This is an old revision of the document!
Proiectul consta in implementarea unui sistem interactiv de semaforizare pentru o trecere de pietoni, controlat de un microcontroler ATmega328P.
Arhitectura sistemului se bazeaza pe o unitate centrala de procesare (microcontrolerul de pe placa Xplained Mini) care comunica cu mai multe module de Input/Output:
Functionarea de ansamblu este dirijata de un Timer Hardware pe 16 biti (ex. Timer1) configurat in modul CTC, care asigura numararea secundelor si controlul starilor fara a bloca executia programului principal, permitand actualizarea fluenta a ecranului LCD.
Lista de piese:
Mediu de dezvoltare: Microchip Studio (fostul Atmel Studio) / C pur. Librarii si surse 3rd-party:
Algoritmi si structuri:
Codul Sursa:
#define F_CPU 16000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdio.h> #define LED_AUTO_ROSU PD3 #define LED_AUTO_GALBEN PD4 #define LED_AUTO_VERDE PD5 #define LED_PIETON_ROSU PB0 #define LED_PIETON_VERDE PB1 #define BUZZER PB2 #define BUTON PD2 typedef enum { STATE_MASINI_VERDE, STATE_TRANZITIE_GALBEN, STATE_PIETONI_VERDE, STATE_COOLDOWN } StateMachine_t; volatile StateMachine_t current_state = STATE_MASINI_VERDE; volatile uint8_t state_timer = 0; volatile uint8_t cooldown_timer = 0; volatile uint8_t cerere_traversare = 0; volatile uint8_t beep_state = 0; void hardware_init() { DDRD |= (1 << LED_AUTO_ROSU) | (1 << LED_AUTO_GALBEN) | (1 << LED_AUTO_VERDE); DDRB |= (1 << LED_PIETON_ROSU) | (1 << LED_PIETON_VERDE) | (1 << BUZZER); DDRD &= ~(1 << BUTON); PORTD |= (1 << BUTON); EICRA |= (1 << ISC01); EICRA &= ~(1 << ISC00); EIMSK |= (1 << INT0); TCCR1B |= (1 << WGM12); TCCR1B |= (1 << CS12) | (1 << CS10); OCR1A = 15625; TIMSK1 |= (1 << OCIE1A); sei(); } void set_leds_masini(uint8_t rosu, uint8_t galben, uint8_t verde) { if(rosu) PORTD |= (1 << LED_AUTO_ROSU); else PORTD &= ~(1 << LED_AUTO_ROSU); if(galben) PORTD |= (1 << LED_AUTO_GALBEN); else PORTD &= ~(1 << LED_AUTO_GALBEN); if(verde) PORTD |= (1 << LED_AUTO_VERDE); else PORTD &= ~(1 << LED_AUTO_VERDE); } void set_leds_pietoni(uint8_t rosu, uint8_t verde) { if(rosu) PORTB |= (1 << LED_PIETON_ROSU); else PORTB &= ~(1 << LED_PIETON_ROSU); if(verde) PORTB |= (1 << LED_PIETON_VERDE); else PORTB &= ~(1 << LED_PIETON_VERDE); } ISR(INT0_vect) { if (current_state == STATE_MASINI_VERDE && cooldown_timer == 0) { cerere_traversare = 1; } } ISR(TIMER1_COMPA_vect) { if (state_timer > 0) { state_timer--; } if (cooldown_timer > 0) { cooldown_timer--; } if (current_state == STATE_PIETONI_VERDE) { beep_state = !beep_state; if (beep_state) { PORTB |= (1 << BUZZER); } else { PORTB &= ~(1 << BUZZER); } } else { PORTB &= ~(1 << BUZZER); } } int main(void) { hardware_init(); set_leds_masini(0, 0, 1); set_leds_pietoni(1, 0); while (1) { switch (current_state) { case STATE_MASINI_VERDE: set_leds_masini(0, 0, 1); set_leds_pietoni(1, 0); if (cerere_traversare == 1) { cerere_traversare = 0; state_timer = 3; current_state = STATE_TRANZITIE_GALBEN; } break; case STATE_TRANZITIE_GALBEN: set_leds_masini(0, 1, 0); if (state_timer == 0) { state_timer = 10; current_state = STATE_PIETONI_VERDE; } break; case STATE_PIETONI_VERDE: set_leds_masini(1, 0, 0); set_leds_pietoni(0, 1); if (state_timer == 0) { cooldown_timer = 10; current_state = STATE_COOLDOWN; } break; case STATE_COOLDOWN: set_leds_masini(0, 0, 1); set_leds_pietoni(1, 0); current_state = STATE_MASINI_VERDE; break; } } }