1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Looking help on calculator programming

Discussion in 'Microcontrollers' started by Parth86, Aug 2, 2017.

  1. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    I want to write c program for calculator but I think at this time I don't have capabilities to writes c program for calculator. so for deep understanding I started with addition only .. I want to write c program that can do addition like below example
    Example 1+2 =3, 2+1=3, 12+1=13, 1+12=13, 21+2=23, 21+1=22..... and so on

    consider I have 8051 LCD and four switches to perform addition
    Switch 1 = "1"
    switch 2 = "+"
    Switch 3 = "2"
    Switch 4 = "="

    if switch 1 is pressed than display number '1" on LCD.
    if switch 2 is pressed than display operator "+" on LCD.
    if switch 3 is pressed than display operator "2" on LCD.
    if switch 4 is pressed than display"result" on LCD

    basic steps
    1) get the first argument, maybe one or digits
    2) get the operator '+'
    3) get the second argument maybe one or digits
    4) get another operator '=' then perform the operation

    Look at this program. This program display "1" when I press switch 1 and display "2" when I press switch 2

    Code (c):

    #include<reg51.h>
    /* Data pins connected to port P1 of 8051 */
    #define  Data_Port_Pins        (P1)
    sbit    Register_Select_Pin   = P2^0;           /* Register Pin of LCD connected to Pin 0 of Port P2 */
    sbit    Read_Write_Pin        = P2^1;           /* Read/Write Pin of LCD connected to Pin 1 of Port P2 */
    sbit    Enable_Pin            = P2^2;           /* EN pin connected to pin 2 of port P2 */
    sbit    Switch1               = P3^0;           /* switch 1 connected to port pin P3.0 */
    sbit    Switch2               = P3^3;           /* switch 2 connected to port pin P3.3 */
    sbit    Switch3               = P3^4;          
    sbit    Switch4               = P3^5;          
    /* Function for creating delay in milliseconds */
    void Delay(unsigned int wait)
       {
          unsigned i, j;
          for(i = 0; i < wait; i++)
             for(j = 0; j < 1200; j++);
       }
    /* Function to send command instruction to LCD */
    void LCD_Command (unsigned char cmd)
    {
        Data_Port_Pins = cmd;
        Register_Select_Pin =0;
        Read_Write_Pin=0;
        Enable_Pin =1;
        Delay (2);
        Enable_Pin =0;
    }
    /* Function to send display data to LCD */
    void LCD_Data (unsigned char Data)
    {
        Data_Port_Pins = Data;
        Register_Select_Pin=1;
        Read_Write_Pin=0;
        Enable_Pin =1;
        Delay(2);
        Enable_Pin =0;
    }
    /* Function to prepare the LCD  and get it ready */
    void LCD_Initialization()
    {
        LCD_Command(0x38);
        Delay(20);
        LCD_Command(0x0e);
        Delay(20);
        LCD_Command(0x06);
        Delay(20);
        LCD_Command(0x01);
        Delay(20);
    }
    /* Function to send string to LCD */
    void LCD_String (unsigned char *string)
    {
    int i=0;
    while(string[i]!='\0')
    {
        LCD_Data(string[i]);
        i++;
        Delay(10);
    }
        return;
    }
        void main()
        {
        unsigned char string1[] ="1";
        unsigned char string2[] ="2";
            LCD_Initialization();
            while(1)
                    {
                        if (Switch1 == 1)
                        {
                                LCD_Command(0x82);
                                LCD_String(string1);
                                Delay(500);
                                LCD_Command(0x01);
                        }
                        else if (Switch2 == 1)
                        {
                                LCD_Command(0x82);
                                LCD_String(string2);
                                Delay(500);
                                LCD_Command(0x01);
                                Delay(10);
                        }
                       else
                         {
                                 LCD_Command(0x01);
                         }
            }
    }
     
    Now how to write c program for addition ?
    Note: I have replaced keypad with switch for easy understanding
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    First... Map a keyboard so the result is 0~9 , +, -, / * and enter ( possibly a clear key ).

    Then you need three arguments... Op1 Op2 and result..

    Set up a 4 state scenario with

    1 enter operand ( maybe a few key presses )
    2 enter operator ( ends state 1 and stores operator )
    3 enter second digits (again a few keypresses )
    4 deduce and display. ( ends state 3 and works out answer. )

    I have done this so when you struggle... I'll help
     
    • Like Like x 1
  3. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    I didn't want to use keypad because its so complicated for me. I have seen some program for keypad interfacing but really I don't understand the big program. My main aim is to learn programming with basics. so , I am trying to start with only four switch buttons. I am trying to write program for calculator which can do only addition. I don't have any idea how to complete program.

    so I started to learn one by one. first I wrote program that display number on LCD. than I wrote program to display number if switch pressed. after that I wrote program for two switches. I checked that program. if Switch 1 pressed than number 1 will display and switch 2 pressed number 2 will display. after that I tried to write program for addition with four switches but I am stuck I don't have any idea to write program for addition. how to write program for addition.
     
    Last edited: Aug 2, 2017
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK

    With four buttons, it won't be a very good calculator.

    In C there ate many tools to convert decimals to strings and visa~versa...

    C also has an extensive math library!
     
  6. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    okk I try to understand the code for keypad interfacing with microcontroller. I am trying to divide program into small parts.
    [​IMG]

    This code is for keypad scanning
    Code (c):

    keypad_read ()
    /* scan keypress on first Row 7 8 9 */
        RowA = 0;
        RowB = 1;
        RowC = 1;
        RowD = 1;

          if (Column1 == 0)     /* key "7" is pressed */                  
          if (Column2 == 0)     /* key "8" is pressed */
          if (Column3 == 0)     /* key "9" is pressed */
          if (Column4 == 0)     /* key "/" is pressed */

    /* scan keypress on second Row 4 5 6 x */
        RowA = 1;
        RowB = 0;
        RowC = 1;
        RowD = 1;

          if (Column1 == 0)     /* key "4" is pressed */                  
          if (Column2 == 0)     /* key "5" is pressed */
          if (Column3 == 0)     /* key "6" is pressed */
          if (Column4 == 0)     /* key "x" is pressed */

    /*scan keypress on third Row 1 2 3 -  */
        RowA = 1;
        RowB = 1;
        RowC = 0;
        RowD = 1;

          if (Column1 == 0)     /* key "1" is pressed */                  
          if (Column2 == 0)     /* key "2" is pressed */
          if (Column3 == 0)     /* key "3" is pressed */
          if (Column4 == 0)     /* key "-" is pressed */

        // scan keypress on fourth Row C 0 = + */
        RowA = 1;
        RowB = 1;
        RowC = 1;
        RowD = 0;

           if (Column1 == 0)     /* key "C"  is  pressed */                  
          if (Column2 == 0)     /* key "0" is   pressed */
          if (Column3 == 0)     /* key "+" is pressed */
          if (Column4 == 0)     /* key "=" is pressed * /
    I’m assigning high to all column and Then i am assigning first row to zero and keeps remaining row as high. to check which key is pressed. Then i am assigning second row to zero , than third and fourth row to zero to check which key is pressed

    How to complete whole program ?
     
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    Reading a complete keypad is very easy..

    look at this..
    Code (c):

    unsigned char KEY_Table[] = {0x31, 0x32, 0x33, 0x46,
           0x34, 0x35, 0x36, 0x45,
           0x37, 0x38, 0x39, 0x44,
           0x41, 0x30, 0x42, 0x43}; // keypad numbers

    unsigned char getkey()      //
     {
     char mask = 0xEF;      // mask for row selection
     char row;
     unsigned char key = 0;
     for(row = 0;row<4;row++)   // Four rows
      {
      KEY_PORT = mask;
      if(!COL1) key=1;     // Check
      if(!COL2) key=2;     // each
      if(!COL3) key=3;     // column
      if(!COL4) key=4;
      if(key)
       {
       delayMs(300);
       return (row*4) + key;   // if a key was pressed
               // mulply rows by 4 and add
       }        // add the column.
      mask<<=1;       // next row.
      }
     return 0;
     }
     
    This will grab a keypress... Then using the table you get the right key ( mapped ).
     
  8. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    I got this program. can you help me to understand this program. I want to understand working of each function one by one . I don't understand use of "void writeline(char[]); " in below program

    Code (c):


    #include<reg51.h>
    #include<string.h>

    //Define Macros
    #define Error  13    // Any value other than 0 to 9 is good here

    //Function declarations
    void cct_init(void);
    void delay(int);
    void lcdinit(void);
    void writecmd(int);
    void writedata(char);
    void writeline(char[]);
    void ReturnHome(void);
    char READ_SWITCHES(void);
    char get_key(void);
    int get_num(char);
    char get_func(char);
    void DispError(int);
    void disp_num(int);

    //*******************
    //Pin description
    /*
    P2 is data bus
    P3.7 is RS
    P3.6 is E
    P1.0 to P1.3 are keypad row outputs
    P1.4 to P1.7 are keypad column inputs
    */

    //********************
    // Define Pins
    //********************
    sbit RowA = P1^0;     //RowA
    sbit RowB = P1^1;     //RowB
    sbit RowC = P1^2;     //RowC
    sbit RowD = P1^3;     //RowD

    sbit C1   = P1^4;     //Column1
    sbit C2   = P1^5;     //Column2
    sbit C3   = P1^6;     //Column3
    sbit C4   = P1^7;     //Column4

    sbit E    = P3^6;     //E pin for LCD
    sbit RS   = P3^7;     //RS pin for LCD

    // ***********************************************************
    // Main program
    //
    int main(void)
    {
       char key;                     //key char for keeping record of pressed key
       int num1 = 0;                 //First number
       char func = '+';              //Function to be performed among two numbers
       int num2 = 0;                 //Second number
       
       cct_init();                   //Make input and output pins as required
       lcdinit();                    //Initilize LCD

       while(1)
       {
         //get numb1
         key = get_key();
         writecmd(0x01);            //clear display
        writedata(key);            //Echo the key pressed to LCD
        num1 = get_num(key);       //Get int number from char value, it checks for wrong input as well
         
        if(num1!=Error)            //if correct input then proceed, num1==Error means wrong input
        {
            //get function
            key = get_key();
            writedata(key);                  //Echo the key pressed to LCD
            func = get_func(key);            //it checks for wrong func
           
            if(func!='e')                    //if correct input then proceed, func=='e' means wrong input
            {
                //get numb2
                key = get_key();
                writedata(key);              //Echo the key pressed to LCD
                num2 = get_num(key);         //Get int number from char value, it checks for wrong input as well
               
                if(num2!=Error)              //if correct input then proceed, num2==Error means wrong input
                {
                    //get equal sign
                    key = get_key();
                    writedata(key);          //Echo the key pressed to LCD
                   
                    if(key == '=')           //if = is pressed then proceed
                    {
                        switch(func)         //switch on function
                        {
                        case '+': disp_num(num1+num2); break;
                        case '-': disp_num(num1-num2); break;
                        case 'x': disp_num(num1*num2); break;
                        case '/': disp_num(num1/num2); break;
                        }
                    }
                    else                     //key other then = here means error wrong input
                    {
                        if(key == 'C')       //if clear screen is pressed then clear screen and reset
                           writecmd(0x01);   //Clear Screen
                        else
                           DispError(0);      //Display wrong input error
                    }                                
                }
            }
         }
       }
    }


    void cct_init(void)
    {
       P0 = 0x00;   //not used
       P1 = 0xf0;   //used for generating outputs and taking inputs from Keypad
       P2 = 0x00;   //used as data port for LCD
       P3 = 0x00;   //used for RS and E  
    }

    void delay(int a)
    {
       int i;
       for(i=0;i<a;i++);   //null statement
    }

    void writedata(char t)
    {
       RS = 1;             // This is data
       P2 = t;             //Data transfer
       E  = 1;             // => E = 1
       delay(150);
       E  = 0;             // => E = 0
       delay(150);
    }


    void writecmd(int z)
    {
       RS = 0;             // This is command
       P2 = z;             //Data transfer
       E  = 1;             // => E = 1
       delay(150);
       E  = 0;             // => E = 0
       delay(150);
    }

    void lcdinit(void)
    {
      ///////////// Reset process from datasheet /////////
         delay(15000);
       writecmd(0x30);
         delay(4500);
       writecmd(0x30);
         delay(300);
       writecmd(0x30);
         delay(650);
      /////////////////////////////////////////////////////
       writecmd(0x38);    //function set
       writecmd(0x0c);    //display on,cursor off,blink off
       writecmd(0x01);    //clear display
       writecmd(0x06);    //entry mode, set increment
    }

    void ReturnHome(void)     /* Return to 0 cursor location */
    {
       writecmd(0x02);
       delay(1500);
    }

    void writeline(char Line[])
    {
       int i;
       for(i=0;i<strlen(Line);i++)
       {
          writedata(Line[i]);     /* Write Character */
       }
       
       ReturnHome();          /* Return to 0 cursor position */
    }

    char READ_SWITCHES(void)  
    {  
       RowA = 0; RowB = 1; RowC = 1; RowD = 1;    //Test Row A

       if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
       if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
       if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
       if (C4 == 0) { delay(10000); while (C4==0); return '/'; }

       RowA = 1; RowB = 0; RowC = 1; RowD = 1;    //Test Row B

       if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
       if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
       if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
       if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }
       
       RowA = 1; RowB = 1; RowC = 0; RowD = 1;    //Test Row C

       if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
       if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
       if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
       if (C4 == 0) { delay(10000); while (C4==0); return '-'; }
       
       RowA = 1; RowB = 1; RowC = 1; RowD = 0;    //Test Row D

       if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
       if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
       if (C3 == 0) { delay(10000); while (C3==0); return '='; }
       if (C4 == 0) { delay(10000); while (C4==0); return '+'; }

       return 'n';               // Means no key has been pressed
    }

    char get_key(void)           //get key from user
    {
       char key = 'n';              //assume no key pressed

       while(key=='n')              //wait untill a key is pressed
           key = READ_SWITCHES();   //scan the keys again and again

       return key;                  //when key pressed then return its value
    }

    int get_num(char ch)         //convert char into int
    {
       switch(ch)
       {
           case '0': return 0; break;
           case '1': return 1; break;
           case '2': return 2; break;
           case '3': return 3; break;
           case '4': return 4; break;
           case '5': return 5; break;
           case '6': return 6; break;
           case '7': return 7; break;
           case '8': return 8; break;
           case '9': return 9; break;
           case 'C': writecmd(0x01); return Error; break;  //this is used as a clear screen and then reset by setting error
           default: DispError(0); return Error; break;     //it means wrong input
       }
    }

    char get_func(char chf)            //detects the errors in inputted function
    {
       if(chf=='C')                   //if clear screen then clear the LCD and reset
       {
           writecmd(0x01);            //clear display
           return 'e';
       }
       
       if( chf!='+' && chf!='-' && chf!='x' && chf!='/' )  //if input is not from allowed funtions then show error
       {
           DispError(1);
           return 'e';
       }

       return chf;                        //function is correct so return the correct function
    }


    void DispError(int numb)           //displays differet error messages
    {
       writecmd(0x01);                //clear display
       
       switch(numb)
       {
       case 0:    writeline("Wrong Input");      break;
       case 1:    writeline("Wrong Function");   break;
       default:    writeline("Wrong Input");      break;
       }
    }

    void disp_num(int numb)            //displays number on LCD
    {  
       unsigned char UnitDigit  = 0;  //It will contain unit digit of numb
       unsigned char TenthDigit = 0;  //It will contain 10th position digit of numb

       if(numb<0)
       {
           numb = -1*numb;  // Make number positive
           writedata('-');    // Display a negative sign on LCD
       }

       TenthDigit = (numb/10);             // Findout Tenth Digit

       if( TenthDigit != 0)             // If it is zero, then don't display
           writedata(TenthDigit+0x30);     // Make Char of TenthDigit and then display it on LCD

       UnitDigit = numb - TenthDigit*10;

       writedata(UnitDigit+0x30);     // Make Char of UnitDigit and then display it on LCD
    }


     
     
  9. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    It's a function definition ( A bad one at that )

    If you are going to pass pointers it would be like this..
    void writeline(char* str);

    Plus!! They are passing constants so I would worry if it works atall...
    This is more appropriate...
    void writeline(const char* str);

    But!! From this you can still see the calculations and functions.... I prefer my way of reading the keypad.

    My calculator has 24 buttons.... I'll dig it out and show you!!
     

Share This Page