Calculator științific

Introducere

Proiectul constă în implementarea unui calculator științific care poate realiza diverse operații aritmetice (adunare, scădere, înmulțire, împărțire), care poate afișa rezultatul unor funcții matematice (funcția exponențială și modulo) și care poate calcula rezultatul unor expresii care conțin paranteze.

Scopul proiectului este de a realiza un calculator care poate efectua operații complexe cât mai rapid.

Proiectul este util deoarece cu ajutorul acestuia se pot realiza calcule foarte dificile într-un interval foarte scurt de timp, fiind mult mai eficient, rapid și corect.

Descriere generală

Pentru introducerea operanzilor se va folosi o matrice de butoane (4 x 4), iar operația se va alege utilizând un encoder. Se va prelucra inputul primit și se va afișa pe un ecran LCD rezultatul operației când se va apăsa pe tasta “=”.

În caz de eroare (împărțire la 0, input invalid etc.) se va aprinde un LED.

Schemă bloc

Hardware Design

Listă de piese

Componentele principale sunt:

  • ATMega324
  • Quartz 16MHz
  • LCD 16×2
  • Tastatură
  • LED roșu
  • Potențiometru

Schemă electrică

Software Design

Codul a fost scris in limbajul de programare C, folosind masina virtuala de Linux. Pentru testare si pentru incarcarea codului pe placa am folosit HIDBootFlash.exe pe Windows.

Encoder:

  • poate genera 30 de pulsuri la rotirea a 360 grade
  • folosit pentru a alege operatia in functie de numarul de pulsuri generate
  • se folosesc semnalele DT si CLK pentru a numara pulsurile si pentru stabili in ce directie se roteste encoder-ul
  • cand se apasa butonul SW este aleasa operatia

Operatii posibile:

  1. adunare
  2. scadere
  3. inmultire
  4. impartire
  5. ridicarea la putere
  6. modulo
  7. mutarea cursorului la dreapta
  8. mutarea cursorului la stanga
/* initializare encoder */
void encoder_init(void);

/* citire semnal CLK */
int read_CLK(void);

/* citire semnal DT */
int read_DT(void);

/* verificare apasare buton */
int encoder_switch(void);

/* calculare pozitie actuala a encoder-ului */
int encoder_position(void);

Keyboard:

  • se folosesc 8 pini: 4 pentru linii si 4 pentru coloane
  • pentru a verifica daca un buton este apasat se pune pe rand o linie pe 1 si celelalte linii pe 0, iar apoi se citeste iesirea de pe fiecare coloana
  • se asteapta pana cand butonul nu mai este apasat si se intoarce index-ul butonului apasat
  • 10 butoane reprezinta tastele 0-9
  • 1 buton reprezinta , pentru introducerea numerelor reale
  • 1 buton reprezinta =
  • 2 butoane pentru operatii de stergere (clear si clear all)
  • 2 butoane pentru paranteze: (, )
/* initializare tastatura */
void keyboard_init(void);

/* row devine activ si celelale randuri sunt 0 */
void scan_row(int row);

/* citire coloana */
int read_column(int column);

/* se verifica daca a fost apasat un buton */
int keyboard_read(void);

LCD:

  • am folosit biblioteca din laboratorul 1, modificand doar pinii de date si de control
  • se foloseste pentru a afisa pe prima linie expresia introdusa iar pe a doua linie rezultatul acesteia
  • expresia este calculata doar atunci cand se apasa tasta =
/* initializare LCD */
void LCD_init(void);

/* trimite o instructiune de control catre LCD. */
void LCD_writeInstr(uint8_t instr);

/* asifeaza string-ul msg pe LCD */
void LCD_printAt(uint8_t addr, const char* msg);

LED:

  • este folosit pentru a indica a[aritia unei erori
  • acesta este aprins atunci cand expresia introdusa nu este corecta (parantezelele nu sunt inchise corect, nu sau primit suficienti operanzi sau s-a realizat o operatie invalida cum ar fi impartirea la 0)
  • daca se modifica expresia atunci se inchide led-ul
/* initializare led */
void led_init(void);

/* pornire led */
void led_on(void);

/* oprire led */
void led_off(void);

Stack:

  • pentru a calcula rezultatul expresiei, acesta trebuie trecuta in forma postfixata (operatorii sunt scrisi dupa operanzi)
  • pentru a trece in forma postfixata este nevoie de 2 stive: una pentru operanzi si una pentru operatori
  • stiva este implementata folosind o lista inlantuita
typedef struct node {
	double value;
	struct node *next;
} node;

typedef struct {
	node *head;
} stack;

/* initializare stiva */
int stack_init(stack **s);

/* dezalocare stiva */
void stack_free(stack *s);

/* adauga un element in stiva */
int push(stack *s, double value);

/* elimina un element din stiva */
void pop(stack *s);

/* intoarce elementul din varful stivei */
double top(stack *s);

/* verifica daca stiva e goala */
int stack_is_empty(stack *s);

Evaluate:

  • contine algoritmul de rezolvare a unei expresii
  • se parseaza expresia primita, verificand corectitudinea acesteia si se trece in forma postfixata folosind algoritmul Shunting-yard
/* prioritatea unei operatii */
int get_priority(int op);

/* calculeaza a op b */
int apply_op(double a, double b, int op, double *res);

/* verifica daca un caracter este cifra */
int is_digit(char c);

/* calculeaza o expresie */
int calculate(stack *values, stack *ops);

/* codifica o operatie */
int encode(char c);

/* evalueaza expresia si intoarce rezultatul */
int evaluate(char *string, double *res);

Main:

  • initializeaza encoder-ul, tastatura, led-ul si LCD-ul
  • verifica daca a fost apasat un buton si prelucreaza inputul, afisand pe ecran expresia
  • daca se introduce = apeleaza functia evaluate pentru a obtine rezultatul

Rezultate obținute

Se poate calcula rezultatul mai multor expresii aritmetice care pot avea ca operanzi numere intregi si numere reale si se pot folosi paranteze. Operatiile care pot fi efectuate sunt: adunare, scadere, inmultire, impartire, se poate calcula rezultatul functiilor exponentiala si modulo.

De asemenea, daca se introduce un caracter gresit, acesta poate fi sters sau se poate sterge intreaga expresie si exista posibilitatea de a muta cursorul la stanga sau la dreapta.

Concluzii

Am realizat un calculator aritmetic care poate calcula expresii cat mai complexe si poate verifica daca expresia care trebuie calculata este corecta.

In viitor, se poate extinde adaugand mai multe functii matematice precum: sinus, cosinus, tangenta, logaritm, radical.

Download

Cod sursa: proiect_334cc_visananamaria.zip

Pentru compilare se foloseste comanda make. Se obtin fisierele main.elf si main.hex si se foloseste HIDBootFlash.exe pentru a porni aplicatia.

Bibliografie/Resurse

pm/prj2019/astratulat/1024.txt · Last modified: 2021/04/14 17:07 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0