SlideShare a Scribd company logo
1 of 24
Universitatea „Politehnica” din Timisoara
Facultatea de Electronica si Telecomunicatii
Proiect de procesoare
Calculator pentru operatii
matematice de baza
Profesor indrumator: Echipa 6:
As.Ing. Sorin Popescu Gheorghe Stefan Ionut EA 1.2
Martincsek Cristian EA 1.3
Duta Razvan EA 1.2
Timişoara
2014-2015
2
Cuprins
1. Introducere 3
2. Schema bloc-explicatii de functionare 4
3. Componente principale 5
3.1 PIC 16F877 5
3.2 LCD16x2 7
3.3 Circuitul MAX232 10
3.4 Conectori 11
3.4.1 ConectorDB9 11
3.4.2 ConecotrICSP 11
4. BOM 12
5. Schema electrica 13
6. Descrierea schemei electrice 14
7. Cablajul 16
7.1 Top layer 16
7.2 Silkscreen top layer 16
7.3 Bottom layer 17
7.4 Silkscreen bottom layer 17
7.5 Drill drawing 18
8. Codul sursa 19
9. Simularea 23
10. Bibliografie 24
3
Introducere
In realizarea proiectului de fata s-a pornit de la cerinta de a alege un
microcontroler cu memorie flash programabila si sa aibe o interfata de
programare ISP (In System Programming) sau ICP (In Circuit Programming).
Echipa de proiect a putut astfel alege dintr-o paleta foarte larga de aplicatii
pentru tema proiectului, putand folosi orice microcontroler care respecta
constrangerile de mai sus.
Microcontrolerul ales este PIC16F877 produs de firma Microchip
Technology. Acesta are o memorie Flash de 8K Bytes si este programabil ISP. In
alegerea temei proiectului s-a ales una din aplicatiile destul de intalnite in lucrul
cu microcontrolere, dar folositoare in viata de zi cu zi, respectiv realizarea unui
calculator.
Pentru realizarea acestuia s-a folosit o tastatura matrice X-Y cu 16 butoane
care contine atat cifrele de la 0 pana la 9 dar si semnele + - / * = si o tasta de clear
care permite stergerea informatiei de pe display in orice moment iar pentru
afisarea datelor un LCD 2x16.
4
Schema bloc-explicatii de functionare
Datele se preiau de la tastatura 4x4 alcatuita din 16 butoane care se afla in
afara PCB-ului si este conectata printr-un fir panglica si un conector in linie cu 8
pini. Microcontrolerul citeste datele primite de la tastatura realizeaza operatia
dorita si ofera raspunsul pe un afisaj digital.
LCD-ul mai sus mentionat, asemenea tastaturii nu se gaseste pe PCB, ci se
conecteaza cu ajutorul unui fir panglica si un conector IDC la circuit din exterior.
Pentru a realiza interfata seriala RS-232 cu PC-ul se foloseste circuitul
MAX232 impreuna cu conectorul DB9-F.
Pentru punerea programului pe microcontrolerul PIC16F877 prin
intermediul programatorului se foloseste conectorul ICSP.
In circuit a fost prevazut si un bloc de alimentare care indiferent de
tensiunea primita (in gama 9-17 V) va oferi la iesire LCD-ului, microcontroler-ului
si integratului MAX232 o tensiune fixa de 5 V.
Frecventa necesara microcontroler-ului este oferita de catre un cristal de
cuart de 20MHz si ptr orice eventualitate schema a fost prevazuta si cu un switch
care in momentul actionarii va trage pinul MCLR al integratului PIC16F877 la
masa, fapt care va declansa astfel resetarea sa.
5
Componente principale
PIC 16F877
Specificaţiile unităţii centrale:
• unitate centrala (CPU) de tip RISC;
• 35 de instrucţiuni;
• toate instrucţiunile se execută într-un ciclu al unităţii centrale, cu
excepţia instrucţiunlor de ramificarea programuluicare se execută în două cicluri CPU;
• frecvenţa de ceas: 20 MHz (durata ciclului instrucţiuniide 200 ns);
• memoria: maximum 8k cuvinte de 14 biţi de memorieFLASH;maximum368 octeţi
de memorie de date - Data Memory -(RAM); maximum 256 octeţi de memorie de date
EEPROM;
• microcontroleruleste compatibilpin la pin cu PIC16C73B/74B/76/77
• posibilitatea tratării întreruperilor de la 14 surse de întrerupere;
• stivă hardware cu opt nivele; Power-up Timer (PWRT) – temporizare la aplicarea
tensiunii de alimentare, şi Oscillator Start-up Timer (OST) – stabilizarea oscilatorului la
pornire;
• Wtchdog Timer (WDT) cu propriuloscilator RC on-chip pentru funcţionaresigură;
• mecanism de protecţie a codului programabil;
• mod SLEEP pentru economisirea energiei;
• opţiuni selectabile pentru oscilator;
• tehnologie CMOS FLASH/EEPROM de consum redus şi de viteză ridicată;
• circuitul este în întregime de tip static;
• In-CircuitSerial Programming (ICSP) - programarea serială directă a
circuituui– prin intermediula doi pini;
• posibilitate de programareserială cu o singură tensiunede 5V;
• In-CircuitDebugging – depanaredirectă la circuit – prin intermediul a doi pini;
• acces scriere/citirea
procesoruluila memoria de
program;
• domeniul tensiunilor de
alimentare: 2,0V la 5,5V;
• curent maxim
absorbit: 25mA;
Conexiunile externe:
6
Organizarea memoriei
Microcontrolerul are 3 blocuri de memorie. Memoria de program şi
memoria de date au magistrale separate şi deci se pote realiza accesul
simultan la date şi la program.
Contorul de program are 13 biţi ce poate adresa un spaţiu de memorie
program de 8K x 14 biţi. Accesarea locaţiilor în afara spaţiului fizic al memoriei
implementate va produceo adresarewraparound.
Vectorul RESET este 0000h iar vectorul de întrerupere este
0004h. Memoria este paginată iar paginilesunt:
• pagina 0 la adresele0005h la 07FFh inclusiv;
• pagina 1 la adresele0800h la 0FFFh inclusiv;
• pagina 2 la adresele1000h la 17FFh inclusiv;
•pagina 3 la adresele1800h la 1FFFh inclusiv
Organizarea memoriei de date
Memoria de date este împărţită în 4 bank-urice conţin registrelede uz
general (General Purpose Registers) şi registrele funcţiilor speciale (Special
Function Registers).
Selecţia bank-urilor se face cu ajutorul biţilor RP1 (STATUS<6>) şi
RP0 (STATUS<5>).
RP1:RP0 Bank
00 0
01 1
10 2
11 3
Fiecare bank din memoria statică are 128 de octeţi (7Fh). Locaţiile la
adresele mici sunt rezervate regiătrilor funcţiilor speciale (SFR) iar sub acestea
se găsesc regiştrii de uy general (GPR). Fiecare bank are proprii regiştrii SFR
dar anumiţi regiştrii SFR dintr-un bank se pot găsi şi într-un alt bank pentru
reducerea dimensiunii codului şi pentru acces mai rapid la aceşti regiştrii.
Regiştrii de uz general pot fi accesaţi atât în mod direct cât şi indirect
prin intermediul regiştrilor de selecţie: File Select Register (FSR).
7
Schema bloc a microcontrolerului PIC16F877
LCD16x2
LCD 16x2 este un modul foarte de bază şi este foarte frecvent utilizat în
diverse dispozitive şi circuite pentru afisarea datelor. LCD-urile sunt economice;
uşor programabile, nu au nici o limitare de afişarea caracterelor speciale chiar şi
personalizate (spre deosebire de în şapte segmente).
Un display 16x2 inseamna ca poate afisa 16 caractere pe linie şi are 2 linii.
În acest LCD fiecare caracter este afişat în matrice de 5x7 pixeli. Acest LCD are
două registre, şi anume, comandă şi de date.
Registrul comanda contine o serie de comenzi predefinite. O comandă este
o instrucţiune dată la LCD pentru a face o sarcină predefinit ca aceasta initializare,
ecran de compensare, stabilind poziţia cursorului, controlul display. Registrul de
8
date stochează datele pentru a fi afişate pe ecranul LCD. Datele reprezinta
valoarea ASCII a caracterului care urmează să fie afişat pe ecranul LCD.
Figura 6: Configuratia pinilor LCD 2x16
Figura 7:
Schema bloc a LCD
2x16
Număr Pin Simbol Funcţie
1 VSS GND(masa)
2 VDD Alimentare +5V
3 VO Ajustare contrast
4 RS Registru selecţie intrare
5 R/W Folosit pentru scriere/citire
6 E Semnalul de declansare scriere/citire
7~10 DB0~DB3 Linie de date
11~14 DB4~DB7 Linie de date
- A Linie de alimentare pentru LED-ul backlight (+)
- K Linie de alimentare pentru LED-ul backlight (-)
9
Tabelul de comanda a LCD-ului
"*" - Not Used/Ignored. This bit can be either "1" or "0"
Set Cursor Move Direction:
ID - Increment the Cursor After Each Byte Written to Display if Set
S - Shift Display when Byte Written to Display
Enable Display/Cursor
D - Turn Display On(1)/Off(0)
C - Turn Cursor On(1)/Off(0)
B - Cursor Blink On(1)/Off(0)
Move Cursor/Shift Display
SC - Display Shift On(1)/Off(0)
RL - Direction of Shift
Right(1)/Left(0)
Set Interface Length
DL - Set Data Interface Length
8(1)/4(0)
N - Number of Display Lines
1(0)/2(1)
F - Character Font
5x10(1)/5x7(0)
Poll the "Busy Flag"
BF - This bit is set while the
LCD is processing
Move Cursor to CGRAM/Display
A - Address
Read/Write ASCII to the Display
D - Data
Tabel de comanda pentru scrierea
datelor
10
Circuitul MAX232
Circuitul MAX232 este un circuit dual driver/receptor ce include un
generator de voltaje capacitive pentru a furniza nivelele de voltaj ale standardului
EIA-232 folosind curent doar de la o singură sursă de alimentare de 5V. Fiecare
receptor converteşte intrările EIA-232 în nivele TTL/CMOS de 5V. Aceşti receptori
au un prag tipic de 1.3V şi un hysterezis tipic de 0.5 V şi pot accepta intrări de 
30V. Fiecare driver converteşte intrările de nivel TTL/CMOS în nivele EIA-232.
Caracteristici principale: operează cu o singură sursă de alimentare de 5V,
are doi driveri şi doi receptori si funcţionează cu un curent tipic de 8mA. Aplicaţii
unde poate fi folosit: sisteme cu baterii, terminale, modemuri, computere
Figura 9: Configuratia pinilor MAX232
Figura 10: Niveluri de tensiune RS-232
11
Conectori
Conector DB 9 este utilizat pentru a seputea realiza interfata seriala RS-232
cu calculatorul.
Figura 11 Configuratia Pinilor DB-9
Conector ICSP
Programarea ICSP (“in-circuit-serial programming”) inseamna posibilitatea
de a programa procesorul fara a-l demonta din circuit; exista si varianta
programarii separate, prin scoaterea din soclu si montarea in soclul unui
programator dedicat.
Programarea ICSP presupune existenta a 2 componente:
1) circuitul de programare (programatorul), care se conecteaza la mufa ISP a
placutei si la portul serial/paralel/USB al PC-ului
2) soft-ul de programare, care preia fisierul utilizator si il transmite
programatorului. Trebuie sa fie
compatibil cu acesta din urma.
Figura 11: Configuratia Pinilor
Figura 12: Semnificatia pinilor
12
BOM
13
Schema electrica
14
Descrierea schemei electrice
R13, R14 si butonul numit SW_MCLR formeaza circuitul de reset. Operatia
de reset poate fi realizata si in mod automat fara a fi necesara apasarea manuala
a butonului SW_MCLR de catre programatorul care se conecteaza la conectorul
ISP . Acest reset este necesar pentru a asigura pornirea în bune condiţii a
procesorului; în lipsa lui, tensiunile tranzitorii care apar în momentul alimentării
pot duce la ajungerea procesorului intr-o stare incertă. Practic, linia RESET e
ţinută în “0” un timp semnificativ mai lung decît are nevoie sursa de alimentare să
intre în regim staţionar.
Condensatoarele C7 si C8 se vor lipi cat mai aproape de procesor, langa
pinii 12 respectiv 35 (VCC). Ele sunt condensatoare de decuplare şi sunt specifice
alimentarii oricărui circuit digital - asigură o “rezervă” de energie în momentul
comutării, şi astfel previne apariţia zgomotului de comutare pe liniile de
alimentare.
Cristalul de cuarţ, împreuna cu condensatoarele C6, C5 şi cu amplificatorul
intern de la bornele XTAL1,2 formeaza un oscilator cu cuarţ. Aceste componente
se vor lipi, de asemenea, cît mai aproape de pinii respectivi ai procesorului.
Circuitul este alimentat de la +12V prin conectorul de tip jack J2.
Standardul RS232 prevede o tensiune între +6V..+15V faţă de masă pentru
“0” logic şi de -6V..-15V faţă de masă pentru “1” logic. Se observă că logica este
“inversată” şi sînt necesare tensiuni negative, care nu sînt furnizatedirect de către
sursa de alimentare.
Pinii RxD, TxD ai procesorului se conectează la pinii cu acelaşi nume ai
convertorului de nivel realizat cu circuitul MAX232 .Rolul acestuia este sa
convertească nivelurile TTL (0..5V) în
niveluri RS232, şi viceversa; practic, tensiunile +3V…-15V şi -3V… -15V se obtin
folosind un convertor intern cu capacităţi comutate, care foloseşte
condensatoarele externe C9-C13 de 1uF.
In final trebuie sa se obtina o tensiune intre 3..15V cu polaritatea
corescpunzatoare (+) pe pinul 2 VS+ si (-) pe pinul 6 VS-.
Mufa DB9 de tip mamă (conectorul J2) este cablată după standardul DCE
(Data Communications Equipment):
Pin mufa DB9 Descriere
2 TX
3 RX
5 GND
15
Aceasta înseamnă ca se va folosi un cablu serial direct (1-la-1) pentru
conectarea la PC, care este echipat cu o mufa de tip tată, cablată dupa standardul
DTE (Data Terminal Equipment), la care pinii 2 şi 3 sînt inversaţi.
Afisarea datelor se face prin LCD-ul 2x16, datele transmitandu-se de la
portul PB al MCU la pinii 11-14 ai ai afisajului. Intrarile de comanda date de
valorile pinilor 4-6: E, RW, RS sunt conectate de asemenea la portul B al MCU.
J1 este conectorul de programare ISP (In-System Programming); acesta
permite programarea memoriei FLASH din procesor folosind un programator
extern.
16
Cablajul
17
18
19
Codul sursa
//////////////////////////////////////////////////////////////////////Main///////////////////////////////////////////////////////////////////
#include "Includes.h"
void main(void)
{
char key; // tine evidenta butonuluiapasat
int num1 = 0; // primul nr
char func = '+'; // functia matematica ce va fi realizata intre cele doua numere
int num2 = 0; // al doilea nr
InitKeypad(); // Initialize Keypad
InitLCD(); // initializare LCD
while(1)
{
//get numb1
key = GetKey();
ClearLCDScreen(); // sterge ecran LCD
WriteDataToLCD(key);
num1 = get_num(key);
if(num1!=Error) // daca este inserata o valoare corecta aceasta este atribuita variabilei num1, altfel
se primeste un mesaj de eroare
{
// se receptioneaza functia dorita
key = GetKey();
WriteDataToLCD(key);
func = get_func(key); //verifica daca functia matematica ceruta este cea corecta
if(func!='e') //daca este corecta i se aloca variabilei func, alftel se primeste mesaj de
eroare
{
//se receptioneaza al doilea nr
key = GetKey();
WriteDataToLCD(key);
num2 = get_num(key);
if(num2!=Error) // daca este inserata o valoare corecta aceasta este atribuita variabilei
num1, altfel se primeste un mesaj de eroare {
key = GetKey();
WriteDataToLCD(key);
if(key == '=') //daca se apasa „=” se continua cu realizarea calculului
{
switch(func) //se alege functia
{
case '+': disp_num(num1+num2); break;
case '-': disp_num(num1-num2); break;
case 'x': disp_num(num1*num2); break;
case '/': disp_num(num1/num2); break;
}
}
else //orice alta tasta apasata in afara de „=” va fisa eroare
{
if(key == 'C') //daca se apasa clear screen se va sterge informatia
de pe LCD
ClearLCDScreen(); // se sterge informatia de pe LCD
else
DispError(0); //afiseaza eroare
}
}
}
20
}
}
}
/*
* Functions used inside main for
* making calculator are shown below
*/
int get_num(char ch) //se realizeaza conversia din char in int
{
int num = 0;
switch(ch)
{
case '0': num = 0; break;
case '1': num = 1; break;
case '2': num = 2; break;
case '3': num = 3; break;
case '4': num = 4; break;
case '5': num = 5; break;
case '6': num = 6; break;
case '7': num = 7; break;
case '8': num = 8; break;
case '9': num = 9; break;
case 'C': ClearLCDScreen(); num = Error; break;
default: DispError(0); num = Error; break; //atentioneaza ca s-a introdus o valoare gresita
}
return num;
}
char get_func(char chf) //detecteaza eroarea
{
if(chf=='C') //daca se apasa clear screen se va sterge informatia de pe LCD
{
ClearLCDScreen(); // se sterge informatia de pe LCD
return 'e';
}
if( chf!='+' && chf!='-' && chf!='x' && chf!='/' ) //daca functia matematica aleasa nu face parte
din functiile de baza ale calculatorului, va fi afisata o eroare
{
DispError(1);
return 'e';
}
return chf; //decide ca functia aleasa e corecta => returneaza functia aleasa
}
void DispError(int numb) //afiseaza diverse mesaje de eroare
{
ClearLCDScreen(); // se sterge informatia de pe LCD
switch(numb)
{
case 0: WriteStringToLCD("Wrong Input"); break;
case 1: WriteStringToLCD("Wrong Function"); break;
default: WriteStringToLCD("Wrong Input"); break;
}
}
void disp_num(int numb) //afiseaza cifre pe LCD
{
unsigned char UnitDigit = 0;
unsigned char TenthDigit = 0;
if(numb<0)
{
numb = -1*numb; // tranforma un nr negativ intr-unul pozitiv
WriteDataToLCD('-'); // afiseaza semnul – pe LCD
21
}
TenthDigit = (numb/10); // gaseste al 10-lea digit
if( TenthDigit != 0) // daca este 0 nu il afiseaza
WriteDataToLCD(TenthDigit+0x30); // afiseaza al 10-lea digit pe LCD
UnitDigit = numb - TenthDigit*10;
WriteDataToLCD(UnitDigit+0x30); // afiseaza digit-ul unitatilor pe LCD
}
//////////////////////////////////////////////////////////////////////LCD///////////////////////////////////////////////////////////////////
#include "Includes.h"
void ToggleEpinOfLCD(void)
{
LCD_E = 1; // ofera un impuls la pinul E al LCD-ului
__delay_us(E_Delay); // ptr a initializa LCD si acesta sa poate primi informatii de pe liniile de date
LCD_E = 0;
__delay_us(E_Delay);
}
void WriteCommandToLCD(unsigned char Command)
{
LCD_RS = 0; // primeste comanda
LCD_PORT &= 0x0F; // pinii de date sunt pe 0
LCD_PORT |= (Command&0xF0);
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
LCD_PORT &= 0x0F; // pinii de date sunt pe 0
LCD_PORT |= ((Command<<4)&0xF0);
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
}
void WriteDataToLCD(char LCDChar)
{
LCD_RS = 1; // primeste date
LCD_PORT &= 0x0F; // pinii de date sunt pe 0
LCD_PORT |= (LCDChar&0xF0);
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
LCD_PORT &= 0x0F; // pinii de date sunt pe 0
LCD_PORT |= ((LCDChar<<4)&0xF0);
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
}
void InitLCD(void)
{
// toti pinii sunt declarati iesiri
LCD_E = 0; // E = 0
LCD_RS = 0; // RS = 0
LCD_Data_Bus_D4 = 0; // linia de date = 0
LCD_Data_Bus_D5 = 0; // linia de date = 0
LCD_Data_Bus_D6 = 0; // linia de date = 0
LCD_Data_Bus_D7 = 0; // linia de date = 0
LCD_E_Dir = 0; // declarat ca iesire
LCD_RS_Dir = 0; // declarat ca iesire
LCD_Data_Bus_Dir_D4 = 0; // declarat ca iesire
LCD_Data_Bus_Dir_D5 = 0; // declarat ca iesire
LCD_Data_Bus_Dir_D6 = 0; // declarat ca iesire
LCD_Data_Bus_Dir_D7 = 0; // declarat ca iesire
22
///////////////// procedura de reset din datasheet-ulLCD-ului //////////////
__delay_ms(40);
LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0
LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
__delay_ms(6);
LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0
LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date bus
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
__delay_us(300);
LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0
LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
__delay_ms(2);
LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0
LCD_PORT |= 0x20; // se scrie valoarea 0x3 pe liniile de date
ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului
__delay_ms(2);
///////////////// finalul procedurii de reset //////////////
WriteCommandToLCD(0x28);
WriteCommandToLCD(0x0c); //display on,cursoroff,blink off
WriteCommandToLCD(0x01); //clear display
WriteCommandToLCD(0x06); //entry mode, set increment
}
void WriteStringToLCD(const char *s)
{
while(*s)
WriteDataToLCD(*s++); // afiseaza primul caracter pe LCD
}
void ClearLCDScreen(void) // sterge ecranul si aduce cursorul la pozitia initiala
{
WriteCommandToLCD(0x01); // sterge ecranul
__delay_ms(2);
}
//////////////////////////////////////////////////////////////////////TST///////////////////////////////////////////////////////////////////
#include "Includes.h"
void InitKeypad(void)
{
Keypad_PORT = 0x00; // seteaza pinii conectati la tastatura pe 0
Keypad_PORT_Dir = 0xF0; // seteaza ultimii 4 pini ca intrari si primii 4 ca iesiri
OPTION_REG &= 0x7F;
}
char READ_SWITCHES(void) //scaneaza fiecare buton
{
RowA = 0; RowB = 1; RowC = 1; RowD = 1; //testeaza randul A
if (C1 == 0) { __delay_ms(250); while (C1==0); return '7'; }
if (C2 == 0) { __delay_ms(250); while (C2==0); return '8'; }
if (C3 == 0) { __delay_ms(250); while (C3==0); return '9'; }
if (C4 == 0) { __delay_ms(250); while (C4==0); return '/'; }
RowA = 1; RowB = 0; RowC = 1; RowD = 1; //testeaza randul B
if (C1 == 0) { __delay_ms(250); while (C1==0); return '4'; }
if (C2 == 0) { __delay_ms(250); while (C2==0); return '5'; }
if (C3 == 0) { __delay_ms(250); while (C3==0); return '6'; }
if (C4 == 0) { __delay_ms(250); while (C4==0); return 'x'; }
RowA = 1; RowB = 1; RowC = 0; RowD = 1; // testeaza randul C
23
if (C1 == 0) { __delay_ms(250); while (C1==0); return '1'; }
if (C2 == 0) { __delay_ms(250); while (C2==0); return '2'; }
if (C3 == 0) { __delay_ms(250); while (C3==0); return '3'; }
if (C4 == 0) { __delay_ms(250); while (C4==0); return '-'; }
RowA = 1; RowB = 1; RowC = 1; RowD = 0; // testeaza randul D
if (C1 == 0) { __delay_ms(250); while (C1==0); return 'C'; }
if (C2 == 0) { __delay_ms(250); while (C2==0); return '0'; }
if (C3 == 0) { __delay_ms(250); while (C3==0); return '='; }
if (C4 == 0) { __delay_ms(250); while (C4==0); return '+'; }
return 'n'; // inseamna ca nu a fost apasat nici un buton
}
char GetKey(void) // primeste un caracter de la utilizator prin apasarea unui anumit buton
{
char key = 'n'; // presupune ca nu exista buton apasat
while(key=='n') // asteapta pana cand un buton este apasat
key = READ_SWITCHES(); // scaneaza reteaua (tastatura)de butoate in continuu
return key; //cand un buton este apasat,returneaza valoarea specifica acelui buton
}
Simularea
Cu ajutorul programului Proteus 8 Professional a fost conceputa schema
elementara din figura de mai jos prin intermediul careia s-a putut simula
functionarea softului fara a fi necesar un circuit fizic.
24
Bibliografie
http://picprojects.org.uk/
http://www.microchip.com/
http://www.hobbyprojects.com/microcontroller_tutorials.html
http://www.8052.com/
http://www.engineersgarage.com/
http://www.alldatasheet.com/
https://www.sparkfun.com
http://en.wikipedia.org/wiki/PIC_microcontroller
http://en.wikipedia.org/wiki/MAX232

More Related Content

Similar to Proiect PP

Controlul unui motor pas cu pas
Controlul unui motor pas cu pasControlul unui motor pas cu pas
Controlul unui motor pas cu paskramactar
 
curs microprocesoare si microcontrolere ASC Curs 2008.ppt
curs microprocesoare si microcontrolere ASC Curs 2008.pptcurs microprocesoare si microcontrolere ASC Curs 2008.ppt
curs microprocesoare si microcontrolere ASC Curs 2008.ppt9cqrb8vkfp
 
curs porti logice si circuite digitale lectie curs 2
curs porti logice si circuite digitale lectie curs 2curs porti logice si circuite digitale lectie curs 2
curs porti logice si circuite digitale lectie curs 2dertify455
 
Arduino alcoolmetru
Arduino alcoolmetruArduino alcoolmetru
Arduino alcoolmetruIulius Bors
 
Arduino comparatorul intern
Arduino comparatorul internArduino comparatorul intern
Arduino comparatorul internIulius Bors
 
Arduino comunicatie i2c
Arduino comunicatie i2cArduino comunicatie i2c
Arduino comunicatie i2cIulius Bors
 
Eap 203 numarator_4.0
Eap 203 numarator_4.0Eap 203 numarator_4.0
Eap 203 numarator_4.0Daniel Rosner
 
Eap 202 astabil_555_4.0
Eap 202 astabil_555_4.0Eap 202 astabil_555_4.0
Eap 202 astabil_555_4.0Daniel Rosner
 
Arduino matriceled8x8
Arduino matriceled8x8Arduino matriceled8x8
Arduino matriceled8x8Iulius Bors
 
Curs gratuitarduino lectia10-lcd-uri
Curs gratuitarduino lectia10-lcd-uriCurs gratuitarduino lectia10-lcd-uri
Curs gratuitarduino lectia10-lcd-uriIulius Bors
 
Referat placa de baza andrei
Referat placa de baza andreiReferat placa de baza andrei
Referat placa de baza andreiFlorin Iordache
 
Prezentarea calculatorului
Prezentarea calculatoruluiPrezentarea calculatorului
Prezentarea calculatoruluiSima Sorin
 

Similar to Proiect PP (20)

Controlul unui motor pas cu pas
Controlul unui motor pas cu pasControlul unui motor pas cu pas
Controlul unui motor pas cu pas
 
curs microprocesoare si microcontrolere ASC Curs 2008.ppt
curs microprocesoare si microcontrolere ASC Curs 2008.pptcurs microprocesoare si microcontrolere ASC Curs 2008.ppt
curs microprocesoare si microcontrolere ASC Curs 2008.ppt
 
9905i.pdf
9905i.pdf9905i.pdf
9905i.pdf
 
curs porti logice si circuite digitale lectie curs 2
curs porti logice si circuite digitale lectie curs 2curs porti logice si circuite digitale lectie curs 2
curs porti logice si circuite digitale lectie curs 2
 
Arduino alcoolmetru
Arduino alcoolmetruArduino alcoolmetru
Arduino alcoolmetru
 
Arduino rtc
Arduino rtcArduino rtc
Arduino rtc
 
Arduino comparatorul intern
Arduino comparatorul internArduino comparatorul intern
Arduino comparatorul intern
 
Manual casa de_marcat_orgtech_abac
Manual casa de_marcat_orgtech_abacManual casa de_marcat_orgtech_abac
Manual casa de_marcat_orgtech_abac
 
Arduino comunicatie i2c
Arduino comunicatie i2cArduino comunicatie i2c
Arduino comunicatie i2c
 
Arduino - GPIO
Arduino - GPIOArduino - GPIO
Arduino - GPIO
 
Curs calcul
Curs calculCurs calcul
Curs calcul
 
Eap 203 numarator_4.0
Eap 203 numarator_4.0Eap 203 numarator_4.0
Eap 203 numarator_4.0
 
Eap 202 astabil_555_4.0
Eap 202 astabil_555_4.0Eap 202 astabil_555_4.0
Eap 202 astabil_555_4.0
 
Arduino matriceled8x8
Arduino matriceled8x8Arduino matriceled8x8
Arduino matriceled8x8
 
E A P D 3 Numarator
E A P  D 3 NumaratorE A P  D 3 Numarator
E A P D 3 Numarator
 
Mc cap 7
Mc cap 7Mc cap 7
Mc cap 7
 
Curs gratuitarduino lectia10-lcd-uri
Curs gratuitarduino lectia10-lcd-uriCurs gratuitarduino lectia10-lcd-uri
Curs gratuitarduino lectia10-lcd-uri
 
Referat placa de baza andrei
Referat placa de baza andreiReferat placa de baza andrei
Referat placa de baza andrei
 
Cardul bancar
Cardul bancarCardul bancar
Cardul bancar
 
Prezentarea calculatorului
Prezentarea calculatoruluiPrezentarea calculatorului
Prezentarea calculatorului
 

Proiect PP

  • 1. Universitatea „Politehnica” din Timisoara Facultatea de Electronica si Telecomunicatii Proiect de procesoare Calculator pentru operatii matematice de baza Profesor indrumator: Echipa 6: As.Ing. Sorin Popescu Gheorghe Stefan Ionut EA 1.2 Martincsek Cristian EA 1.3 Duta Razvan EA 1.2 Timişoara 2014-2015
  • 2. 2 Cuprins 1. Introducere 3 2. Schema bloc-explicatii de functionare 4 3. Componente principale 5 3.1 PIC 16F877 5 3.2 LCD16x2 7 3.3 Circuitul MAX232 10 3.4 Conectori 11 3.4.1 ConectorDB9 11 3.4.2 ConecotrICSP 11 4. BOM 12 5. Schema electrica 13 6. Descrierea schemei electrice 14 7. Cablajul 16 7.1 Top layer 16 7.2 Silkscreen top layer 16 7.3 Bottom layer 17 7.4 Silkscreen bottom layer 17 7.5 Drill drawing 18 8. Codul sursa 19 9. Simularea 23 10. Bibliografie 24
  • 3. 3 Introducere In realizarea proiectului de fata s-a pornit de la cerinta de a alege un microcontroler cu memorie flash programabila si sa aibe o interfata de programare ISP (In System Programming) sau ICP (In Circuit Programming). Echipa de proiect a putut astfel alege dintr-o paleta foarte larga de aplicatii pentru tema proiectului, putand folosi orice microcontroler care respecta constrangerile de mai sus. Microcontrolerul ales este PIC16F877 produs de firma Microchip Technology. Acesta are o memorie Flash de 8K Bytes si este programabil ISP. In alegerea temei proiectului s-a ales una din aplicatiile destul de intalnite in lucrul cu microcontrolere, dar folositoare in viata de zi cu zi, respectiv realizarea unui calculator. Pentru realizarea acestuia s-a folosit o tastatura matrice X-Y cu 16 butoane care contine atat cifrele de la 0 pana la 9 dar si semnele + - / * = si o tasta de clear care permite stergerea informatiei de pe display in orice moment iar pentru afisarea datelor un LCD 2x16.
  • 4. 4 Schema bloc-explicatii de functionare Datele se preiau de la tastatura 4x4 alcatuita din 16 butoane care se afla in afara PCB-ului si este conectata printr-un fir panglica si un conector in linie cu 8 pini. Microcontrolerul citeste datele primite de la tastatura realizeaza operatia dorita si ofera raspunsul pe un afisaj digital. LCD-ul mai sus mentionat, asemenea tastaturii nu se gaseste pe PCB, ci se conecteaza cu ajutorul unui fir panglica si un conector IDC la circuit din exterior. Pentru a realiza interfata seriala RS-232 cu PC-ul se foloseste circuitul MAX232 impreuna cu conectorul DB9-F. Pentru punerea programului pe microcontrolerul PIC16F877 prin intermediul programatorului se foloseste conectorul ICSP. In circuit a fost prevazut si un bloc de alimentare care indiferent de tensiunea primita (in gama 9-17 V) va oferi la iesire LCD-ului, microcontroler-ului si integratului MAX232 o tensiune fixa de 5 V. Frecventa necesara microcontroler-ului este oferita de catre un cristal de cuart de 20MHz si ptr orice eventualitate schema a fost prevazuta si cu un switch care in momentul actionarii va trage pinul MCLR al integratului PIC16F877 la masa, fapt care va declansa astfel resetarea sa.
  • 5. 5 Componente principale PIC 16F877 Specificaţiile unităţii centrale: • unitate centrala (CPU) de tip RISC; • 35 de instrucţiuni; • toate instrucţiunile se execută într-un ciclu al unităţii centrale, cu excepţia instrucţiunlor de ramificarea programuluicare se execută în două cicluri CPU; • frecvenţa de ceas: 20 MHz (durata ciclului instrucţiuniide 200 ns); • memoria: maximum 8k cuvinte de 14 biţi de memorieFLASH;maximum368 octeţi de memorie de date - Data Memory -(RAM); maximum 256 octeţi de memorie de date EEPROM; • microcontroleruleste compatibilpin la pin cu PIC16C73B/74B/76/77 • posibilitatea tratării întreruperilor de la 14 surse de întrerupere; • stivă hardware cu opt nivele; Power-up Timer (PWRT) – temporizare la aplicarea tensiunii de alimentare, şi Oscillator Start-up Timer (OST) – stabilizarea oscilatorului la pornire; • Wtchdog Timer (WDT) cu propriuloscilator RC on-chip pentru funcţionaresigură; • mecanism de protecţie a codului programabil; • mod SLEEP pentru economisirea energiei; • opţiuni selectabile pentru oscilator; • tehnologie CMOS FLASH/EEPROM de consum redus şi de viteză ridicată; • circuitul este în întregime de tip static; • In-CircuitSerial Programming (ICSP) - programarea serială directă a circuituui– prin intermediula doi pini; • posibilitate de programareserială cu o singură tensiunede 5V; • In-CircuitDebugging – depanaredirectă la circuit – prin intermediul a doi pini; • acces scriere/citirea procesoruluila memoria de program; • domeniul tensiunilor de alimentare: 2,0V la 5,5V; • curent maxim absorbit: 25mA; Conexiunile externe:
  • 6. 6 Organizarea memoriei Microcontrolerul are 3 blocuri de memorie. Memoria de program şi memoria de date au magistrale separate şi deci se pote realiza accesul simultan la date şi la program. Contorul de program are 13 biţi ce poate adresa un spaţiu de memorie program de 8K x 14 biţi. Accesarea locaţiilor în afara spaţiului fizic al memoriei implementate va produceo adresarewraparound. Vectorul RESET este 0000h iar vectorul de întrerupere este 0004h. Memoria este paginată iar paginilesunt: • pagina 0 la adresele0005h la 07FFh inclusiv; • pagina 1 la adresele0800h la 0FFFh inclusiv; • pagina 2 la adresele1000h la 17FFh inclusiv; •pagina 3 la adresele1800h la 1FFFh inclusiv Organizarea memoriei de date Memoria de date este împărţită în 4 bank-urice conţin registrelede uz general (General Purpose Registers) şi registrele funcţiilor speciale (Special Function Registers). Selecţia bank-urilor se face cu ajutorul biţilor RP1 (STATUS<6>) şi RP0 (STATUS<5>). RP1:RP0 Bank 00 0 01 1 10 2 11 3 Fiecare bank din memoria statică are 128 de octeţi (7Fh). Locaţiile la adresele mici sunt rezervate regiătrilor funcţiilor speciale (SFR) iar sub acestea se găsesc regiştrii de uy general (GPR). Fiecare bank are proprii regiştrii SFR dar anumiţi regiştrii SFR dintr-un bank se pot găsi şi într-un alt bank pentru reducerea dimensiunii codului şi pentru acces mai rapid la aceşti regiştrii. Regiştrii de uz general pot fi accesaţi atât în mod direct cât şi indirect prin intermediul regiştrilor de selecţie: File Select Register (FSR).
  • 7. 7 Schema bloc a microcontrolerului PIC16F877 LCD16x2 LCD 16x2 este un modul foarte de bază şi este foarte frecvent utilizat în diverse dispozitive şi circuite pentru afisarea datelor. LCD-urile sunt economice; uşor programabile, nu au nici o limitare de afişarea caracterelor speciale chiar şi personalizate (spre deosebire de în şapte segmente). Un display 16x2 inseamna ca poate afisa 16 caractere pe linie şi are 2 linii. În acest LCD fiecare caracter este afişat în matrice de 5x7 pixeli. Acest LCD are două registre, şi anume, comandă şi de date. Registrul comanda contine o serie de comenzi predefinite. O comandă este o instrucţiune dată la LCD pentru a face o sarcină predefinit ca aceasta initializare, ecran de compensare, stabilind poziţia cursorului, controlul display. Registrul de
  • 8. 8 date stochează datele pentru a fi afişate pe ecranul LCD. Datele reprezinta valoarea ASCII a caracterului care urmează să fie afişat pe ecranul LCD. Figura 6: Configuratia pinilor LCD 2x16 Figura 7: Schema bloc a LCD 2x16 Număr Pin Simbol Funcţie 1 VSS GND(masa) 2 VDD Alimentare +5V 3 VO Ajustare contrast 4 RS Registru selecţie intrare 5 R/W Folosit pentru scriere/citire 6 E Semnalul de declansare scriere/citire 7~10 DB0~DB3 Linie de date 11~14 DB4~DB7 Linie de date - A Linie de alimentare pentru LED-ul backlight (+) - K Linie de alimentare pentru LED-ul backlight (-)
  • 9. 9 Tabelul de comanda a LCD-ului "*" - Not Used/Ignored. This bit can be either "1" or "0" Set Cursor Move Direction: ID - Increment the Cursor After Each Byte Written to Display if Set S - Shift Display when Byte Written to Display Enable Display/Cursor D - Turn Display On(1)/Off(0) C - Turn Cursor On(1)/Off(0) B - Cursor Blink On(1)/Off(0) Move Cursor/Shift Display SC - Display Shift On(1)/Off(0) RL - Direction of Shift Right(1)/Left(0) Set Interface Length DL - Set Data Interface Length 8(1)/4(0) N - Number of Display Lines 1(0)/2(1) F - Character Font 5x10(1)/5x7(0) Poll the "Busy Flag" BF - This bit is set while the LCD is processing Move Cursor to CGRAM/Display A - Address Read/Write ASCII to the Display D - Data Tabel de comanda pentru scrierea datelor
  • 10. 10 Circuitul MAX232 Circuitul MAX232 este un circuit dual driver/receptor ce include un generator de voltaje capacitive pentru a furniza nivelele de voltaj ale standardului EIA-232 folosind curent doar de la o singură sursă de alimentare de 5V. Fiecare receptor converteşte intrările EIA-232 în nivele TTL/CMOS de 5V. Aceşti receptori au un prag tipic de 1.3V şi un hysterezis tipic de 0.5 V şi pot accepta intrări de  30V. Fiecare driver converteşte intrările de nivel TTL/CMOS în nivele EIA-232. Caracteristici principale: operează cu o singură sursă de alimentare de 5V, are doi driveri şi doi receptori si funcţionează cu un curent tipic de 8mA. Aplicaţii unde poate fi folosit: sisteme cu baterii, terminale, modemuri, computere Figura 9: Configuratia pinilor MAX232 Figura 10: Niveluri de tensiune RS-232
  • 11. 11 Conectori Conector DB 9 este utilizat pentru a seputea realiza interfata seriala RS-232 cu calculatorul. Figura 11 Configuratia Pinilor DB-9 Conector ICSP Programarea ICSP (“in-circuit-serial programming”) inseamna posibilitatea de a programa procesorul fara a-l demonta din circuit; exista si varianta programarii separate, prin scoaterea din soclu si montarea in soclul unui programator dedicat. Programarea ICSP presupune existenta a 2 componente: 1) circuitul de programare (programatorul), care se conecteaza la mufa ISP a placutei si la portul serial/paralel/USB al PC-ului 2) soft-ul de programare, care preia fisierul utilizator si il transmite programatorului. Trebuie sa fie compatibil cu acesta din urma. Figura 11: Configuratia Pinilor Figura 12: Semnificatia pinilor
  • 14. 14 Descrierea schemei electrice R13, R14 si butonul numit SW_MCLR formeaza circuitul de reset. Operatia de reset poate fi realizata si in mod automat fara a fi necesara apasarea manuala a butonului SW_MCLR de catre programatorul care se conecteaza la conectorul ISP . Acest reset este necesar pentru a asigura pornirea în bune condiţii a procesorului; în lipsa lui, tensiunile tranzitorii care apar în momentul alimentării pot duce la ajungerea procesorului intr-o stare incertă. Practic, linia RESET e ţinută în “0” un timp semnificativ mai lung decît are nevoie sursa de alimentare să intre în regim staţionar. Condensatoarele C7 si C8 se vor lipi cat mai aproape de procesor, langa pinii 12 respectiv 35 (VCC). Ele sunt condensatoare de decuplare şi sunt specifice alimentarii oricărui circuit digital - asigură o “rezervă” de energie în momentul comutării, şi astfel previne apariţia zgomotului de comutare pe liniile de alimentare. Cristalul de cuarţ, împreuna cu condensatoarele C6, C5 şi cu amplificatorul intern de la bornele XTAL1,2 formeaza un oscilator cu cuarţ. Aceste componente se vor lipi, de asemenea, cît mai aproape de pinii respectivi ai procesorului. Circuitul este alimentat de la +12V prin conectorul de tip jack J2. Standardul RS232 prevede o tensiune între +6V..+15V faţă de masă pentru “0” logic şi de -6V..-15V faţă de masă pentru “1” logic. Se observă că logica este “inversată” şi sînt necesare tensiuni negative, care nu sînt furnizatedirect de către sursa de alimentare. Pinii RxD, TxD ai procesorului se conectează la pinii cu acelaşi nume ai convertorului de nivel realizat cu circuitul MAX232 .Rolul acestuia este sa convertească nivelurile TTL (0..5V) în niveluri RS232, şi viceversa; practic, tensiunile +3V…-15V şi -3V… -15V se obtin folosind un convertor intern cu capacităţi comutate, care foloseşte condensatoarele externe C9-C13 de 1uF. In final trebuie sa se obtina o tensiune intre 3..15V cu polaritatea corescpunzatoare (+) pe pinul 2 VS+ si (-) pe pinul 6 VS-. Mufa DB9 de tip mamă (conectorul J2) este cablată după standardul DCE (Data Communications Equipment): Pin mufa DB9 Descriere 2 TX 3 RX 5 GND
  • 15. 15 Aceasta înseamnă ca se va folosi un cablu serial direct (1-la-1) pentru conectarea la PC, care este echipat cu o mufa de tip tată, cablată dupa standardul DTE (Data Terminal Equipment), la care pinii 2 şi 3 sînt inversaţi. Afisarea datelor se face prin LCD-ul 2x16, datele transmitandu-se de la portul PB al MCU la pinii 11-14 ai ai afisajului. Intrarile de comanda date de valorile pinilor 4-6: E, RW, RS sunt conectate de asemenea la portul B al MCU. J1 este conectorul de programare ISP (In-System Programming); acesta permite programarea memoriei FLASH din procesor folosind un programator extern.
  • 17. 17
  • 18. 18
  • 19. 19 Codul sursa //////////////////////////////////////////////////////////////////////Main/////////////////////////////////////////////////////////////////// #include "Includes.h" void main(void) { char key; // tine evidenta butonuluiapasat int num1 = 0; // primul nr char func = '+'; // functia matematica ce va fi realizata intre cele doua numere int num2 = 0; // al doilea nr InitKeypad(); // Initialize Keypad InitLCD(); // initializare LCD while(1) { //get numb1 key = GetKey(); ClearLCDScreen(); // sterge ecran LCD WriteDataToLCD(key); num1 = get_num(key); if(num1!=Error) // daca este inserata o valoare corecta aceasta este atribuita variabilei num1, altfel se primeste un mesaj de eroare { // se receptioneaza functia dorita key = GetKey(); WriteDataToLCD(key); func = get_func(key); //verifica daca functia matematica ceruta este cea corecta if(func!='e') //daca este corecta i se aloca variabilei func, alftel se primeste mesaj de eroare { //se receptioneaza al doilea nr key = GetKey(); WriteDataToLCD(key); num2 = get_num(key); if(num2!=Error) // daca este inserata o valoare corecta aceasta este atribuita variabilei num1, altfel se primeste un mesaj de eroare { key = GetKey(); WriteDataToLCD(key); if(key == '=') //daca se apasa „=” se continua cu realizarea calculului { switch(func) //se alege functia { case '+': disp_num(num1+num2); break; case '-': disp_num(num1-num2); break; case 'x': disp_num(num1*num2); break; case '/': disp_num(num1/num2); break; } } else //orice alta tasta apasata in afara de „=” va fisa eroare { if(key == 'C') //daca se apasa clear screen se va sterge informatia de pe LCD ClearLCDScreen(); // se sterge informatia de pe LCD else DispError(0); //afiseaza eroare } } }
  • 20. 20 } } } /* * Functions used inside main for * making calculator are shown below */ int get_num(char ch) //se realizeaza conversia din char in int { int num = 0; switch(ch) { case '0': num = 0; break; case '1': num = 1; break; case '2': num = 2; break; case '3': num = 3; break; case '4': num = 4; break; case '5': num = 5; break; case '6': num = 6; break; case '7': num = 7; break; case '8': num = 8; break; case '9': num = 9; break; case 'C': ClearLCDScreen(); num = Error; break; default: DispError(0); num = Error; break; //atentioneaza ca s-a introdus o valoare gresita } return num; } char get_func(char chf) //detecteaza eroarea { if(chf=='C') //daca se apasa clear screen se va sterge informatia de pe LCD { ClearLCDScreen(); // se sterge informatia de pe LCD return 'e'; } if( chf!='+' && chf!='-' && chf!='x' && chf!='/' ) //daca functia matematica aleasa nu face parte din functiile de baza ale calculatorului, va fi afisata o eroare { DispError(1); return 'e'; } return chf; //decide ca functia aleasa e corecta => returneaza functia aleasa } void DispError(int numb) //afiseaza diverse mesaje de eroare { ClearLCDScreen(); // se sterge informatia de pe LCD switch(numb) { case 0: WriteStringToLCD("Wrong Input"); break; case 1: WriteStringToLCD("Wrong Function"); break; default: WriteStringToLCD("Wrong Input"); break; } } void disp_num(int numb) //afiseaza cifre pe LCD { unsigned char UnitDigit = 0; unsigned char TenthDigit = 0; if(numb<0) { numb = -1*numb; // tranforma un nr negativ intr-unul pozitiv WriteDataToLCD('-'); // afiseaza semnul – pe LCD
  • 21. 21 } TenthDigit = (numb/10); // gaseste al 10-lea digit if( TenthDigit != 0) // daca este 0 nu il afiseaza WriteDataToLCD(TenthDigit+0x30); // afiseaza al 10-lea digit pe LCD UnitDigit = numb - TenthDigit*10; WriteDataToLCD(UnitDigit+0x30); // afiseaza digit-ul unitatilor pe LCD } //////////////////////////////////////////////////////////////////////LCD/////////////////////////////////////////////////////////////////// #include "Includes.h" void ToggleEpinOfLCD(void) { LCD_E = 1; // ofera un impuls la pinul E al LCD-ului __delay_us(E_Delay); // ptr a initializa LCD si acesta sa poate primi informatii de pe liniile de date LCD_E = 0; __delay_us(E_Delay); } void WriteCommandToLCD(unsigned char Command) { LCD_RS = 0; // primeste comanda LCD_PORT &= 0x0F; // pinii de date sunt pe 0 LCD_PORT |= (Command&0xF0); ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului LCD_PORT &= 0x0F; // pinii de date sunt pe 0 LCD_PORT |= ((Command<<4)&0xF0); ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului } void WriteDataToLCD(char LCDChar) { LCD_RS = 1; // primeste date LCD_PORT &= 0x0F; // pinii de date sunt pe 0 LCD_PORT |= (LCDChar&0xF0); ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului LCD_PORT &= 0x0F; // pinii de date sunt pe 0 LCD_PORT |= ((LCDChar<<4)&0xF0); ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului } void InitLCD(void) { // toti pinii sunt declarati iesiri LCD_E = 0; // E = 0 LCD_RS = 0; // RS = 0 LCD_Data_Bus_D4 = 0; // linia de date = 0 LCD_Data_Bus_D5 = 0; // linia de date = 0 LCD_Data_Bus_D6 = 0; // linia de date = 0 LCD_Data_Bus_D7 = 0; // linia de date = 0 LCD_E_Dir = 0; // declarat ca iesire LCD_RS_Dir = 0; // declarat ca iesire LCD_Data_Bus_Dir_D4 = 0; // declarat ca iesire LCD_Data_Bus_Dir_D5 = 0; // declarat ca iesire LCD_Data_Bus_Dir_D6 = 0; // declarat ca iesire LCD_Data_Bus_Dir_D7 = 0; // declarat ca iesire
  • 22. 22 ///////////////// procedura de reset din datasheet-ulLCD-ului ////////////// __delay_ms(40); LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0 LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului __delay_ms(6); LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0 LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date bus ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului __delay_us(300); LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0 LCD_PORT |= 0x30; // se scrie valoarea 0x3 pe liniile de date ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului __delay_ms(2); LCD_PORT &= 0x0F; // pinii de date sunt trecuti pe 0 LCD_PORT |= 0x20; // se scrie valoarea 0x3 pe liniile de date ToggleEpinOfLCD(); // ofera un impuls la pinul E al LCD-ului __delay_ms(2); ///////////////// finalul procedurii de reset ////////////// WriteCommandToLCD(0x28); WriteCommandToLCD(0x0c); //display on,cursoroff,blink off WriteCommandToLCD(0x01); //clear display WriteCommandToLCD(0x06); //entry mode, set increment } void WriteStringToLCD(const char *s) { while(*s) WriteDataToLCD(*s++); // afiseaza primul caracter pe LCD } void ClearLCDScreen(void) // sterge ecranul si aduce cursorul la pozitia initiala { WriteCommandToLCD(0x01); // sterge ecranul __delay_ms(2); } //////////////////////////////////////////////////////////////////////TST/////////////////////////////////////////////////////////////////// #include "Includes.h" void InitKeypad(void) { Keypad_PORT = 0x00; // seteaza pinii conectati la tastatura pe 0 Keypad_PORT_Dir = 0xF0; // seteaza ultimii 4 pini ca intrari si primii 4 ca iesiri OPTION_REG &= 0x7F; } char READ_SWITCHES(void) //scaneaza fiecare buton { RowA = 0; RowB = 1; RowC = 1; RowD = 1; //testeaza randul A if (C1 == 0) { __delay_ms(250); while (C1==0); return '7'; } if (C2 == 0) { __delay_ms(250); while (C2==0); return '8'; } if (C3 == 0) { __delay_ms(250); while (C3==0); return '9'; } if (C4 == 0) { __delay_ms(250); while (C4==0); return '/'; } RowA = 1; RowB = 0; RowC = 1; RowD = 1; //testeaza randul B if (C1 == 0) { __delay_ms(250); while (C1==0); return '4'; } if (C2 == 0) { __delay_ms(250); while (C2==0); return '5'; } if (C3 == 0) { __delay_ms(250); while (C3==0); return '6'; } if (C4 == 0) { __delay_ms(250); while (C4==0); return 'x'; } RowA = 1; RowB = 1; RowC = 0; RowD = 1; // testeaza randul C
  • 23. 23 if (C1 == 0) { __delay_ms(250); while (C1==0); return '1'; } if (C2 == 0) { __delay_ms(250); while (C2==0); return '2'; } if (C3 == 0) { __delay_ms(250); while (C3==0); return '3'; } if (C4 == 0) { __delay_ms(250); while (C4==0); return '-'; } RowA = 1; RowB = 1; RowC = 1; RowD = 0; // testeaza randul D if (C1 == 0) { __delay_ms(250); while (C1==0); return 'C'; } if (C2 == 0) { __delay_ms(250); while (C2==0); return '0'; } if (C3 == 0) { __delay_ms(250); while (C3==0); return '='; } if (C4 == 0) { __delay_ms(250); while (C4==0); return '+'; } return 'n'; // inseamna ca nu a fost apasat nici un buton } char GetKey(void) // primeste un caracter de la utilizator prin apasarea unui anumit buton { char key = 'n'; // presupune ca nu exista buton apasat while(key=='n') // asteapta pana cand un buton este apasat key = READ_SWITCHES(); // scaneaza reteaua (tastatura)de butoate in continuu return key; //cand un buton este apasat,returneaza valoarea specifica acelui buton } Simularea Cu ajutorul programului Proteus 8 Professional a fost conceputa schema elementara din figura de mai jos prin intermediul careia s-a putut simula functionarea softului fara a fi necesar un circuit fizic.