Ljubuncic Orhan Hasanic Nadin

Dependencies:   mbed

main.cpp

Committer:
tim004
Date:
2014-06-08
Revision:
0:3c6d7d94ba99

File content as of revision 0:3c6d7d94ba99:

#include "mbed.h"
#include "math.h"

// PAI - projekat - kalkulator

BusInOut segmenti( dp2,dp1,dp28, dp6,dp5,dp27,dp26); // 7 segmenata

int brojevi[10]={0x01,0x4f,0x12,0x06,0x4c,0x24,0x20,0x0f,0x0,0x04};
int znakovi[6] = {0x02, 0x60, 0x72, 0x42, 0x62, 0x48}; 


DigitalOut red[4] = {dp16, dp15, dp17, dp18};
DigitalIn kolona[4]  = {dp9, dp10, dp11, dp13};




Timer db, db1;
Ticker osvjezi, tasteri;

char vratiZnak();

class Kalkulator
{
    float operand1, operand2, memorija;
    char operacija;
    bool second_fun, third_fun, poceo2;
    int decimala;
    bool minus, error, binary, mem;
    int faza;
public:
    Kalkulator() {pocetnoStanje();}
    float getOperand1() const {return operand1;}
    float getOperand2() const {return operand2;}
    int dajFazu() const {return faza;}
    bool jePoceo2() const {return poceo2;}
    bool jeGreska() const {return error;}
    void pocetnoStanje();
    void secondFun() {second_fun = !second_fun;}
    void thirdFun() {third_fun = !third_fun;}
    void izvrsiOperaciju(char button);
    void promjenaStanja() {izvrsiOperaciju(vratiZnak());   }
    bool jeCifra(char c) {return c >= '0' && c <= '9';}
    void azurirajOperand(int cifra);
    void primijeniOperaciju(char op);
    void izracunaj();
    void postaviZarez(); 
    void binToDec();
    void decToBin();
    void toMr();                
    void fromMr();
    void clear();
    void sinus();
    void korijen();
    void reciproc();
    void logaritam10();       

};


Kalkulator k;


 
BusOut mjesta(dp23, dp24,dp25 ); // 3 cifre
 
DigitalOut dp(dp4); // dec point
 
void prikaziBroj(int n)
{
    segmenti = brojevi[n];
}
 

void prikaziMinus()
{
    segmenti = 0x7E;

}


void prikaziOverflow()
{

    Timer o;
    o.start();
    while(o.read() < 2)
    {
        dp = 1;
        mjesta = 6;
        segmenti = 0x62;
        wait(0.001);
        mjesta = 5;
        segmenti = 0x63;
        wait(0.001);
        mjesta = 3;
        segmenti = 0x38;
        wait(0.001);
    }
    
    k.clear();

}


void prikaziError()
{
    Timer e;
    e.start();
    while(e.read() < 2)
    {
        dp = 1;
        mjesta = 6;
        segmenti = 0x30;
        wait(0.001);
        mjesta = 5;
        segmenti = 0x7A;
        wait(0.001);
        mjesta = 3;
        wait(0.001);
    }
    
        k.clear();
}


void ispisDisplay()
{
    
   /* if(k.jeGreska())
    {
        prikaziError();
        return;
        
    } */
    
    float ispis;
    int prva, druga, treca;
    if(k.dajFazu()==0 || (k.dajFazu()==1 && !k.jePoceo2()) || k.dajFazu()==2) ispis = k.getOperand1();
    else ispis = k.getOperand2();
    
    ispis = ispis * 100;
    ispis = int(ispis);
    ispis = ispis / 100.;
    
    
    // test overflowa
    /*
    if(int(ispis) == ispis)
    {
        if(ispis > 999 || ispis < -99) prikaziOverflow();
        return;
    
    }
    else
    {
        if(ispis > 100.0 || ispis < -10.0) prikaziOverflow();
        return;
    
    }
    
   if(k.jeGreska()) prikaziError();
    
    */
    int mjestoZareza(0), mjestoMinusa(0);
    
    segmenti.output();
    
    if(int(ispis) == ispis)
    {
        if(ispis < 0) 
        {
            if(ispis <= -1 && ispis >= -9) mjestoMinusa = 2;
            else if(ispis <= -10 && ispis >= -99) mjestoMinusa = 1;
            ispis = abs(ispis);
        
        }
        
        
    
    }
    else
    {
        if(ispis > 0.)
        {
            if(ispis < 10.0)
            {
                ispis = ispis * 100;
                mjestoZareza = 1;
                if(int(ispis)%10 == 0)
                {
                    ispis = ispis / 10;
                    mjestoZareza = 2;
                    
                }
                
            }
            else
            {
                mjestoZareza = 2;
                ispis = ispis * 10;
            
            }
        
        }
        else
        {
            mjestoZareza = 2;
            ispis = ispis * 10;
            ispis = fabs(ispis);
        }
    
    }
    
    
    
    
    
    bool flag(false);
    
    
            treca = (int)abs(ispis) % 10;
            druga = (int)abs(ispis / 10) % 10;
            prva  = (int)abs(ispis / 100) % 10;
            
        if(ispis==0)
        {
           
            mjesta = 3;
            prikaziBroj(0);
            wait(0.001);
                
            
        }
        
        else 
        {
            
            if(prva == 0 && !flag)
            {
                
                if(mjestoZareza == 1)
                {   
                    mjesta = 6;
                    prikaziBroj(0);
                    dp = 0;
                    
                }
                if(mjestoMinusa == 1)
                {
                    mjesta = 6;
                    dp = 1;
                    prikaziMinus();
                    
                    
                }
                
            
            } 
            else
            {
                mjesta = 6;
                prikaziBroj(prva);
                if(mjestoZareza == 1) dp = 0;
                else dp = 1;
                if(mjestoMinusa == 1) prikaziMinus();
                flag = true;
                
            }
            wait(0.001);
            
            if(druga == 0 && !flag)
            {
                if(mjestoZareza == 2)
                {   
                    mjesta = 5;
                    prikaziBroj(0);
                    dp = 0;
                    
                }
                if(mjestoMinusa == 2)
                {
                    mjesta = 5;
                    dp = 1;
                    prikaziMinus();
                    
                    
                }
            
            } 
            else
            {
                mjesta = 5;
                prikaziBroj(druga);
                if(mjestoZareza == 2) dp = 0;
                else dp = 1;
                if(mjestoMinusa == 2) prikaziMinus();
                flag = true;
                
            }
            wait(0.001); //0.02
            
            if(treca == 0 && !flag) {dp = 1;}
            else
            {
                mjesta = 3;
                prikaziBroj(treca);
                dp = 1;
                flag = true;
                
            }
            wait(0.001);
            
        
        
        }
        

}


char vratiZnak()
{
    
    
    
    for(int i = 0; i < 4; i++)
    {
        red[i] = 0;  // iskljuciSveRedove
    }
    
    char znak = 0;
    for(int i = 0; i < 4; i++)
    {
        red[i] = 1;
        for(int j = 0; j < 4; j++)
        {
            if(kolona[j]==1) // ako je nesto pritisnuto
                {
                    
                     if(db.read_ms() <= 200) break; // debouncing
                    
                    if(i < 3 && j < 3)
                    // cifra 1-9
                        {
                            db.reset();
                            return znak = i * 3 + j + 1 + '0';
                        
                        }
                        
                    else if(j == 3) // A-D
                    { db.reset();
                        return znak = 'A' + i;
                        
                        }
                    else if(i == 3)// 0, * ili #
                    {
                        if(j == 1)
                        {
                            db.reset();
                            return znak = '0';
                            }
                        if(j == 0)
                        {db.reset();
                            return znak = '*';
                            }
                        if(j == 2)
                        {
                            db.reset();
                            return znak = 'E';
                            }
                            
                    }
                    
                     db.reset();
                }
        }
        red[i] = 0;
    }
    
    return znak;  // ako dodje ovdje znaci da nista nije pritisnuto - vraca 0
}




void Kalkulator::pocetnoStanje()
{
    operand1 = operand2 = 0.;
    operacija = 0;
    second_fun = third_fun = poceo2 = minus = error = binary = mem = false;
    decimala = faza = 0;

}

void Kalkulator::izracunaj()
 {
    
   // if(binary) binToDec();
    
    
    if(operacija == 'a')
        operand1 = operand1 + operand2;
    else if(operacija == 'b')
        operand1 = operand1 - operand2;
    else if(operacija == 'c')
        operand1 = operand1 * operand2;
    else if(operacija == 'd')
    {
        if(operand2==0) error = true;
        else operand1 = operand1 / operand2;
    }
    else if(operacija == 's')
    {
        for(int i=0;i<operand2 - 1;i++)
            operand1 = operand1 * operand1;
    
    }
        
    
 }
void Kalkulator::postaviZarez()
 {
        decimala = 1;
 }


void Kalkulator::logaritam10()
{
    if(binary) binToDec();
    if(faza==1) izracunaj();
    
    
    
        if(operand1 <= 0) error = true;
        else operand1 = log10(operand1);
       
    
    
}
void Kalkulator::sinus()
{

    if(binary) binToDec();
    if(faza==1) izracunaj();
    
        operand1=sin(operand1);
        
    
    
       
    
}


void Kalkulator::reciproc()
{

if(binary) binToDec();
if(faza==1) izracunaj();
    
        if(operand1 == 0) error = true;
        else operand1 = 1./operand1;
     
    
    
    
}
void Kalkulator::korijen()
{

if(binary) binToDec();
if(faza==1) izracunaj();
    
        if(operand1 < 0) error = true;
        else operand1 = sqrt(operand1);
    
    
   
    
    
}
void Kalkulator::toMr()
{

if(binary) binToDec();
    if(faza==0 || faza==2)
    {
        memorija=operand1;
        
    }
    else if(faza==1)
    {
        memorija=operand2;
    }
}

void Kalkulator::fromMr()
{

if(binary) binToDec();
    if(faza==0 || (faza==1 && poceo2)) error = true;
    if(memorija==0) error = true;
    if(error) return;
    
    if(faza == 1)
    {
        operand2 = memorija;
        mem = true;
    
    }
    
    
    else if(faza==2)
    {
        pocetnoStanje();
        operand1 = memorija;
        
    }
}
void Kalkulator::clear()
{
    pocetnoStanje();
    memorija = 0.;
}
void Kalkulator::binToDec()
{
    if(faza==1) izracunaj();
    
    
        
        if(int(operand1) != operand1) error = true;
            if(operand1 < 0 ) error = true;
            
            if((int)operand1%10 !=1 || (int)operand1%10 != 0) error = true;
            if( (int)operand1/10 % 10 !=1 || (int)operand1/10 % 10 != 0) error = true;
            if( (int)operand1/100 % 10 !=1 || (int)operand1/100 % 10 != 0) error = true;
            
            if(error) return;
    
            int pom = int(operand1);
            
            operand1 =(pom / 100)*4 + ((pom%100)/10)*2 + pom%10;
            binary = false;
}
void Kalkulator::decToBin()
{   
    if(binary) binToDec();
    if(faza==1) izracunaj();
        
        if(int(operand1) != operand1) error = true;
        if(operand1 > 7 || operand1 < 0) error = true;
        
        if(error) return;
        
        int pom=int(operand1); int zbir[3]= {0,0,0} ;
        for(int i=0;i <3;i++){
            if(pom==1) {zbir[2]=1; break;}
            zbir[i]=(pom%2);
            pom=pom/2;
        }
        operand1= zbir[2]*100 + zbir[1]*10 + zbir[0];   
        binary = true;      
    
}

void Kalkulator::izvrsiOperaciju(char button)
{
    
    if(jeCifra(button)) azurirajOperand(int(button - '0'));
    else primijeniOperaciju(button);

}

void Kalkulator::azurirajOperand(int cifra)
{
    if(second_fun || third_fun || mem)
    {
        second_fun = third_fun = false;
        return;
    }
    
    float pom;
    
    if(faza==0) pom = operand1;
    else if(faza==1)
    {   
        pom = operand2;
        if(!poceo2)
        {
       /* float pomd = operand1;
        pocetnoStanje();
        operand1 = pomd;            */
        poceo2 = true;
        decimala = 0;
        minus = false;
        }
        faza = 1;
    }
    
    else if(faza==2)
    {
        pocetnoStanje();
        pom = operand1;
    }
    
    
        if((decimala==0 || decimala==1) && (pom >=100 || pom <= -10)) return;
        if(decimala==2 && ((int)pom >= 10 || (int)pom < 0)) return;
        if(decimala==3) return;
        
        
        if(decimala==0)
                if(!minus) pom = pom * 10 + cifra;
                else pom = pom*10 - cifra;
                
        else if(decimala==1)
        {
            if(!minus) pom = pom + cifra/10.;
            else pom = pom - cifra/10.;
            decimala++;
        }
            
        else if(decimala==2)
        {
             if(!minus) pom = pom + cifra/100.;
             else pom = pom - cifra/100.;
             decimala++;
        }
        
        if(faza==0 || faza==2) operand1 = pom;
    else if(faza==1) operand2 = pom;
    

}


void Kalkulator::primijeniOperaciju(char op)
{
    if(faza==1 && !poceo2)
            {
                if(!second_fun && !third_fun && op == '-')
                    minus = true;
                else if(second_fun && op == 'D') {}
                else error = true;

            }   
            
    
    
    //if(error) return;
    if(op==0) return;
    
    if(!second_fun && !third_fun)
    {
        if(op == 'A')
        {                   // +
            if(faza==1)
                {
                
                    izracunaj();
                    /*float pom = operand1;
                    pocetnoStanje();
                    operand1 = pom;*/
                    
                }
                    
            operacija = 'a';
            decimala = 0;
            minus = false;
            poceo2 = false;
            faza = 1;
            
        }
            
        else if(op == 'B') // -
        {
           if(faza==1)
                {
                
                    izracunaj();
                    float pom = operand1;
                    pocetnoStanje();
                    operand1 = pom;
                    
                }
                    
            operacija = 'b';
            faza = 1;
        }
            
        else if(op == 'C') // *
        {
            if(faza==1)
                {
                
                    izracunaj();
                    float pom = operand1;
                    pocetnoStanje();
                    operand1 = pom;
                    
                }
                    
            operacija = 'c';
            faza = 1;
        }
            
        else if(op == 'D') // /
        {
            if(faza==1)
                {
                
                    izracunaj();
                    float pom = operand1;
                    pocetnoStanje();
                    operand1 = pom;
                    
                }
                    
            operacija = 'd';
            faza = 1;
        }
            
        else if(op == '*') // dec. zarez
            postaviZarez();
            
            
        else if(op == 'E') // =
        {
            if(faza==1) izracunaj();
            /*float pom = operand1;
            pocetnoStanje();
            operand1 = pom;*/
            faza = 2;
            decimala = 0;
            operand2 = 0;
            minus = false;
            poceo2 = false;
        }
            
            
        
    
    }
    
    else if(second_fun)
    {
        if(op == 'A')
        {                   // Bin to Dec
            binToDec();
            float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
            
        }
            
        else if(op == 'B') // Dec to Bin
        {
            decToBin();
            float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
        }
            
        else if(op == 'C') // to MR
        {
            toMr();
            
        }
            
        else if(op == 'D') // from MR
        {
            fromMr();
            
        }
            
        else if(op == '*') // Clear
            clear();
            
            
        else if(op == '#') // nema nista
            second_fun = false;
            
        
    
    }
    
    else if(third_fun)
    {
            if(op == 'A')
        {                   // sin(x)
            sinus();
            float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
            
        }
            
        else if(op == 'B') // x^y
        {
             if(faza==1)
                {
                
                    izracunaj();
                    float pom = operand1;
                    pocetnoStanje();
                    operand1 = pom;
                    
                }
                    
            operacija = 's';
            faza = 1;
        }
            
        else if(op == 'C') // sqrt(x)
        {
            korijen();
            float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
            
        }
            
        else if(op == 'D') // 1/x
        {
            reciproc();
            float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
        }
            
        else if(op == '*')
            {       // log10
                logaritam10();
                float pom = operand1;
            pocetnoStanje();
            operand1 = pom;
            faza = 2;
            
            }           
        else if(op == '#') // nema nista
            third_fun = false;
    
    }
    
    

}

void secAndThird()
{
        osvjezi.detach();
        if(db1.read_ms() < 200) return;
    segmenti.input();
    if(segmenti == 0x7D)
        k.secondFun();
    else if(segmenti == 0x7E)
        k.thirdFun();
    segmenti.output();
    db1.reset();
    osvjezi.attach(&ispisDisplay, 0.005); 

}

int main()

{
    db.start();
    db1.start();
    dp = 1;
    mjesta = 0;
    osvjezi.attach(&ispisDisplay, 0.005); 
    tasteri.attach(&secAndThird, 0.5);
    
    for(int i = 0; i < 4; i++)
    {
        red[i] = 0;
    }
    
    while(1)
    {
        k.promjenaStanja();
    
    }


}