Obiective:
- Definirea unei librării;
- Separarea resurselor în globale și locale;
- Reutilizarea librăriilor.
Problema:
Să se proiecteze un sistem care ar permite ca caracterele culese de la o tastatură să se afișeze la un display 8x7seg. Pentru realizarea problemei se vor dezvolta librării/drivere de lucru cu fiecare dispozitiv(tastatura și display). Adițional se vor realiza resurse care vor reacționa la anumite taste cu funcții speciale: ‘*’ - Backspace, ‘#’ - Clrear.
- Separarea resurselor în globale și locale;
- Reutilizarea librăriilor.
Problema:
Să se proiecteze un sistem care ar permite ca caracterele culese de la o tastatură să se afișeze la un display 8x7seg. Pentru realizarea problemei se vor dezvolta librării/drivere de lucru cu fiecare dispozitiv(tastatura și display). Adițional se vor realiza resurse care vor reacționa la anumite taste cu funcții speciale: ‘*’ - Backspace, ‘#’ - Clrear.
Consideraţii teoretice:
Un program C++ este alcatuit din
una sau mai multe functii, din care una este radacina sau functie principala -
adica nu poate lipsi si executia incepe automat cu ea. Aceasta se numeste main. Functiile aplelate pot fi functii
predefinite descrise in fisiere header predefinite sau pot fi functii definite
de catre programator. Acestea din urma pot fi definite in fisierul sursa care
contine programul principal sau in alt fisier pe care il vom numi header utilizator si cu care se creeaza legatura in
perioada de linkeditare prin directiva preprocessor # include.
In cazul in care programatorul isi poate
creeaza propriile fisiere header numele fisierului va fi inclus intre ghilimele
( " " ) . Fisierul va fi continut de directorul setat ca fiind
director de lucru.
De exemplu:
#include "Keyboard.h" , unde Keyboard.h este
un fisier header definit de programator.
Compilatorul C
alocă memorie variabilelor din program de dimensiune corespunzătoare tipului
fiecăreia. Memoria se alocă în 2 moduri:
-static, repartizată într-o zonă specială
asociată programului;
-dinamic, repartizată într-o zonă specială
numită stivă (se comportă ca o listă LIFO).
În funcţie de
modul cum se alocă memorie, vom distinge mai multe clase de variabile.
O primă clasă de
variabile este aceea a variabilelor globale cărora li se alocă memorie pe
toatădurata execuţiei programului şi ele pot fi utilizate în orice funcţie a
programului. Altă clasă devariabile este clasa variabilelor locale, aceste
variabile au o utilizare locală la nivelul unei funcţii.
Definiţia
unei variabile globale coincide
sintactic cu o declaraţie obişnuită, dar care este scrisă înafara oricărei
funcţii a programului (fişierului sursă). Implicit, definiţia unei variabile
globaledetermină ca variabila respectivă să fie definită începând din punctul
scrierii ei şi până lasfârşitul fişierului sursă respectiv. De aceea se
recomandă ca definiţiile variabilelor globale să fiescrise la începutul
fişierului sursă, pentru a fi accesate în orice funcţie a fişierului.
Pentru
a utiliza variabilele globale şi în alte funcţii situate în alte fişiere sursă
decât în cel în caresunt definite, ele trebuie declarate ca externe în
funcţiile respective
Variabilele locale nu sunt valabile în tot
programul. Ele au o utilizare locală în două feluri:
-ca şi variabile automatice (alocate pe stivă)
la nivelul unei funcţii;
-ca şi variabile statice (alocate în zona
programului) la nivel de fişier (eventual şi la nivelul uneifuncţii).
Variabilele
declarate în interiorul unei funcţii şi care nu sunt declarate ca externe sunt
variabile locale. Lor li se alocă memorie pe stivă la intrarea în funcţia în
care sunt declarate. La ieşirea dinfuncţie, stiva se reface la conţinutul
dinaintea apelului şi variabilele locale pierd alocarea. Deciori de câte ori se
apelează o funcţie, variabilele locale acesteia (denumite şi variabile
automatice) se alocă (primesc memorie) pe stivă şi la ieşirea din funcţie
variabilele locale sunt şterse din stivă.
Mersul lucrării:
Listingul
programului:
/*####################
# main.c #
####################*/
#include
<avr\io.h>
#include
<avr/interrupt.h>
#include
"Display7x8.h"
#include
"KeyBoard.h"
void
main(void){
GICR=(1<<INT0);
//MCUCR=(1<<ISC01); //| 0 | 0 | pe nivel jos la pinul INT0 0-logic
TIMSK
= (1 << TOIE0);
TCCR0
= (1 << CS01); //CK/8
KeyBoard_Init();
Display_Init();
sei();
while(1){}
}
//***************************************
ISR(INT0_vect){
char
ch;
ch=KeyGetChar();
if
(ch){
if
(ch=='*') Display_Clear();
else
if (ch=='#') Display_BackSpace();
else
Keyboard_Push(ch);
}
}
//***************************************
ISR(TIMER0_OVF_vect)
{
Display_Driver();
}
|
/*####################
# Display7x8.c #
####################*/
#include
<avr/io.h>
#include
"Display7x8.h"
volatile char k=0;
void Display_Init(){
DISPLAY_DATA_DDR=0xFF;
DISPLAY_DATA_PORT=0x00;
DISPLAY_DIGIT_DDR=0xFF;
DISPLAY_DIGIT_PORT=0xFF;
display_cursor_pos=0;
vect_pos=0;
}
//*********************************************************
char
Keyboard_Push(char c){
if (vect_pos<8){
MEM[vect_pos]=c;
vect_pos++;
}
}
//********************************************************
void Clipire(){
k++;
DISPLAY_DATA_PORT=0x00;
DISPLAY_DIGIT_PORT=~(1<<vect_pos);
if (k<40) DISPLAY_DATA_PORT=0x10;
else if
(k>40) DISPLAY_DATA_PORT=0x00;
else if (k>100)
k=0;
}
//******************************************************
char CharTo7Seg(char
c){
switch (c){
case '1' :
{c=0x60; break;} //1
case '2' :
{c=0xDA; break;} //2
case '3' :
{c=0xF2; break;} //3
case '4' :
{c=0x66; break;} //4
case '5' :
{c=0xB6; break;} //5
case '6' :
{c=0xBE; break;} //6
case '7' :
{c=0xE0; break;} //7
case '8' :
{c=0xFE; break;} //8
case '9' :
{c=0xF6; break;} //9
case '0' :
{c=0xFC; break;} //0
case 'A' :
{c=0xEE; break;} //A
case 'b' :
{c=0x3E; break;} //B
case 'C' :
{c=0x9C; break;} //C
case 'd' :
{c=0x7A; break;} //D
default :c=0xFF;
}
return c;
}
//*******************************************************
void
Display_Driver(){
Clipire();
if
(display_cursor_pos < vect_pos){
DISPLAY_DATA_PORT=0x00;
DISPLAY_DIGIT_PORT=~(1<<display_cursor_pos);
DISPLAY_DATA_PORT=CharTo7Seg(MEM[display_cursor_pos]);
display_cursor_pos++; }
else if
(display_cursor_pos >= vect_pos) display_cursor_pos=0;
}
//********************************************************
void
Display_Clear(){
char i;
for (i=0; i <=
vect_pos; i++)
MEM[i]='0';
display_cursor_pos=vect_pos=0;
DISPLAY_DATA_PORT=0x00;
DISPLAY_DIGIT_PORT=0xFF;
}
//********************************************************
void
Display_BackSpace(){
if (vect_pos>0) {
MEM[vect_pos-1]='0';
vect_pos--;
}
else if
(vect_pos<1) MEM[vect_pos]='0';
}
|
/*####################
# KeyBoard.c #
####################*/
#include
<avr\io.h>
#include
"KeyBoard.h"
//**********************************************************************
// Initializarea
Tastaturi
void
KeyBoard_Init(){
KEYBOARD_DDR= 0x0F;
KEYBOARD_PORT=0xF0;
DDRD= 0b00000000;
PORTD=0b11111111;
}
//**********************************************************************
// Extragera codul
tastei
unsigned char
KeyGetKey(){
char rind,col;
unsigned char key;
KEYBOARD_DDR=0x0F;
KEYBOARD_PORT=0xF0;
rind=PINC;
KEYBOARD_DDR=0xF0;
KEYBOARD_PORT=0x0F;
col=PINC;
key=rind|col;
KEYBOARD_DDR=0x0F;
KEYBOARD_PORT=0xF0;
return key;
}
//**********************************************************************
// transformarea
codul tastei intrun char, p/u a inscri in vector
unsigned char
KeyToChar( unsigned char c){
char k;
switch (c){
case 0xee:
{k='1'; break; } //1
case 0xed:
{k='2'; break; } //2
case 0xeb:
{k='3'; break; } //3
case 0xe7:
{k='4'; break; } //4
case 0xde:
{k='5'; break; } //5
case 0xdd:
{k='6'; break; } //6
case 0xdb: {k='7'; break; } //7
case 0xd7:
{k='8'; break; } //8
case 0xbe:
{k='9'; break; } //9
case 0xbd:
{k='0'; break; } //0
case 0xbb:
{k='A'; break; } //A
case 0xb7:
{k='b'; break; } //B
case 0x7e:
{k='C'; break; } //C
case 0x7d:
{k='d'; break; } //D
case 0x7b:
{k='*'; break; } //
* - clear
case 0x77:
{k='#'; break; } //
# - BackSpace
default :k='-';
}
return k;
}
//*********************************************************************
char KeyGetChar(){
unsigned char c;
unsigned char ch;
c=KeyGetKey();
ch=KeyToChar(c);
return ch;
}
//**********************************************************************
|
#ifndef Display
#define Display
/*###########################################
# File Name: Display7x8.h #
# Created: #
# Modificat #
# Author:
XXXXXXX #
# Description: "Driver" pentru afisor 7seg #
# 8
digit, #
#############################################*/
#include
<avr/io.h>
#ifndef
DISPLAY_DATA_PORT
#define
DISPLAY_DATA_PORT PORTB
#endif
#ifndef
DISPLAY_DATA_DDR
#define
DISPLAY_DATA_DDR DDRB
#endif
#ifndef
DISPLAY_DIGIT_DDR
#define
DISPLAY_DIGIT_DDR DDRA
#endif
#ifndef
DISPLAY_DIGIT_PORT
#define
DISPLAY_DIGIT_PORT PORTA
#endif
// Definirea
dimensiunile afisorului Nr de segmente( p/u vector)
#ifndef DISPLAY_SIZE
#define DISPLAY_SIZE
8
#endif
// Vector &
Declararea variabelor
char display_cursor_pos;
char vect_pos;
char
MEM[DISPLAY_SIZE];
void
Display_Driver();
void Display_Init();
char
Keyboard_Push(char);
void
Display_Clear();
void
Display_BackSpace();
#endif
|
#ifndef KeyBoard
#define KeyBoard
/*############################################
# File Name: KeyBoard.h #
# Created: #
# Modified: #
# Author: XXXXXXX #
# Description: "KeyBoard 4x4" #
#############################################*/
#include
<avr/io.h>
#ifndef KEYBOARD_DDR
#define KEYBOARD_DDR
DDRC
#endif
#ifndef
KEYBOARD_PORT
#define
KEYBOARD_PORT PORTC
#endif
void
KeyBoard_Init();
char
KeyGetChar(void);
#endif
|
Download |