Advertisement
milanmetal

[RSDMK] Tastatura 2. Kalkulator

Apr 29th, 2018
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.95 KB | None | 0 0
  1. #include <c8051f340.h>        
  2. #include "time.h"
  3. #include "uart.h"
  4.  
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. void OSCILLATOR_Init (void);          
  9. void PORT_Init (void);
  10.  
  11. // znojimo preprocesor
  12. #define cekaj_prijem()          while(!UART0_Available())          
  13. #define primljen_karakter()     UART0_Available() > 0
  14.  
  15. #define UNOS_MAX 8
  16.  
  17. char    Keypad_Scan();
  18. void    pocupajOperande(char *unos, char operandi[2][UNOS_MAX], char *operator);
  19. char*   intToStr(int num, char *digits);
  20. int     racunaj();
  21.  
  22. char xdata  unos[UNOS_MAX];
  23. char        unosBrojac = 0;
  24. char        operator = 0;
  25. bit         gotovUnos = 0;
  26. char        operandi[2][UNOS_MAX];
  27. char        rezultat[UNOS_MAX];
  28. bit         ispisano = 0;
  29.  
  30. char        taster;
  31. char        taster_prev;  
  32.  
  33. void main(void)
  34. {
  35.     int i = 0;
  36.  
  37.     PCA0MD &= ~0x40;    // Watchdog tajmer iskljucen
  38.  
  39.     OSCILLATOR_Init();  // Inicijalizacija oscilatora (Fosc = 22.1184 MHz)
  40.     TIME_Init();        // Inicijalizacija sistemskog vremena (koristi se prekid tajmera 2)
  41.     PORT_Init();        // Inicijalizacija portova
  42.     UART0_Init();       // startuje UART0
  43.  
  44.     while(1) {
  45.         taster_prev = taster;
  46.         taster = Keypad_Scan();
  47.  
  48.         if(taster && (!taster_prev)) {
  49.             if(taster == '#') {
  50.                 // iza poslednjeg unesenog karaktera stavi terminacioni
  51.                 unos[unosBrojac] = '\0';
  52.                 gotovUnos = 1;
  53.                 unosBrojac = 0;
  54.                 ispisano = 0;           // dozvoli ponovo ispis dole   
  55.             } else {
  56.                 if(unosBrojac < UNOS_MAX){
  57.                     unos[unosBrojac++] = taster;
  58.                     UART0_PutChar(taster);
  59.                 }
  60.             }
  61.         }
  62.  
  63.         if(!ispisano && gotovUnos) {
  64.             UART0_PutString("\nUnijeli ste: ");
  65.             UART0_PutString(unos);
  66.            
  67.             pocupajOperande(unos, operandi, &operator);
  68.  
  69.             UART0_PutString("\n\nPrvi operand:  ");
  70.             UART0_PutString(operandi[0]);
  71.  
  72.             UART0_PutString("\nOperator:    ");
  73.             UART0_PutChar(operator);
  74.  
  75.             UART0_PutString("\nDrugi operand:   ");
  76.             UART0_PutString(operandi[1]);
  77.             // ------------------------------------------
  78.  
  79.             // ispis oblika kakav su trazili
  80.             UART0_PutString("\n");
  81.             UART0_PutString(operandi[0]);
  82.             UART0_PutChar(operator);
  83.             UART0_PutString(operandi[1]);
  84.             UART0_PutChar('=');
  85.  
  86.             UART0_PutString(intToStr(racunaj(), rezultat));
  87.  
  88.             UART0_PutString("\n\n");
  89.  
  90.             ispisano = 1;
  91.             gotovUnos = 0; 
  92.         }
  93.     }                    
  94.  }
  95.  
  96. /*
  97.  * Okej, nije moralo ovako, ali sto da ne.
  98.  *
  99.  * Unos je oblika 123A234 , operatori su A, B, C, D
  100.  *
  101.  * JU! STA ZVEZDICA! Prosto sija...
  102.  **/
  103. void pocupajOperande(char *unos, char operandi[2][UNOS_MAX], char *operator) {
  104.     // brojac koji prolazi kroz cijeli unos
  105.     char i = 0;     // broji karaktere u prvom operandu I UKUPAN BROJ NJIH
  106.     char j = 0;     // broji karaktere u drugom operandu
  107.     while(
  108.         *(unos+i) != 'A' &&
  109.         *(unos+i) != 'B' &&
  110.         *(unos+i) != 'C' &&
  111.         *(unos+i) != 'D' &&
  112.         *(unos+i) != '*' &&
  113.         *(unos+i) != '#'
  114.     ) {
  115.         //UART0_PutString("\nOperator1");
  116.         *(*(operandi+0)+i) = *(unos+i);
  117.         i++;
  118.     }
  119.  
  120.     *(*(operandi+0)+i) = '\0';  // kraj stringa prvog operanda
  121.     *operator = *(unos+i);      // Kada while zavrsi, to znaci da je naisao na operator
  122.  
  123.     // Pretpostavljam ispravan unos, jedan operand. Ovo ga preskace.
  124.     i++;
  125.  
  126.     while(
  127.         *(unos+i) != 'A' &&
  128.         *(unos+i) != 'B' &&
  129.         *(unos+i) != 'C' &&
  130.         *(unos+i) != 'D' &&
  131.         *(unos+i) != '*' &&
  132.         *(unos+i) != '#' &&
  133.         *(unos+i) != '\0'       // Sada provjeravas da li je dosao do kraja
  134.     ) {
  135.         //UART0_PutString("\nOperator2");
  136.         *(*(operandi+1)+j) = *(unos+i);
  137.         i++;
  138.         j++;
  139.     }
  140.    
  141.     *(*(operandi+1)+j) = '\0';  // kraj stringa drugog operanda
  142.  
  143.     // nije najkulturnije da se ovo radi ode pa posle opet nesto slicno
  144.     // ali sluzi svrsi
  145.     switch(*operator) {
  146.         case 'A': *operator = '+'; break;
  147.         case 'B': *operator = '-'; break;
  148.         case 'C': *operator = '*'; break;
  149.         case 'D': *operator = '/'; break;
  150.     }
  151.    
  152. }
  153.  
  154. /*
  155.  * Posto su svi objekti globalni, ne moram da radim sa pokazivacima
  156.  * nije moralo ni u prethodnoj funkciji.
  157.  */
  158. int racunaj() {
  159.     switch(operator) {
  160.         case '+': return atoi(operandi[0]) + atoi(operandi[1]);
  161.         case '-': return atoi(operandi[0]) - atoi(operandi[1]);
  162.         case '*': return atoi(operandi[0]) * atoi(operandi[1]);
  163.         case '/': return atoi(operandi[0]) / atoi(operandi[1]);
  164.     }
  165. }
  166.  
  167. /*
  168.  * Integer proizvoljne duzine prebacuje u string.
  169.  * Nije trazeno u zadatku, ali sto da ne.
  170.  * Sto da ne? Sto da ne kolega...
  171.  */
  172. char* intToStr(int num, char *digits) {
  173.     // broj cifara
  174.     char digitCnt   = 0;
  175.     // pomocna cifra
  176.     char digitTmp;
  177.  
  178.     char i = 0;
  179.  
  180.     while(num) {
  181.         // +'0' prisiljava konverziju integera u char,
  182.         // kastovanje iz nekog razloga ne radi.
  183.         digitTmp = (num % 10)+'0';
  184.         num = num / 10;
  185.  
  186.         *(digits+digitCnt) = digitTmp;
  187.         digitCnt++;
  188.     }
  189.  
  190.     // u ovom trenutku imamo sve cifre, ali naopako poslagane. Obrcem.
  191.     for(i = 0; i < digitCnt / 2; i++) {
  192.                                                     // komentari za prvi prolaz petlje:
  193.         digitTmp = *(digits+i);                     // uzmem prvu cifru niza
  194.         /*
  195.          * -1 postoji da se odmaknem korak nazad
  196.          * od terminacionog karaktera
  197.          */
  198.         *(digits+i) = *(digits+digitCnt-1-i);       // na prvu stavim poslednju
  199.         *(digits+digitCnt-1-i) = digitTmp;          // na poslednju stavim prvu
  200.                                                     // i proces se ponavlja sa 2. i n-1, sa 3. i n-2 cifrom itd.
  201.     }
  202.     // pravim string, dodajem terminacioni karakter na kraj.
  203.     *(digits+digitCnt) = '\0';
  204.     return digits;
  205. }
  206.  
  207.  
  208. void PORT_Init (void)
  209. {
  210.    P2MDIN |= 0x0F;              // 4 najniza bita porta P2 -> digitalni
  211.    P2MDOUT = 0x0C;              // Pinovi za LED -> push-pull izlazi
  212.  
  213.                                 // Crossbar inicijalizacija
  214.    XBR1    = 0x40;              // Dozvola crossbar-a i slabih pull-up otpornika
  215. }
  216.  
  217.  
  218. char Keypad_Scan()
  219. {
  220.  unsigned char col;
  221.  XBR1 = 0x40; //dozvola crossbar-a i pull-up otpornika
  222.  P1MDOUT = 0x00; //svi pinovi su open-drain
  223.  for(col = 0x01; col != 0x10; col <<= 1)
  224.  {
  225.      P1MDIN = col | 0xf0; //nule u masci su HiZ pinovi
  226.      P1 = ~col; //adresiranje kolone
  227.      delay_ms(2);
  228.      //visi nibl predstavlja kolonu, a nizi stanja tastera:
  229.      switch((col << 4) | ((~P1) >> 4))
  230.      {
  231.          //prva kolona:
  232.          case 0x11:
  233.             return '1';
  234.          case 0x12:
  235.             return '2';
  236.          case 0x14:
  237.             return '3';
  238.          case 0x18:
  239.             return 'A';
  240.        
  241.          //druga kolona:
  242.          case 0x21:
  243.          return '4';
  244.          case 0x22:
  245.             return '5';
  246.          case 0x24:
  247.             return '6';
  248.          case 0x28:
  249.             return 'B';
  250.          //treca kolona:
  251.          case 0x41:
  252.             return '7';
  253.          case 0x42:
  254.             return '8';
  255.          case 0x44:
  256.             return '9';
  257.          case 0x48:
  258.             return 'C';
  259.          //cetvrta kolona:
  260.          case 0x81:
  261.             return '*';
  262.          case 0x82:
  263.             return '0';
  264.          case 0x84:
  265.             return '#';
  266.          case 0x88:
  267.             return 'D';
  268.      }
  269.  }
  270.  return 0; //nije detektovan nijedan taster
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement