rendered paste body#include <avr/io.h>
#include <util/delay.h>
#include <avr/iomx8.h>
#define klawiatura PINC
#define FOSC 1843200 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
// definicje pinów używanych do sterowania LCD
// należy zmodyfikować w zależności od połaczeń
// rejestry linii DB4
#define DDR_DB4 DDRB
#define PORT_DB4 PORTB
#define DB4 PB4
// rejestry linii DB5
#define DDR_DB5 DDRB
#define PORT_DB5 PORTB
#define DB5 PB5
// rejestry linii DB6
#define DDR_DB6 DDRB
#define PORT_DB6 PORTB
#define DB6 PB6
// rejestry linii DB7
#define DDR_DB7 DDRB
#define PORT_DB7 PORTB
#define DB7 PB7
// rejestry linii RS
#define DDR_RS DDRB
#define PORT_RS PORTB
#define RS PB2
// rejestry linii E
#define DDR_E DDRB
#define PORT_E PORTB
#define E PB3
//
// instrukcje sterownika HD44780
//
#define CLEAR 0x01
#define HOME 0x02
#define INCREMENT 0x04
#define DECREMENT 0x06
#define SHIFTRIGHT 0x07
#define SHIFTLEFT 0x05
#define BLINK 0x09
//#define NOBLINK 0x08
#define CURON 0x0A
//#define CUROFF 0x08
#define DISPON 0x0C
//#define DISPOFF 0x08
#define SHIFT_CURSOR_LEFT 0x10
#define SHIFT_CURSOR_RIGHT 0x14
#define SHIFT_DISPLAY_LEFT 0x18
#define SHIFT_DISPLAY_RIGHT 0x1C
// definicje pomocniczych makroinstrukcji
// NIE ZMIENAĆ!
#define SET_DB4 PORT_DB4 |= (1 << DB4)
#define CLR_DB4 PORT_DB4 &= ~(1 << DB4)
#define SET_DB5 PORT_DB5 |= (1 << DB5)
#define CLR_DB5 PORT_DB5 &= ~(1 << DB5)
#define SET_DB6 PORT_DB6 |= (1 << DB6)
#define CLR_DB6 PORT_DB6 &= ~(1 << DB6)
#define SET_DB7 PORT_DB7 |= (1 << DB7)
#define CLR_DB7 PORT_DB7 &= ~(1 << DB7)
#define SET_E PORT_E |= (1 << E)
#define CLR_E PORT_E &= ~(1 << E)
#define SET_RS PORT_RS |= (1 << RS)
#define CLR_RS PORT_RS &= ~(1 << RS)
// funkcja wystawiająca na szynę danych połówkę bajtu
// pod uwagę brana jest młodsza połówka parametru
void out_nibble(char x)
{
CLR_DB4;CLR_DB5;CLR_DB6;CLR_DB7;
if(x & (1 << 0)) SET_DB4;// else CLR_DB4;
if(x & (1 << 1)) SET_DB5;// else CLR_DB5;
if(x & (1 << 2)) SET_DB6;// else CLR_DB6;
if(x & (1 << 3)) SET_DB7;// else CLR_DB7;
}
// funkcja zapisująca do LCD bajt danych
void write_to_lcd(char x)
{
SET_E;
out_nibble(x >> 4); // wystawienie na szynę danych starszej połówki bajtu
CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
SET_E;
out_nibble(x); // wystawienie na szynę danych młodszej połówki bajtu
CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
_delay_ms(1); // opóźnienie ok 1 ms
}
// funkcja zapisująca do LCD rozkaz
void write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
write_to_lcd(x); // zapis do LCD
}
// funkcja zapisujaca do LCD znak
void write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
write_to_lcd(x); // zapis do LCD
}
// funkcja zapisu tekstu do wyświetlacza LCD
void write_text(char * s)
{
while(*s) // do napotkania 0
{
write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj nastepny znak)
}
}
// funkcja czyszcząca ekran wyświetlacza
void lcd_clr(void)
{
write_command(CLEAR);
write_command(HOME);
}
// funkcja ustawiajaca adres zapisu w drugim wierszu wyświeltacza
void lowerline(void)
{
write_command(0xA8);
}
// funkcja inicjująca LCD
void lcd_init(void)
{
// ustawienie wszystkich linii sterujących LCD jako wyjścia
DDR_DB4 |= (1 << DB4);
DDR_DB5 |= (1 << DB5);
DDR_DB6 |= (1 << DB6);
DDR_DB7 |= (1 << DB7);
DDR_E |= (1 << E);
DDR_RS |= (1 << RS);
//
_delay_ms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmianna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
{
SET_E; // E = 1
out_nibble(0x03);
CLR_E; // E = 0
_delay_ms(5); // czekaj 5ms
}
SET_E; // E = 1
out_nibble(0x02);
CLR_E; // E = 0
_delay_ms(1); // czekaj 1ms
write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
write_command(0x08); // wyłącz LCD, kursor i miganie
write_command(0x01); // czyść LCD
write_command(0x06); // bez przesuwania w prawo
write_command(0x0C); // włącz LCD, bez kursora i mrugania
}
void USART_Init( unsigned int ubrr)
{
DDRD|=0x2; /* TXD as OUTPUT */
PORTD|=0x2; /* PULL-UP TXD */
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
/*Enable transmitter */
UCSR0B = (1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void wyslij( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
int main(void)
{
unsigned char Dane[3]={0,0,0};
unsigned char N=0;
unsigned char RD_klawisz;
unsigned char klawisz[3];
unsigned char suma_kontrolna;
//Zdefiniowanie portu klawiatury jako wejscie
//oraz podciagniecie wejsc do zasilania
PORTC=0xff;
DDRC=0;
//Inicjacja USART
USART_Init(MYUBRR);
//Inicjacja LCD
lcd_init();
while(1){
while(klawiatura==0){}; //czekaj na nacisniecie klawisza
while(klawiatura!=0){ // czekaj ja zwolnienie klawisza
RD_klawisz=klawiatura;
_delay_ms(10);}
switch(RD_klawisz)
{
case(0x09):
sprintf(klawisz,"0");break;
case(0x06):
sprintf(klawisz,"1");break;
case(0x03):
sprintf(klawisz,"2");break;
case(0x12):
sprintf(klawisz,"3");break;
case(0x44):
sprintf(klawisz,"4");break;
case(0x41):
sprintf(klawisz,"5");break;
case(0x50):
sprintf(klawisz,"6");break;
case(0x24):
sprintf(klawisz,"7");break;
case(0x21):
sprintf(klawisz,"8");break;
case(0x30):
sprintf(klawisz,"9");break;
case(0x0C):
sprintf(klawisz,"10"); break;//10 = KASUJ
case(0x18):
sprintf(klawisz,"11"); break;//11 = ENTER
}
if (N==3)
{
if (klawisz=="11") //KLAWISZ==ENTER
{
wyslij(0xEE);
wyslij(0xDD);
wyslij(Dane[0]);
wyslij(Dane[1]);
wyslij(Dane[2]);
suma_kontrolna=(Dane[0]^Dane[1]^Dane[2]);
wyslij(suma_kontrolna);
N=0;
}
if (klawisz!="11") //klawisz!=enter
N=0;
}
if (N==0)
lcd_clr();
if (N!=3)
{
if (klawisz=="10") //klawisz==kasuj
{
N=0;
lcd_clr();
}
else if (klawisz=="11") //klawisz==enter
{
N=0;
lcd_clr();
write_text("Error"); //nie wiadomo jak to wypisac
}
else
{
write_text((char*)klawisz);
Dane[N]=klawisz;
N++;
}
}
}
return(1);
}