Przykładowy program dla sterowników SU
Poniżej prezentuję kody źródłowe przykładowego programu dla sterownika SU 1.2 oraz sterownika SU 1.5. Program został napisany w języku C, w środowisku Atmel Studio 6.
Program wyświetla napis na wyświetlaczu oraz za pomocą klawiszy można zmieniać stan wyjść cyfrowych.
Cały program został podzielony na trzy pliki:
- plik „przyklad_C_SU_12.c” zawiera program główny,
- plik „lcd.c” zawiera procedury od obsługi wyświetlacza LCD.
- plik „procedury.c” zawiera pozostałe procedury.
Program główny został podzielony na trzy części:
- odpowiednia konfiguracja TIMER-a 0 i pinów procesora,
- wyświetlenie napisu na wyświetlaczu LCD,
- w pętli głównej sterownik odczytuje wciśniety klawisz i odpowiednio zmienia stan wyjść.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <avr/io.h> #include "avr/interrupt.h" #include "procedury.h" #include "global.h" #include "avr/pgmspace.h" #include "lcd.h" #define KL_UP 0x02 #define KL_LEFT 0x03 #define KL_DOWN 0x04 #define KL_RIGHT 0x05 #define KL_OK 0x06 #define KL_ESC 0x07 volatile unsigned short ms, usx10; volatile unsigned char KLAWISZ_P, KLSZ, KLAWISZ; unsigned char const napis1[] PROGMEM= { "Sterownik SU 1.2á" }; int main( void ) { unsigned char wyjscie; //poniżej konfiguracja TIMER-a 0, // TIMER 0 wykorzystany jest do obsługi klawiatury OCR0=91; TIFR=0; TCCR0=(1<<WGM01)|(0<<CS02)|(1<<CS01)|(0<<CS00); TIMSK=(1<<OCIE0); //załączenie przerwań od TIMER-a 0 sei(); //globalne załączenie przerwań DDRB=0xff; //magistrala danych jako wyjscie sbi(DDRD,4); //aktywacja pinu wyswietlacza sbi(DDRC,6); //aktywacja pinu ING1 odczytu wejsc cyfrowych sbi(DDRC,7); //aktywacja pinu do sterowania wyjsc cyfrowych sbi(DDRA,4); //aktywacja pinu /OE wyjsc cyfrowych sbi(PORTC,6); //stan wysoki na ING1 sbi(PORTC,7); //stan wysoki na OUTG1 cbi(PORTA,4); //stan niski na /OE (sterowanie wyjsc cyfrowych mozliwe) sbi(PORTD,4); //stan wysoki na DISPLAY LCD_init(); //inicjalizacja wyświetlacza LCD LCD_clear(); //wyczyszczenie wyświetlacza LCD_TXT(napis1); //wyświetlenie napisu pierwszego w wierszu pierwszym LCD_xy(1,2); LCD_TXT(napis2); //wyświetlenie napisu drugiego w wierszu drugim wyjscie=0; while (1) //pętla główna programu { switch (KLAWISZ) // w zależności od naciśniętego klawisza sterowane // jest wyjscie cyfrowe { case KL_UP: wyjscie=wyjscie^0b10000001; //wyjście przekaźnikowe nr 1 KLAWISZ=0; break ; case KL_DOWN: wyjscie=wyjscie^0b01000010; //wyjście przekaźnikowe nr 2 KLAWISZ=0; break ; case KL_LEFT: wyjscie=wyjscie^0b00000100; //wyjście przekaźnikowe nr 3 KLAWISZ=0; break ; case KL_RIGHT: wyjscie=wyjscie^0b00001000; //wyjście przekaźnikowe nr 4 KLAWISZ=0; break ; case KL_ESC: wyjscie=wyjscie^0b00010000; //wyjście tranzystorowe nr 1 KLAWISZ=0; break ; case KL_OK: wyjscie=wyjscie^0b00100000; //wyjście tranzystorowe nr 2 KLAWISZ=0; break ; } PORTB=wyjscie; //wystawienie danej na magistralę danych cbi(PORTC,7); //zatrzaśnięcie z magistrali danych na wyjścia cyfrowe sbi(PORTC,7); } } |
Plik „lcd.c” zawiera procedury do obsługi wyświetlacza:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #include "global.h" #include <avr/io.h> #include "procedury.h" #include "avr/pgmspace.h" /* ************************************************* * Procedura zapisująca dane w wyświetlaczu LCD. * ************************************************* */ void LCD_clock(u08 data, u08 rs) { MAGIST_DATA=((data&0x0f)<<4); if (rs==1) // linia RS wyświetlacza sbi(MAGIST_DATA,LCD_RS); // ustaw linię RS wyświetlacza else cbi(MAGIST_DATA,LCD_RS); cbi(PORTB,1); sbi(DDRD,4); sbi(MAGIST_DATA,LCD_EN); // ustaw linię EN wyświetlacza wait(1); cbi(PORTD,4); // i wysłanie danych na szynę sbi(PORTD,4); wait(1); cbi(MAGIST_DATA,LCD_EN); // skasuj linię EN wyświetlacza wait(1); cbi(PORTD,4); sbi(PORTD,4); wait(1); cbi(MAGIST_DATA,LCD_RS); // skasuj liniŕ RS wyświetlacza } /* ************************************************* * Wysyłanie danych lub komend do wyświetlacza. * ************************************************* */ void LCD_send(u08 data, u08 rs) { LCD_clock(data >> 4 , rs); // bardziej znacząca część LCD_clock(data & 0x0F, rs); // mniej znacząca część } /* ************************************************* * Procedura wysyłająca komendy do wyświetlacza. * ************************************************* */ void LCD_send_0(u08 ch) { LCD_send(ch, 0); } /* ************************************************* * Procedura wysyłająca dane do wyświetlacza LCD.* ************************************************* */ void LCD_send_1(u08 ch) { LCD_send(ch, 1); } /* ************************************************* * Procedura czyszcząca wyświetlacz LCD. * ************************************************* */ void LCD_clear( void ) { LCD_send_0(0x01); // wyczyść LCD wait(100); } /* ************************************************* * Procedura inicjująca wyświetlacz LCD. * ************************************************* */ void LCD_init( void ) { register unsigned char i; wait(1600); for (i=0;i<3;i++) { LCD_clock(0x03, 0); //reset LCD wait(40); } LCD_clock(0x02,0); //operacje 4-bitowe LCD_send_0(0x2C); LCD_send_0(0x08); //wylacz lcd, wylacz kursor, wlacz mruganie kursora LCD_clear(); //skasuj lcd, kursor do pozycji home LCD_send_0(0x06); //przesuwaj kursor w prawo w trakcie wyswietlania LCD_send_0(0x0C); //wlacz lcd i wyłącz kursor } /* ************************************************* * Procedura wyświetlająca znak na wyświelaczu * * LCD. * ************************************************* */ void LCD_putchar( char ch) { LCD_send_1(ch); } /* ************************************************* * Procedura wyświetlająca napis umieszczony * * w pamięci programu. * ************************************************* */ void LCD_TXT(unsigned char tablica[]) { unsigned char x; x=0; for (x=0; pgm_read_byte(&tablica[x])!= 'á' ; x++) { LCD_putchar(pgm_read_byte(&tablica[x])); } } /* ************************************************* * Procedura umieszczająca kursor wyświetlacza * * na odpowiednich współrzędnych. * ************************************************* */ void LCD_xy(u08 x, u08 y) { switch (y) { case 1: y=0x00; break ; // adres 1 znaku 1 wiersza case 2: y=0x40; break ; // adres 1 znaku 2 wiersza } LCD_send_0(0x80+y+x-1); // ustaw adres RAM } |
Plik „procedury.c” zawiera m.in. obsługę przerwania TIMER-a 0:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include "avr/interrupt.h" #include "global.h" #include "procedury.h" #include "lcd.h" #include "avr/pgmspace.h" #define KL_UP 0x02 #define KL_LEFT 0x03 #define KL_DOWN 0x04 #define KL_RIGHT 0x05 #define KL_OK 0x06 #define KL_ESC 0x07 volatile extern unsigned char KLAWISZ_P, KLSZ, KLAWISZ; volatile extern unsigned short ms, usx10; /* ***************************************************** * Obsługa przerwania TIMER-a 0, przerwanie to * * odpowiedzialne jest za obsługę klawiatury w * sterowniku. * ***************************************************** */ ISR(TIMER0_COMP_vect) { usx10++; // if (us==8) us=0; ms++; if (ms==400) { ms=0; KLAWISZ_P=0; if (bit_is_clear(PINC,PC2)) KLAWISZ_P=KL_UP; if (bit_is_clear(PINC,PC3)) KLAWISZ_P=KL_LEFT; if (bit_is_clear(PINC,PC4)) KLAWISZ_P=KL_DOWN; if (bit_is_clear(PINC,PC5)) KLAWISZ_P=KL_RIGHT; if (bit_is_clear(PINA,PA6)) KLAWISZ_P=KL_ESC; |