2011_P2

Calculator de buzunar

Project Description

Proiectul implica emularea calculatorului din windows cu programul Open Watcom si integrarea cu ajutorul placii EV/Z3.

Project Requirements

Proiectul consta in implementarea calculatorului din windows.Acesta presupune crearea unui program  in Open Watcom pentru efectuarea operatiilor:
  • adunare
  • scadere
  • impartire a 2 numere intregi
  • inmultire a 2 numere intregi
  • extragerea radacinii patrate dintr-un numar cu precizie de 2 zecimale.

User Flow

Utilizatorul poate folosi proiectul prin intermediul tastaturii placii EV/Z3.Astfel,
Pasii care trebuie urmati de utilizator sunt:
  1. Utilizatorul introduce primul numar(format din cifre de la 0 la 9)
  2. Utilizatorul alege operatia dorita:
  • Pentru operatia de adunare,se apasa tasta A de pe placuta EV/Z3;
  • Pentru operatia de scadere,se apasa tasta B de pe placuta EV/Z3;
  • Pentru operatia de inmultire,se apasa tasta C de pe placuta EV/Z3;
  • Pentru operatia de impartire,se apasa tasta D de pe placuta EV/Z3;
  • Pentru operatia de radical,se apasa tasta E de pe placuta EV/Z3;
  • Pentru resetare calcul,se apasa tasta O de pe placuta EV/Z3.
3.  Utilizatorul introduce cel de-al doilea numar(format din cifre de la 0 la 9):
Dupa efectuarea pasului 3,utilizatorul are mai multe posibilitati de continuare a calculului:
  • Daca doreste afisarea rezultatului,utilizatorul apasa tasta F de pe placuta EV/Z3;
  • Dar daca utilizatorul,dupa introducerea celor 2 numere si a operatiei dorite,alege sa faca inca o data operatia precedenta,atunci apasa din nou tasta corespunzatoare operatiei si va observa ca rezultatul spre exemplu in cazul adunarii 2+3=5 ,va aduna al doilea operand la rezultat -->8.

Required components

Software Design

In prima etapa a proiectului,am folosit pentru compilarea codului programul Microsoft Visual Studio,iar dupa accea,programul Open Watcom.
Codul programului se bazeaza pe mai multi algoritmi:
  1. Algoritm pentru apasarea pe placuta EV/Z3 a unor caractere si intoarcere acestor caractere in calculator(a codurilor acestora) pentru efectuarea operatiilor dorite.
Astfel,daca se apasa 2 A 4 si utilizatorul apasa tasta F,atunci calculatorul va stii sa faca 2+4 si va returna spre afisare pe placuta rezultatul 6.
unsigned char getch()
{
//citeste codul de la tastatura
int code;
code=kIo.ReadMyKey();
//testam ce cod este
switch(code)
{
case 0x00:
return '0';
case 0x0A:
return '1';
case 0x01:
return '2';
case 0x0B:
return '3';
case 0x02:
return '4';
case 0x0C:
return '5';
case 0x03:
return '6';
case 0x0D:
return '7';
case 0x04:
return '8';
case 0x0E:
return '9';
case 0x05:
return 'A';
case 0x0F:
return 'B';
case 0x06:
return 'C';
case 0x10:
return 'D';
case 0x07:
return 'E';
case 0x08:
return 'O';
case 0x11:
return 'F';
default:
return '\0';
}  
}
//Vectorul de caractere in ordinea crescatoare a codurilor fiecarui caracter in parte
char coduri[19]={0,2,4,6,8,'A','C','E','O','D','F',1,3,5,7,9);
int readkey() //intoarce in monitor codul tastei apasate
{
while (1)
{
int key=kIo.ReadMyKey();
kIo.DisplayBuffer((const unsigned char *)(&key,2);
}
return key;
}
char convert(int key)
{
return coduri[key];
}
2.   Algoritm pentru efectuare modulului dintre 2 numere
int abs(int a,int b)
{
if (a<b)
return b-a;
else
return a-b;
}
3.   Algoritm pentru efectuarea radicalului de ordin 2 dintr-un numar
float radical(int x)
{
float r1,r2;                    // calcul radical din x prin aproximatii
r2=x;                              // aproximatia initiala
do {
r1=r2;                         // r1 este aprox. veche
r2=(r1+x/r1)/2;           // r2 este aprox. mai noua
} while ( abs(r2,r1));   // pana cand r2==r1

return r2;
}
3.  Algoritm pentru convertirea din zecimal in sir de caractere
//x-numarul care trebuie convertit
//z-vectorul de caractere in care vom pune pe x
void conv(int x,char z[10])
{
char y[10];
int n=0;
int i,j;
while (x>1)
{
y[n]=x%10;
x=x/10;
n++;
}
if (x<1)
for (i=1;i<n;i++)
for (j=n;j>0;j--)
z[i]=y[j];
}
4.   Algoritm pentru efectuarea operatiei propriu-zise

int operand_citit=1; //sa stiu al catelea operand il citesc
char semn;              //pastrez semnul operatiei
int a=0,b=0;           //initializarea celor 2 numere
int cod_reset_b=0; //variabila pentru resetarea lui b
while(1)
{
tasta=convert(coduri[key]); //pastrez in variabila "tasta" ce tasta a apasat utilizatorul
kIo.DisplayString(tasta);   //afisez ce tasta am apasat pe ecran

if (tasta>='0' && tasta<='9')         //verific daca citesc o cifra
if (operand_citit == 1)
a=a*10+tasta-'0';                 //daca da,atunci imi formez numarul
else
{
if (cod_reset_b == 1)   //ma ajuta ca atunci cand vreau sa fac ex 2+3 si dak mai apas inca o data +
//atunci imi va aduna inca o data al doilea operand
{
cod_reset_b=0;
b=0;
}
b=b*10+tasta-'0';
//altfel daca am citit primu numar at inseamna k operand citit =2 si citesc pe al doilea
}

tasta=convert(coduri[key]);
//verific ce tasta apas
//daca apas numere de la 0 la 9 le afisez direct
//dar daca apas A B ..,atunci afisez semnul corespunzator fiecarui caracter
if (tasta =='A')
kIo.DisplayString("+");
else
if (tasta == 'B')
kIo.DisplayString("-");
else
if (tasta == 'C')
kIo.DisplayString("*");
else
if (tasta == 'D')
kIo.DisplayString("/");
else
if (tasta == 'E')
kIo.DisplayString("r");
else if (tasta == 'F')
kIo.DisplayString("=");
else
if (tasta =='L')
kIo.DisplayString(".");
else
{char g[10];   //in vectorul g pun sirul de caractere rezultat din functia conv(a,g)
conv(a,g);
kIo.DisplayString(g);
}
if ((tasta == 'A')||(tasta == 'B')||(tasta == 'C')||(tasta == 'D')||(tasta == 'F'))
if (operand_citit ==1)    //inseamna ca am citit primul numar
{                                  //urmatoarea tasta va fi operatia dorita
semn=tasta;           //pastrez operatia
operand_citit=2;      //il fac 2 pentru a putea introduce cel de-al doilea numar
}
else
{                           //altfel,inseamna k am citit toti operanzii si pot sa fac operatia
switch (semn)

case 'A':    // A pentru adunare
a=a+b;
break;

case 'B':   //B pentru scadere
a=a-b;
break;

case 'C':   //C pentru inmultire
a=a*b;
break;

case 'D':  //D pentru impartire
a=a/b;
break;
}
cod_reset_b=1;                // operand_citit ramane al doilea
kIo.DisplayString("="); //afisez rezultatul
char z[10];
conv(a,z);
kIo.DisplayString(z);    //afisez rezultatul
}

if (tasta == 'E')            //se doreste extragerea radicalului dintr-un numar
{
if (operand_citit == 1 )     //se verifica daca a fost introdus doar primul numar al operatiei
{                                 //daca da,se face radical din el
float x=0;
x=radical(a);      
char f[10];
conv(x,f);   
kIo.DisplayString(f);}
else
if (operand_citit == 2)     //daca s-a introdus si al doilea numar,se face radical din el
{y=radical(b);
char h[10];
conv(y,h);
kIo.DisplayString(h);
} //atunci se face radical doar din el
operand_citit=1;
cod_reset_b=1;
}
if (tasta=='O')           //daca tasta este   O,atunci resetam calculul
{
a=0;
b=0;
operand_citit=1;
}

Results

O imagine de ansamblu a cum functioneaza proiectul, screenshoturi, filmulete cu proiectul functionand. Alte detalii care le credeti importante.

Download

Arhiva cu schema hardware + cod microcontroller + tot proiectul OpenWatcom.
Arhiva va contine 2 directoare (1 singur pentru proiecte doar software)
Hardware design - schema uC + codul folosit pentru a genera fisierul .HEX
Software design - template-ul Open Watcom folosit

Status

  • Saptamana 25 aprilie-1 mai -->realizarea codului programului in Microsoft Visual  Studio
  • Saptamana 2 mai - 8 mai -->implementarea codului in OpenWatcom
  • Saptamana 9 mai-15 mai -->gasirea eventualelor posibilitati de optimizare a programului si realizarea completa a paginii de utilizarea a programului