Calculator stiintific

Calculator portabil cu operatii aritmetice si functii avansate (stiintifice).

Introducere

Am creat un calculator care poate efectua operatii aritmetice (+, -, *, /, ridicare la putere) si functii avansate (radical, logaritm natural, exponentiala, trigonometrice si trigonometrice inverse).
De mult timp mi-am dorit sa construiesc un calculator portabil.
Ca proiect la PM, aveam mai multe variante, dar pana la urma mi-am amintit si m-am hotarat sa concep acest calculator.

Cu ce este mai bun aacest calculator fata de alte calculatore portabile?
* Posibilitatea de a calcula expresii mai complexe odata, fata de alte calculatoare, care efectueaza doar expresii binare sau functii.
* Afisarea de mesaje de eroare in caz de operatii invalide (impartire la 0) sau erori de sintaxa.

Descriere generala

Schema bloc:

Configuratie taste:

Hardware

Calculatorul este compus din:
* O placa de baza, care contine:

  1. Microcontroller ATMEL ATMEGA16
  2. alimentator de la USB
  3. programator serial
  4. programator prin ISP

Deoarece placa de baza este realizata prin cablaj imprimat, a mai fost nevoie de: * O placa de test, care contine:

  1. 2 Tastaturi 4×4
  2. 1 LCD DEM16101, cu 2×11 campuri
  3. 1 panglica cu 6 fire, pentru instructiuni si alimentare LCD
  4. 3 panglici cu cate 8 fire, pentru date LCD, input tastatatura1, respectiv input tastatura2
  5. 30 barete-tata
  6. Pentru fiecare panglica am folosit conectori-mama, iar unele sunt legate si direct la pini, in cazul LCD-ului
  7. Toate panglicile leaga placa de baza de cea de test

Schema placa de baza

Schema placa de test
Numele LCD-ului este orientativ (al meu nu este TUXGR_16X2_R2, ci DEM16101, insa nu am gasit DEM16101 in lista de componente suportate de Eagle :( )
Patratele verzi reprezeinta tastaturi (cu cate 16 taste).
Acolo unde mai multe fire par unite, nu am avut loc sa pun mai multe.

Software

Am folosit 4 fisiere: * In utils.h, am macrodefinitii pentru codurile tastelor si semnificatia lor.

* In lcd.h, sunt definiti bitii cei mai importanti ai uC-ului, care dau output-ul pentru LCD.

* In lcd.c, sunt definite functiile de lucru cu LCD-ul:

void LCD_clear(); // reseteaza LCD-ul 
 
void LCD_init(); // initializare LCD, setare mod (2 linii x 11 caractere, cursor, display shift)
 
int char_to_LCD_data(char c); // converteste un caracter in octet a.i. sa poata fi scris pe ecranul LCD-ului
 
void LCD_write_char(char c); // scrie un caracter pe LCD
 
void LCD_write_string(char *s); // scrie (append) un text pe LCD
 
void LCD_output(double value, double l10p); /* scrie valoarea lui value pe LCD; 
  l10p: puterea lui 10 corespunzatoare cifrei cele mai nesemnificative*/
 
void LCD_error(char *s); // scrie un mesaj de eroare pe LCD, dupa de l-a resetat
 
void LCD_on(); // aprinde LCD-ul
 
void LCD_off(); // stinge LCD-ul


* In main.c, sunt definite functiile de input de la tastatura, scriere expresii pe LCD si evaluare expresii:

int check(char expr[256], int start, int end); // verifica corectitudinea expresiei, de la start la end, si intoarce 0 sau 1
 
int eval(char expr[256], int start, int end, double *result); /* evalueaza expresia, de la start la end, 
  pune rezultatul in *result si intoarce 0 in caz de succes si >0 in caz de exceptie (impartire la 0, etc)*/
 
void clear(); // reinitializeaza registrul expr si current_value, reseteaza LCD-ul si scrie 0 pe el
 
char key_to_char(int key); // converteste codul tastei apasate la caracterul respectiv (exceptie tastele cu functii)
 
char* key_to_string(int key); // converteste codul tastei apasate la un string (pentru tastele cu functii)
 
void process_key(int key); /* proceseaza inputul de la tastaturi, in functie de codul tastei citite 
  -> scriere caracter sau evaluare si scriere expresie*/
 
int get_key_id(); /* intoarce codul tastei apasate (testeaza bitii de pe PORTA, PORTD, conectati la pinii tastaturilor;
  verifica linia si coloana tastei apasate)*/
 
int main(){
        int key;
 
	LCD_on();
 
	// initializare tastatura 1 (aritmetica)
	DDRA = 0x00;	// setare PA ca input
	PORTA = 0x00; 		
 
	// initializare tastatura 2 (scientific)
	DDRC = 0x00;	// setare PC ca input
	PORTC = 0x00;
 
	// init LCD (instructiuni)
	DDRB |= 0x0F;	// setare PB(4:1) ca output LCD(3:6)
	PORTB = 0x00;
	PORTB |= 1 << PB4;
 
	// init LCD (date)
	DDRD |= 0x8F;	// setare PD(7:1) ca output LCD(8:14)
	PORTD = 0x00;	
 
	LCD_init(); // date de init LCD
 
	// bucla principala
	while (1){
		_delay_ms(INTR_TIME);
		key = get_key_id(); // primim id tasta apasata (1-32)
		if (key > 0){
			process_key(key); // procesam caracterul
		}
	}
 
	return 0;
}

Rezultate obtinute

Calculatorul este partial functional (apar caractere pe LCD, cand se apasa taste), insa cu conditia ca mufa USB de pe placuta de baza sa fie functionala. Din pacate, a mea s-a defectat (cand conectez cablul USB pentru alimentare, placa nu primeste tensiune :( ).

Concluzii

Din cauza ca am folosit 2 placute (una de test si una cablata), am avut probleme la legarea lor cu fire (intre placa si LCD, tastaturi). Am rezolvat aceasta problema prin folosirea de panglici si conectori-mama.
Am avut si un defect pe placuta cablata (discontinuitati), pe care le-am rezolvat punand fire.

Download

Arhiva zip cu codul sursa, Makefile, executabil, scheme, bootloader

După ce se descarcă şi se despachetează arhiva zip, pentru compilare se foloseşte comanda make în consolă. Pentru programarea plăcuţei, se introduce cablul USB în plăcuţă, şi se dă comanda avrusbboot main.hex in termen de 30 de secunde.

După programare, se scoate cablul USB, se introduce adaptorul şi se aşteaptă cele 30 de secunde până când bootloaderul predă execuţia programului nostru. În acest moment, cifra 0 ar trebui să apară pe ecranul LCD.

Schema pentru simulare (cu ISIS)

Resurse

pm/prj2011/rtataroiu/calculator_stiintific.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