Organizarea librăriilor оn aplicații cu MCU

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.
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.

VARIABILE




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