Sunteți pe pagina 1din 15

Universitatea Tehnică a Moldovei

Facultatea Calculatoare, Informatică și Microelectronică


Departamentul Microelectronica și Inginerie Biomedicală

RAPORT
La Lucrarea de Laborator №2
La Disciplina: Sisteme electronice incorporate
Tema: Interfata cu utilizatorul.Tastatura 4x4.Afisorul alfanumeric.

A efectuat: st. gr ISBM-161 Bodiu Victoria


A verificat: lect. Univ. Verjbitchi Valerii_________

Chișinău 2019
1. Scopul lucrării
a) Realizarea interfetei de intrare prin tastatura 4x4,definirea functiei de colectare a
unui caracter de la tastatura.
b) Definirea unei functii de afisare a simbolului tastei apasate pe afisorul
alfanumeric utilizat.
c) Realizarea unui redactor pentru sistemul construit.

Problema:
Sa se dezvolte o aplicatie pe MCU care ar afisa pe un display alfanumeric LCD
16x02 simbolurile/caractere tastelor apasate pe o tastatura 4x4 atasata catre
microcontroller.Sa se creeze librarii independente pentru fiecare modul al
sistemului.
Libraria pentru display-ul atasat va include diferite functii de redactare a mesajului
pe display.

2. Notiuni teoretice:
Afisorul alfanumeric in baza controllerului LCD HD44780, devenit standard pentru afisoarele de
acest tip, este unul din cele mai utilizate dispozitive de iesire alfanumerice. Fiind limitat doar la
reprezentarea textului monocrom este pe larg intalnit la copiatoare, fax, imprimante, si alte
dispozitive de uz comun. Afisorul poate fi conectat in doua moduri, de 8 biti si de 4 biti ai sinei
de date. In bodul pe 8 bitieste mai simplu tronsferul de date, in cel de 4 biti, facem economic de
pini.

1.Structura interna a controllerului HD44780


Interior afisorul are la baza un sistem de control care opereaza cu comenzile si memoria
interna. Memoria interna este reprezentata de catre trei bancuri diferite DDRAM, CGRAM
si CGROM.

DDRAM- Memoria pentru afisare. Inregistrarile in aceasta memorie vor putea ti vizibile la
ecran. In asa mod, inregistrarea la adresa 0x00 valoarea 0x31, pe ecran va aparea un
caracter, si anume cifra "1".
De mentionat este faptul ca memoria este cu malt mai mare decat regiune vizibila a
afisorului. Ca regula memoria DDRAM tontine 80 de locatii, a cate 40 pentru fiecare linie.
cu adresele 0x00 0x27 pentru primul rand si respectiv 0x40 0x67 pentru randul doi.
Afisarea la ecran se face dupa prncipiul ferestrei mobile, si ca urmare, pentru afisorul 2x 16
regiunea vizibila va cuprinde doar cate 16 adrese, din fiecare rand, pastrand acelasi
deplasament pentru fiecare rand..
CGROM este memoria pentru generatorul de caractere. Atunci cand inscriem in DDRAM un
byte, din CGROM se preia simbolul respectiv pentru codul caracterului reprezentat prin
byteul inscris si se afiseaza pe LCD. Aceste simboluri nu pot fi modificate.
CGRAM este la fel o memorie pentru generatorul de caractere, doar ca aceasta memorie poate fi
modificata. Spatiul de adrese al acestei memorii reprezinta spatiul pentru 8 caractere de la
inceputul
memoriei CGROM. pentru fiecare simbol este rezervat a cate 8 byte, respectiv, memoria
CGRAM va cuprinde 64 byte de la inceputul spatiului de adrese CGROM. Memoria CGRAM
este utilizata pentru introducerea caracterelor utilizatorului. Un simbol va reprezenta un
tablou de 5 x 8 puncte, respectiv pentru a inregistra un caracter este nevoie de a completa un
asemenea tablou dupa cum urmeaza, priul rand al tabloului grafic,cel de sus, va corespunde cu
primul byte al caracterului. de mentionat ca bitii 7..5 al byteului inregistrat nu sunt vizualizati.

2.Tastatura 4x4

Tastatura 4x4 rcprctinta un set de butoane aranjate in rinduri si coloanc. La ticcare intersectie
vorn avea cite un Futon care scurt-circuitcaza conductoarele pentru linia cu coloana respectivA.

In starea initiala pe coloanc vor fi conectate la un set dc pini oricntati ca rc icsire iar
conductoarele liniilor vor ti conccate la un set de pini scull pentru intrarc. cu rctistenta dc pull
up activate.
Vom considera coleclia de fire a coloanclor ca intrarc a tastaturii. iar ale dc pe linii ca iesire.
Modul de detectare a tastei apasate va reprczenta aplicarca de stimuli Ia antra:v. adica la little
coloanclor, si detectarca propagarii acestor stimuli cave icsire.
Mind ca stare initiala unit.iti pc intrarc. apasarea oricarui buton %a implica transterul valorii
logics I dc pe coloana respective cave linia respective la care este conectat butonul apasat, ca
urmare insa. starea pinilor de pe linii nu va li moditicata dcoarcce tittle de icsin: la RI vor area
valoarea logica I conditiortata de rezistentele de pull up concctate la aceste lire. Ca concluzic
din sett spuse mai spus, vom spunc ca aplicand la coloana valoarca logic3 1. vont pasiva
coloana. adica nu va implica caresa schimbari pc linii.
Atoll va ti situatia atunci wind se va aplica la o coloan.10 logic. si un buton de pc coloana
respcctiva este apasat. In asst C37, valoarea logica 0 va ft propagata calm linia respective a
butonului apasat. schimband valoarca logica a pinului mcntinuta de rezistenla de pull up
concctata. Ikci, dcoarecc aplicarca valorii 0 logic pe coloana si apasarca unui buton de pe
accasta coloana implica schimbare pc linia la care c conectat butonul. yarn spun cA coloana
este 3Cli‘ata prin aplicarca valorii 0 logic.
deci.
I- coloana este pasiva
0- coloana este act iva
Utilitand ale spuse mai sus. pentru a detecta butonul apasat vom elabora o metoda de scanare a
tastaturii prin actinarca consecutive a coloanclor si verificarea propagarii valorii logics 0 pc
linii.
3. Mersul Lucrarii
Codul in limbaj C:
#ifndef LCD_H
#define LDC_H
#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <string.h>
#include <util/delay.h>

typedef unsigned char u08;


typedef signed char s08;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned long long u64;
typedef signed long long s64;
//#include "bits_macros.h"
//*******************************************************

//----------------------------------------------------------
// Definirea porturilor
//----------------------------------------------------------
//
// De comanda
//
// Registrul PORT pentru bitul E
#define LCD_E_PORT PORTB
// Registrul PORT pentru bitul RS
#define LCD_RS_PORT PORTB
// Registrul PORT pentru bitul RW
#define LCD_RW_PORT PORTB
// Registrul DDR pentru bitul RS
#define LCD_RS_DDR DDRB
// Registrul DDR pentru bitul RW
#define LCD_RW_DDR DDRB
// Registrul DDR pentru bitul E
#define LCD_E_DDR DDRB
// nr pinului pentru bitul E
#define LCD_E_PIN 3
// nr pinului pentru bitul RW
#define LCD_RW_PIN 2
// nr pinului pentru bitul RS
#define LCD_RS_PIN 1
//
// De date
//
// Portul de date
#define LCD_Data_Port PORTC
// Registrul DDR pentru date
#define LCD_Data_DDR DDRC
// Registrul PIN pentru portul de date
#define LCD_Data_PIN PINC
//
// Others
//
#define DB0 0// DB0
#define DB1 1// DB1
#define DB2 2// DB2
#define DB3 3// DB3
#define DB4 4// DB4
#define DB5 5// DB5
#define DB6 6// DB6
#define DB7 7// DB7

// Rindurile la display (2x40)


#define LINE0 0x00
#define LINE1 0x40
//----------------------------------------------------------

//----------------------------------------------------------
// Definirea Comenzilor
//----------------------------------------------------------
// Curatirea ecranului
#define LCD_Clear 0b00000001
// Resetarea pozitiei cursorului
#define LCD_Reset_Position 0b00000010
// Deplasarea adresei cursorului la stinga n-1
#define LCD_Move_Cursor_Left 0b00000100
// Deplasarea adresei cursorului la dreapta n+1
#define LCD_Move_Cursor_Right 0b00000110
// Deconectarea ecranului
#define LCD_Display_OFF 0b00001000
// Conectarea ecranului
#define LCD_Display_ON 0b00001100
// Cursorul va migai
#define LCD_Cursor_toggle 0b00001101
// Activarea cursorului
#define LCD_Cursor_ON 0b00001110
// both tipuri de cursor
#define LCD_Both_Cursor 0b00001111
// Deplasarea cursorului la dreapta cu o pozitie
#define LCD_Cursor_To_Right 0b00010000
// Deplasarea cursorului la stinga cu o pozitie
#define LCD_Cursor_To_Left 0b00010100
// Deplasarea ecranului la stinga
#define LCD_Display_To_Left 0b00011100
// Deplasarea ecranului la dreapta
#define LCD_Display_To_Right 0b00011000
// Instalarea pe 8 bit si 2 rinduri
#define LCD_Set_8bit_2rows 0b00111000
// Instalarea pe 8 bit si 1 rinduri
#define LCD_Set_8bit_1rows 0b00110000
//----------------------------------------------------------

//----------------------------------------------------------
// Macro functii pentru lucru cu display
//----------------------------------------------------------
// instalarea bitului de activare E in „0”
#define LCD_E_To_Low() LCD_E_PORT &= ~(1<<LCD_E_PIN)
// E in "1"
#define LCD_E_To_High() LCD_E_PORT |= 1<<LCD_E_PIN
// instalarea bitului RS de selectare in „0”
#define LCD_RS_To_Low() LCD_RS_PORT &= ~(1<<LCD_RS_PIN)
// RS in "1"
#define LCD_RS_To_High() LCD_RS_PORT |= 1<<LCD_RS_PIN
// instalarea bitului RW in „0” - scriere;
#define LCD_RW_To_Low() LCD_RW_PORT &= ~(1<<LCD_RW_PIN)
// RW in "1" - citire
#define LCD_RW_To_High() LCD_RW_PORT |= 1<<LCD_RW_PIN
// instalarea portului de date pe intrare;
#define LCD_DataToIn() LCD_Data_DDR = 0x00
// instalarea portului de date pe iesire
#define LCD_DataToOut() LCD_Data_DDR = 0xFF
// activarea de PullUP a portului de date
#define LCD_DataPullUp() LCD_Data_Port = 0xFF
// activarea de HiZ a portului de date
#define LCD_DataHiZ() LCD_Data_Port = 0x00
#define STROB_E() do{ LCD_E_To_High(); _delay_us(1); LCD_E_To_Low();}
while(0)
#define INIT_CMD_PINS() do{LCD_E_DDR |= (1<<LCD_E_PIN); \
LCD_RS_DDR |= (1<<LCD_RS_PIN);\
LCD_RW_DDR |= (1<<LCD_RW_PIN);\
LCD_E_To_Low();\
LCD_RS_To_Low();\
LCD_RW_To_Low();} while(0)

#define INIT_DATA_PINS() do{LCD_DataToOut(); LCD_DataHiZ();} while(0)


#define INIT_ALL_PORTS_LCD() do{ INIT_CMD_PINS(); INIT_DATA_PINS();} while(0)
//----------------------------------------------------------

//----------------------------------------------------------
// Variabile
//----------------------------------------------------------

//----------------------------------------------------------

//----------------------------------------------------------
// Functii
//----------------------------------------------------------
//==========================================================
// FUNCTII AJUTATOARE
//==========================================================
/* verificarea daca LCD este ocupat */
void __busy_flag(void);
/* transmiterea datelor la LCD */
void __Send_byte(u08 i);
//==========================================================
/* Initializarea LCD (initializarea porturilor + configurarea LCD 8 bit, 2 rinduri)*/
void __LCD_init(void);
/* Functia de inscriere a comenzii */
/* Parametrul de intrare - "cmd" - comanda spre executie */
void __LCD_write_command(u08 cmd);
/* Functia de inscriere a datelor */
/* Parametrul de intrare - "data" - datele necesare */
void __LCD_write_data(u08 data);
/* Functia de pozitionare a cursorului */
/* Parametrul de intrare - "row" - rindul, "addr" - locul */
void __LCD_GoTo_XY(u08 row, u08 addr);
/* afisarea string la display la pozitia indicata de row si addr */
/* Parametrul de intrare - "row" - rindul, "addr" - locul, "str" - stringul necesar */
void __LCD_string(char *str,u08 row, u08 addr);
void __afis_lcd_var(u08 variable, u08 row, u08 addr);

//----------------------------------------------------------
#endif

int main(void)
{
__LCD_init();
// 8 bit , 2 rinduri
__LCD_write_command(LCD_Set_8bit_2rows);
// clear ecran
__LCD_write_command(LCD_Clear);
// incrementarea cursorului
__LCD_write_command(LCD_Move_Cursor_Right);

// Aprinderea display
__LCD_write_command(LCD_Display_ON);
// clear ecran
__LCD_write_command(LCD_Clear);
// Rindul 1, adresa 0
__LCD_write_command(LCD_Reset_Position);
//============================================================
__LCD_string("PRESS A KEY",0,0);//displaying a string

DDRA=0xF0;//taking column pins as input and row pins as output

_delay_ms(1);

PORTA=0x0F;// powering the row ins

_delay_ms(1);

u08 keypressed;
u16 key = 0;

while (1)
{
if (PINA!=0b11110000)//in any of column pins goes high execute the
loop

_delay_ms(5);

keypressed = PINA;//taking the column value into integer

DDRA ^=0b11111111;//making rows as inputs and columns as ouput

_delay_ms(1);

PINA ^= 0b11111111;//powering column


_delay_ms(1);

keypressed |=PINA; //taking row value and OR ing it to column


value

if (keypressed==0b00010001)

__LCD_write_data(1);//if row1 and column1 is high show


“1”

key++;

if (keypressed==0b00010010)

{
__LCD_write_data(4);// if row1 and column2 is high show
“4”

key++;

if (keypressed==0b00010100)

__LCD_write_data(7);// if row1 and column3 is high show


“7”

key++;

if (keypressed==0b00100001)

__LCD_write_data(2);// if row2 and column1 is high show


“2”

key++;

if (keypressed==0b00100010)

__LCD_write_data(5);// if row2 and column2 is high show


“5”

key++;

if (keypressed==0b00100100)

__LCD_write_data(8);// if row2 and column3 is high show


“8”

key++;

if (keypressed==0b00101000)

__LCD_write_data(0);// if row2 and column4 is high show


“0”

key++;

if (keypressed==0b01000001)
{

__LCD_write_data(3);

key++;

if (keypressed==0b01000010)

__LCD_write_data(6);

key++;

if (keypressed==0b01000100)

__LCD_write_data(9);

key++;

keypressed=0;//after showing integer erasing the row column


memory

DDRA ^=0b11111111;//shifting input and power port

_delay_ms(1);

PORTA ^= 0b11111111;//powering row pins of keypad

_delay_ms(220);

if (key==16)//if 16 characters are shown on LCD

__LCD_write_command(LCD_Clear);//clear lcd

__LCD_string("PRESS A KEY",0,0);//display string

key=0;

}
//functii pt lcd

void __busy_flag(void)
{
LCD_DataToIn(); // DDR de la date spre intrare
LCD_DataPullUp(); // PORT de la date pe pull up

LCD_RW_To_High(); // citirea din LCD

u08 i=1;
while(i==1)
{
LCD_E_To_High(); // STROB on
asm("nop");
asm("nop");

if (!(LCD_Data_PIN&(1<<DB7))) // am citit si verificat flagul de busy


a LCD
{
i=0;
}

LCD_E_To_Low(); // STROB off


asm("nop");
asm("nop");
}

LCD_RW_To_Low(); // din nou spre scriere


}
/* transmiterea datelor la LCD */
void __Send_byte(u08 i)
{
INIT_DATA_PINS(); // portul de date spre iesire

if ((i&1)==1)
LCD_Data_Port|=(1<<DB0);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB1);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB2);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB3);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB4);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB5);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB6);
i=i>>1;

if ((i&1)==1)
LCD_Data_Port|=(1<<DB7);

STROB_E();

LCD_DataToIn();
LCD_DataHiZ(); // portul pe date pe HiZ
}
/* Initializarea LCD (initializarea porturilor + configurarea LCD 8 bit, 2
rinduri)*/
void __LCD_init(void)
{
// delay pentru stabilirea alimentatiei pentru display
_delay_ms(100);
INIT_ALL_PORTS_LCD();// initializarea pinurilor de comanda, initializarea
portului de date

u08 i = 0;
while(i!=3) // necesar pentru initializare de a trimite de 3 ori comanda
0x30
{
LCD_Data_Port |= 0x30;
STROB_E();
_delay_ms(5);
i++;
}
// CONFIGURAREA LCD
__LCD_write_command(LCD_Set_8bit_2rows); // 8 bit, 2 rinduri
__LCD_write_command(LCD_Display_ON); // conectarea display, fara
cursor
__LCD_write_command(LCD_Move_Cursor_Right); // cursorul se va misca
mereu cu o pozitie
__LCD_write_command(LCD_Reset_Position); // resetarea pozitie
cursorului
__LCD_write_command(LCD_Clear); // curatirea
ecranului
}
/* Functia de inscriere a comenzii */
/* Parametrul de intrare - "cmd" - comanda spre executie */
void __LCD_write_command(u08 cmd)
{
__busy_flag(); // verificarea daca LCD-ul ii ocupat
__Send_byte(cmd); // aplicarea comenzii pe portul de date la LCD
}
/* Functia de inscriere a datelor */
/* Parametrul de intrare - "data" - datele necesare */
void __LCD_write_data(u08 data)
{
__busy_flag(); // verificarea daca LCD-ul ii ocupat
LCD_RS_To_High(); // inscrierea datelor in LCD
__Send_byte(data); // aplicarea datelor pe portul de date la LCD
LCD_RS_To_Low(); // terminarea inscrierii datelor
}
/* Functia de pozitionare a cursorului */
/* Parametrul de intrare - "row" - rindul, "addr" - locul */
void __LCD_GoTo_XY(u08 row, u08 addr)
{
u08 address;

switch(addr)
{
case 0: address = LINE0 + row;
break;
case 1: address = LINE1 + row;
break;
default: address = LINE0 + row;
}

__LCD_write_command(1<<7|address);
}
/* afisarea string la display la pozitia indicata de row si addr */
/* Parametrul de intrare - "row" - rindul, "addr" - locul, "str" - stringul
necesar */
void __LCD_string(char *str, u08 row, u08 addr)
{
__LCD_GoTo_XY(row, addr); // se duce la pozitia data de parametrii de
intrare
while(*str) // inscriere pe rind fiecare caracter pina nu se termina
string-ul
{
__LCD_write_data(*str++);
}
}

// afisarea variabilelor la LCD

void __afis_lcd_var(u08 variable, u08 row, u08 addr)


{
u08 i;
// indicarea marimii masivului pentru pastrarea datelor la afisare la lcd
#define NR_ORDINE 3 // pina la 255
// masivul pentru afisarea variabilelor la lcd
volatile u08 massive[NR_ORDINE];

u16 temp1 = 0;
if(variable==0)
{
massive[0] = ' '; massive[1] = ' '; massive[2] = '0';
}

// afisarea valorii care necesita numai un digit


else if(variable>0 && variable<10)
{
massive[0] = '0'; massive[1] = '0';
massive[2] = (u08) variable + 0x30;
}
// afisarea valorii care necesita 2 digiti
else if(variable>9 && variable<100)
{
massive[0] = '0';
massive[1] = (u08) ((variable*0.1)+0x30);
massive[2] = (u08) (((int)variable%10)+0x30);
}
// afisarea valorii care necesita 3 digiti
else if(variable>99 && variable<256)
{
massive[0] = (u08) ((variable*0.01)+0x30);
temp1 = variable*0.01;
temp1 = variable - (temp1*100);
massive[1] = (u08) ((temp1*0.1)+0x30);
massive[2] = (u08) (((int)temp1%10)+0x30);
}

// afisarea
__LCD_GoTo_XY(row, addr);
for(i=0;i<NR_ORDINE;i++)
__LCD_write_data(massive[i]);
}
Schema in Proteus:

Concluzie:

Efectuind acest laborator am realizarea interfeta de intrare prin tastatura


4x4,am definit functia de colectare a caracterelor de la tastatura.Am definit o
functie de afisare a simbolului tastei apasate de pe afisorul alfanumeric utilizat si
am realizat un redactor pentru sistemul construit.
Lucrarea a fost efectuata cu succes si in viitor vom avea posibilitatea de a crea
tatsaturi cu si mai multe caractere si cu si mai multe butoane.

S-ar putea să vă placă și

  • Anexa 1 - A4
    Anexa 1 - A4
    Document2 pagini
    Anexa 1 - A4
    Nicu Rotari
    Încă nu există evaluări
  • Arme de Distrugere in Masa
    Arme de Distrugere in Masa
    Document27 pagini
    Arme de Distrugere in Masa
    Nicu Rotari
    Încă nu există evaluări
  • Arme de Distrugere in Masa-733
    Arme de Distrugere in Masa-733
    Document5 pagini
    Arme de Distrugere in Masa-733
    Nicu Rotari
    Încă nu există evaluări
  • LAB7 Rotari Nicu (IBM-172)
    LAB7 Rotari Nicu (IBM-172)
    Document18 pagini
    LAB7 Rotari Nicu (IBM-172)
    Nicu Rotari
    Încă nu există evaluări
  • Probleme Ale Mediului Natural
    Probleme Ale Mediului Natural
    Document4 pagini
    Probleme Ale Mediului Natural
    Nicu Rotari
    Încă nu există evaluări
  • LAB5
    LAB5
    Document8 pagini
    LAB5
    Nicu Rotari
    Încă nu există evaluări
  • EM44
    EM44
    Document8 pagini
    EM44
    Nicu Rotari
    Încă nu există evaluări
  • LAB4
    LAB4
    Document12 pagini
    LAB4
    Nicu Rotari
    Încă nu există evaluări
  • LAB3
    LAB3
    Document13 pagini
    LAB3
    Nicu Rotari
    Încă nu există evaluări
  • LAB1
    LAB1
    Document18 pagini
    LAB1
    Nicu Rotari
    Încă nu există evaluări