Calculator portabil cu operatii aritmetice si functii avansate (stiintifice).
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.
Calculatorul este compus din:
* O placa de baza, care contine:
Deoarece placa de baza este realizata prin cablaj imprimat, a mai fost nevoie de: * O placa de test, care contine:
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.
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; }
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 :( ).
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.
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.
Placa de baza
Tutorial realizare placuta
Datasheet ATMEGA16
Placa de test
Datasheet LCD DEM16101
Tutorial conectare tastatura la un microcontroller
Software
Mod utilizare bootloader