- /****************************************************************************/
- /* Program systemu prototypowego SP-AVR */
- /* Autor: */
- /****************************************************************************/
- #include <avr/io.h> // Rejestry mikrokontrolera ATmega32
- #include <avr/interrupt.h> // Przerwania mikrokontrolera
- #include <stdio.h> // Standardowe I/O
- #include "key.h" // Obsługa przycisków (SW0...SW7)
- #include "led.h" // Obsługa diod LED (LD0...LD7)
- #include "lcd.h" // Obsługa wyświetlacza LCD 2x16 znaków
- #define TCYKL 25 // Czas cyklu obliczeń (25 x 4ms = 100ms)
- volatile char cykl; // Odmierzanie czasu cyklu (pętli głównej)
- char buf[64]; // Bufor komunikatów LCD
- //---------------------- Początek deklaracji użytkownika --------------------------------
- //------------------------Deklaracje użytkownika--------------------------------------------------
- volatile char c_in; // odebrany znak (przez port szeregowy - przerwanie)
- char UART_init(long baud) // inicjowanie portu szeregowego
- {
- char speed, err=0;
- speed = baud / 4800;
- switch(speed)
- {
- case 1:
- UBRRL = 103; // 4800 (fosc=8MHz => UBRRL=103)
- UBRRH = 0;
- break;
- case 2:
- UBRRL = 51; // 9600 (fosc=8MHz => UBRRL=51)
- UBRRH = 0;
- break;
- case 4:
- UBRRL = 25; // 19200 (fosc=8MHz => UBRRL=25)
- UBRRH = 0;
- break;
- case 8:
- UBRRL = 12; // 38400 (fosc=8MHz => UBRRL=12)
- UBRRH = 0;
- break;
- default:
- UBRRL = 25; // 19200 (fosc=8MHz => UBRRL=25)
- UBRRH = 0;
- err = 1; // nietypowa predkość (ustawiona domyślnie)
- break;
- }
- UCSRB =_BV(RXCIE)|_BV(RXEN)|_BV(TXEN); // wł. przerwania od odb., wł. odbiornika i nadajnika
- UCSRC =_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0); // transmisja asynchroniczna, 8N1
- sei(); // globalne odblokowanie przerwań
- return err;
- }
- void COM_send(char c_out) // wysłanie jednego znaku do portu COM
- {
- loop_until_bit_is_set(UCSRA, UDRE); // oczekiwanie na wysłanie poprzedniego znaku
- UDR = c_out; // wyślij nowy znak
- }
- char COM_recv(void) // odbiór jednego znaku z portu COM
- {
- char c = c_in; // odczyt znaku - przerwanie ( 0 = brak znaku, NULL)
- c_in = 0; // zeruj flagę
- return c; // zwroć znak
- }
- void send_str(char * s) // wysłanie tekstu do portu COM
- {
- while (*s) COM_send(*s++); // wysyłaj kolejno znaki tekstu
- }
- ISR (SIG_USART_RECV) // przerwanie od odbiornika
- {
- c_in = UDR; // odbiór znaku do bufora
- }
- //--------------------Koniec deklaracji użytkownika-----------------------------------------------
- char T1=30,T2=20,T3=50,stank=1,a,b,c,d,znak;
- char stan=1,KL,LD,tim;
- //---------------------- Koniec deklaracji użytkownika ----------------------------------
- int main(void)
- {
- DDRA = 0xff; // Kierunek portu A (diody LED): port wyjściowy
- DDRB = 0x00; // Kierunek portu B (klawisze) : port wejściowy
- PORTA = 0xff; // Port A (diody LED): ustaw "1" (wygaszone diody)
- PORTB = 0xff; // Port B (klawisze) : aktywne rezystory podciągające
- TCCR0 = _BV(WGM01)|_BV(CS02); // Timer/Counter 0: tryb CTC, dzielnik=256
- OCR0 = 124; // Limit zliczania T0: 0.125us x 256 x (124+1) = 4ms
- TIMSK = _BV(OCIE0); // Odblokowanie przewań T0 (Output Compare Match)
- sei(); // Globalne włączenie obsługi przerwań
- LCD_init(); // Inicjowanie wyświetlacza LCD
- UART_init(9600);
- while(1)
- {
- cykl = TCYKL; // Deklarowany czas cyklu (TCYKL x 4ms)
- KEY_read(); // Odczyt stanu klawiszy aK1..aK4
- //-------------- Początek kodu użytkownika --------------------------------------
- switch (stan) {
- case 1:
- LD=0;
- if (KL) {tim = T1; stan=2;} break;
- case 2:
- LD=1;
- if (!KL) stan=1; else if (!tim) {stan =3; tim=T2;} break;
- case 3:
- LD=0;
- if (!KL) stan=1; else if (!tim) {stan =4; tim=T3;} break;
- case 4:
- LD=1;
- if (!tim && !KL) stan = 1; else if (!tim && KL) stan = 5; break;
- case 5:
- LD=0;
- if (!KL) stan = 1; break;
- }
- znak = COM_recv() & 0x7f;
- if (znak)
- switch (stank) {
- case 1: if (znak == ':') stank = 2; else stank = 1; break;
- case 2:
- if (znak >= '0' && znak <= '8') {stank = 3;a=znak-'0';}
- else stank=1;break;
- case 3:
- if (znak >= '0' && znak <='9') {stank=4;b=znak-'0';}
- else if (znak == '#' && a==0) {
- COM_send(':');
- COM_send(T1/10+'0');
- COM_send(T2/10+'0');
- COM_send(T3/100+'0');
- COM_send((T3%100)/10+'0');
- COM_send((4-(T1/10+T2/10+T3/10)%4)%4 + '0');
- COM_send('#'); stank=1;
- } else stank=1; break;
- case 4:
- if (znak >='1' && znak <= '3') {stank=5;c=znak-'0';}
- else if (znak == '#' && a < 2 && b == !a) {KL=a;stank=1;}
- else stank=1; break;
- case 5:
- if (znak == 'A') {stank=6;d=znak-'0';}
- else if (znak == '#' && a>1 && a<9 && b>1 && b<9 &&
- (a+b+c)%2==1){ T1=a*10;T2=b*10;stank=1;}
- else stank=1; break;
- case 6:
- if (znak == '#' && a>=0 && a<=2 && (a==0)?(b>4):(b>=0) && b <= 9 && (a*10+b+c)%4==0)
- { T3=a*100+b*10;stank=1;}
- else stank=1; break;
- }
- L1=LD;
- if (tim) --tim;
- //-------------- Wyświetlacz LCD --------------
- sprintf(buf,"K1=%dK2=%dK3=%dK4=%d",(int)aK1,(int)aK2,(int)aK3,(int)aK4);
- LCD_xy(0,0); // Ustawienie kursora w linii 1
- LCD_puts(buf); // Wyświetlenie zawartości bufora
- sprintf(buf,"L1=%dL2=%dL3=%dL4=%d",(int)L1,(int)L2,(int)L3,(int)L4);
- LCD_xy(0,1); // Ustawienie kursora w linii 2
- LCD_puts(buf); // Wyświetlenie zawartości bufora
- //-------------- Koniec kodu użytkownika ----------------------------------------
- LED_set(); // Ustawienie diod LED
- //KEY_mem(); // Zapamiętanie stanu klawiszy w pK1..pK4
- while(cykl); // Oczekiwanie na koniec cyklu oblicz.
- }
- return 0;
- }
- //---------------------- Funkcje obsługi przerwań ---------------------------------------
- ISR(TIMER0_COMP_vect) // Przerwanie od Timer/Counter 0 (co 4ms)
- {
- if(cykl) --cykl; // Odmierzanie czasu cyklu pętli głównej
- }