# Calculadora con PIC + teclado + LCD



## emerson mosquera (Nov 16, 2006)

hola a todos, necesito una pequeña ayuda. necesito hacer una calculadora que sume y reste 
utilizando el PIC16F877A + teclado + LCD, ya sé como visualizar datos en LCD, lo que no sé 
es como calcular y visualizarlo el dato resultante,es decir,

si sumo 9+9=18 ó 25+32=57 ó 65-25=40

Gracias por su atención


----------



## Andres Cuenca (Nov 16, 2006)

Hola Emerson,

Te dejo un ejemplo extractado del proteus, mejor imposible.

Saludos.


----------



## jose1 (May 21, 2009)

hola... me podrian ayudar a hacer con pic 16f877 y una lcd, hacer una calculadora q sume reste multipique, divida. para ser programado en mplab,y simularlo en proteus... es indispensable para graduarme porfavorrrrrrr.... necesito ayuda... gracias...


----------



## felixls (May 21, 2009)

Jose, podrías ver este proyecto, aunque no está terminado puede ser un buen comienzo:

http://www.ucontrol.com.ar/forosmf/proyectos-con-pic/calculadora-cientifica-grafica-con-pic/


----------



## luis5195 (Feb 18, 2013)

hola a todos mi inquietud de hoy es la siguiente estoy tratando de hacer una calculadora mediante una lcd y un teclado 4x4  esta calculadora solo realizara sumas de 3 valores ingresados mediante el teclado estoy probando primeramente con hacer que sume 2 valores pero aun no logro resultados me gustaría que alguien me colabore con dicha programación en ccs adjunto el código que he estado usando.


```
#include <16F876a.h>                        //se nombra libreria del pic16f876 para contar con todos sus recursos
#fuses NOWDT,NOPROTECT,XT                   //no perro guardian, no preoteccion,cristal
#use delay(clock=20000000)                  //se utiliza un reloj de 20 mhz
#define lcd_data_port getenv("sfr:portc")   //se define el puerto c para usar el lcd
#include <lcd.c>                            //se nombra libreria del lcd para contar con todos sus recursos
#include <kbd2.c>                            //se nombra libreria del keypad 4x4 para contar con todos sus recursos
#use standard_io(a)                         //se declaran los puertos como estandard
#use standard_io(b)                         //se puede modificar el registro tris en
#use standard_io(c)                         //cualquier momento mediante la directiva "standard"

 char k;                                    //variable k tipo char
int num1;
int num2;
int res;


void tecla(){
while(true){                                //bucle infinito
k=kbd_getc(); 
num2=k-48;                              
if(k!=0){
  if(k=='0','1','2','3','4','5','6','7','8','9'){
    printf(lcd_putc,"%u",num2);}
 delay_ms(100);
 lcd_putc("\f");
 num1=num1-48;
 num2=num2-48;
 res=num1+num2;
       delay_ms(100);
  printf(lcd_putc,"%u",res);
  delay_ms(1000);
  }
  
  }

}
void main() {                               //funcion principal

lcd_init();                                 //se inicializa lcd
kbd_init();                                 //se inicializa keypad

port_b_pullups (true);                      //se activan resistencias pullups de puerto b
 
while(true){                                //bucle infinito
k=kbd_getc(); 
num1=k-48;                              //se obtiene el dato de la tecla pulsada y se guarda en la varible k
if(k!=0){
  if(k=='0','1','2','3','4','5','6','7','8','9'){
    printf(lcd_putc,"%u",num1);}
      
      
  if(k=='+'){
  lcd_putc("\f");
  tecla();
  
  
  }
  }
  
  }


}
```


----------



## oskr2070 (Feb 12, 2014)

Andres Cuenca dijo:


> Hola Emerson,
> 
> Te dejo un ejemplo extractado del proteus, mejor imposible.
> 
> Saludos.



hola andres si me pudieras ayudar tambien con lo mismo de emerson.... una calculadora con display y teclado en ccs


----------



## tek_nikkos (Feb 24, 2014)

en proteus....trae como ejemplo una calculadora realiza las operaciones básicas......busquen los archivos de ejemplo de proteus.............


----------



## ORLANDOC (Sep 18, 2014)

Buenas Tardes!

Como estan? espero que bien.

Les cuento...Resultado que en la U me pusieron a hacer una pequeña calculadora en lenguaje MPLAB, la calculadora suma, resta, y multiplica. No hace mucho es que empeze a andar en este mundo de el lenguaje asm, y en realidad me tiene fascinado, pero estoy que cuelgo toalla, porque no logro entender algunas cosas para poder desarrollar la calculadora.

Se va a utilizar un teclado matricial 4x4 como entrada por el PORTB, hasta ahi facil, lo que se me hace dificil, es que los 3 datos que necesita la calculadora que son los dos numeros y la operacion que se desea, entran por el mismo puerto(PORTB), estuve preguntando y leyendo y parece ser por interrupciones, pero no he logrado dar con ello. La idea es que por ejemplo: yo oprimo el 7, listo me lo guarda en una variable, luego oprimo 2, me lo guarda en otra variable distinta, y luego oprimo la operacion que deseo, en este caso ' + ' , listo que me lo guarde en una variable....Pero como hago para introducir los 3 datos por el mismo puerto?, estuve intentando y al introducir el primer dato, de una vez se llenan todas las demas variables, las que tenia destinadas para el numero que falta y para el tipo de operacion.

Espero me haya hecho entender.

De antemano agradezco cualquier colaboracion que me puedan dar.

PD: Adjunto codigo que llevo hasta el momento, ahi muchas cosas que mejorar, pero por ahora estoy barado es en eso, en como introducir los 3 datos por el mismo puerto, y que me queden guardado en variables distintas.

PD1: Porfavor no se asusten con lo largo del codigo, lo que sucede es que lo estoy haciendo por tablas, y me salieron bastante grandes, no se me ocurre como mejorarlas.

Gracias


----------



## Miembro eliminado 356005 (Sep 18, 2014)

Lees un dato y esperas a que se levante el dedo del pulsador. Para eso te vale con esperar a que el PORTB devuelva un 0 indicando que no hay ninguna tecla pulsada.

El resto de datos los lees así también.

Disculpa... ¿qué significa esto?


```
MOVLW    .100000
```
Humm... ¿el registro W no es de 8 bit? Entonces... ¿Cómo es posible que almacenes 100 000 en un registro de 8 bit?


----------



## MrAlphonse (Sep 18, 2014)

Hola, mira, te adjunto una libreria que maneja el libro "PIC16F84A Desarrollo de proyectos", es un buen libro para entender lo básico, las librerias son buenas. Tambien te adjunto unos de los ejemplos que vienen con el mismo libro, leelos y espero te sean de ayuda. Y como dice el camarada, tienes que esperar a que el usuario deje de pulsar la tecla, en la libreria del teclado viene una rutina detectar si el usuario ya dejo de oprimir la tecla.


----------



## m9197 (May 13, 2015)

necesito hacer una calculadora que realize las siguientes operaciones; seno, coseno, raiz y exponencial. Pero no se como hacer esas operaciones. con el lcd no tengo ningun problema, leer el teclado y imprimir el caracter, el codigo asci y el numero decimal tampoco. 
  La calculadora la voy a hecer usando un teclado 4x4, lcd 2x16 y pic 16f877a. 

mi idea es que me lea el teclado si precion el boton A del teclado llame una funcion llamada raiz y en esta funcion me permita capturar un numero al cual se le calcule la raiz. despues regrese a la funcion principal e imprima el resultado.

adjunto el codigo, donde propongo la idea, pero no me funciona. el codigo que adjunto solo imprime lo siguiente y que no entiendo porque.

0     imprime el cero (el cual es correcto)
pero, al presionar A se va a la funcion raiz imprimiendo lo siguiente
raiz( =6   
raiz=6
 no me permite capturar un numero al cual debo calcularle la raiz y no se de donde sale ese 6, ademas tampoco regresa a la funcion principal, al final puse return(raiz); para que regresra a la funcion principal, pero ahora ya no compila. 

el codigo que adjunto es solo la idea, si funcioanara lo demas seria mas facil. por cierto estoy tratando de ler los caracteres del teclado para despues convertirlos en entero.


```
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4Mhz)
#define use_portb_kbd TRUE
#include <lcd.c>
#include <jkbd.c>


int raiz();
int sin();
int cos();
int exp();
void main ()
{
int k;
int n;
int r;
   lcd_init();
 kbd_init();
 port_b_pullups (TRUE);
 lcd_putc("0");
   while (TRUE)
   {
      k=kbd_getc();
         n=k-48;
             if(k!=0)
             {
                    if(k=='A')
                    {
                    r=raiz();
                    printf(lcd_putc,"\f fin de la raiz");
                    delay_ms(000);
                    printf(lcd_putc,"\f resultado=%u",r);
                    delay_ms(2000);
                    }
             }
    
   } 
}

int raiz()
{
 char k;
 char n;
 char r;
 printf(lcd_putc,"\f raiz(");
  kbd_init();
 k=kbd_getc();
 if(k!=0)
 n=k-48;
 printf(lcd_putc," =%u",n);
 delay_ms(1000);
 r=n^(1/2);
 return(raiz);
}
```


----------



## Miembro eliminado 356005 (May 13, 2015)

Puedes guardar una tabla de tangentes en la memoria del PIC, y luego, para sacar el valor del seno y coseno, solo tienes que construirlos a partir de sus equivalencias usando solo los valores de la tangente. La exponencial, creo que se puede resolver de la misma manera. Y la raíz cuadrada, una forma sería siguiendo el método manual, pero casi seguro que debe haber mejores soluciones (creo que era con otra tabla, pero esta vez, de logaritmos).


----------



## ShangriLa (Mar 14, 2018)

Hola, buenas noches. Tengo cierto problema a la hora de programar.
Lo que sucede es que cuando presiono una tecla en el teclado, lo guardo en una variable, luego guardo la variable para la operación,  pero al momento de querer guardar el segundo valor de la operación, también se modifica el primero.

Dejo el programa para ver si alguien me puede dar un consejo acerca de cómo solucionarlo.

```
#INCLUDE <16f877A.h>

#FUSES XT, NOPUT, NOLVP, NOPROTECT, NOWRT
#USE DELAY (CLOCK=400000)

#iNCLUDE <lcd.c>
#INCLUDE <kbd3.c>

#BYTE TRISB=0x86
#BYTE PORTB=0x06
#BYTE PORTC=0x07
#BYTE TRISC=0x87

char k;
int x;
int n1;
int o;
int n2;

void main (void)
{
    lcd_init();
    kbd_init();
    port_b_pullups(TRUE);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"teclea un numero");

    do
    {
        k=kbd_getc();
        n1=k-48;

        if(k!=0)
        {
            if((k<=58)&&(k>=48))
            {
                lcd_gotoxy(1,2);
                printf(lcd_putc,"%u",n1); //printf(lcd_putc,"C:%c,A:%u,N:%u",k,k,n1);
                delay_ms(1000);
            }

            if(k==47) //%
            {
                o=K;
                lcd_gotoxy(2,2);
                printf(lcd_putc,"%c",o);
                delay_ms(500);
            }

            if(k==88)//x
            {
                o=K;
                lcd_gotoxy(2,2);
                printf(lcd_putc,"%c",o);
                delay_ms(500);
            }

            if(k==45) //-
            {
                o=K;
                lcd_gotoxy(2,2);
                printf(lcd_putc,"%c",o);
                delay_ms(500);
            }

            if(k==43) //+
            {
                o=K;
                lcd_gotoxy(2,2);
                printf(lcd_putc,"%c",o);
                delay_ms(500);
            }

            if(k==61) //=
            {
                o=K;
                lcd_gotoxy(2,2);
                printf(lcd_putc,"%c",o);
                delay_ms(500);
            }

            if(k==78)
            {
                lcd_gotoxy(1,2);
                printf(lcd_putc,"                ");
                delay_ms(500);
            }
        }
    }

    WHILE(TRUE);
}
```


----------



## chclau (Mar 15, 2018)

Hola,

No veo donde guardas el segundo numero. Si entiendo bien tu problema, lo que yo haria es, luego de almacenado el codigo de operacion, encender una bandera tal que el proximo valor de "k" sea almacenado en "n2" en lugar de en "n1".

Saludos


----------



## katalina (May 5, 2020)

Hola. Buena noche.
Tengo un trabajo de la universidad que consiste en una calculadora. (Una matriz 4x4)
Tengo un parte del código pero no entiendo bien cómo hacer las operaciones básicas. 
¿Alguien puede ayudarme ?

```
#include <xc.h>
#define _XTAL_FREQ 80000000
#pragma config  FOSC = HS
#pragma config WDT = OFF
#pragma config MCLRE = OFF
#pragma config LVP = OFF
#define time 10

//LCD
#define CD 0x10
#define RH 0x02
#define EMS 0x06
#define DC 0x0F
#define DSr 0x1C
#define DSl 0x18
#define FS 0x3C
#define RAW1 0x80
#define RAW2 0XC0
#define E    LATE0
#define RS   LATE1

void settings (void) ;
    //LCD
void settingsLCD (unsigned char word );
void writeLCD (unsigned char word );
void LCD(unsigned char data) ;

// INTERRUPCION
void __interrupt() KBINT(void);

//

int  keyborad (void);

int  i, j, keys [4][4] ={ (7,8,9,15),
                          (4,5,6,14),
                          (1,2,3,13),
                          (10,0,11,12)};

void main (void) {
    settings () ;

    while(1) {

    }
}

void settings (void) {
    OSCCON = 0X72 ;
    ADCON1 = 0X0F ;
    TRISB = 0XF0 ;
    TRISD = 0 ;
    TRISE = 0;
    LATB = 0X0F;
    LATD = 0;
    LATE = 0;

    //LCD
    settingsLCD(EMS);
    settingsLCD(DC);
    settingsLCD(FS);
    settingsLCD(CD); 

    // INTERRUPCIONES
    GIE = 0 ;
    RBIE = 1;
    RBIF = 0 ;
}

void settingsLCD (unsigned char word ) {
    RS = 0;
    LCD(word) ;
}

void writeLCD (unsigned char word ) {
    RS = 1;
    LCD(word) ;
}

void LCD(unsigned char data) {
     E = 1;
    __delay_ms(time1);
    LATD = data;
    __delay_ms(time1);
    E = 0;
    __delay_ms(time1);
}

   void __interrupt() KBINT(void){
       if (RBIF){
           if ((PORTB &  0XF0)) {
               keyborad () ;
           }
       }
   }

   int keyborad (void){
       LATB = 0X01 ;
       for (i=0; i<=3 ; i++ ) {
           if (PORTBbits.RB4) {
               j=0
              break;

       }else if (PORTBbits.RB4) {

       }else if (PORTBbits.RB4) {

       }else if (PORTBbits.RB4) {

        
       }
```


----------



## DOSMETROS (May 6, 2020)

De dónde sacaste ese código ?


----------



## katalina (May 6, 2020)

DOSMETROS dijo:


> De dónde sacaste ese código ?


 Yo lo estaba haciendo con lo que aprendí en el semestre.


----------



## el_patriarca (May 6, 2020)

keyboard es palabra reservada? Por qué keyborad? Me pone nervioso.

La declaración de los fuses me parece rara, así también que puedas programar interrupciones y no puedas programar operaciones básicas.


----------



## katalina (May 6, 2020)

Por que el  keyborad te pone nervioso? 
Jajaja 
Lo unico que he hecho es declarar y crear las funciones de la lcd y del pic..


----------



## el_patriarca (May 6, 2020)

Con la función lcd_getc(x,y) puedes obtener el valor de la lcd, guardarla en una variable, y hacer cualquier operación


----------



## D@rkbytes (May 6, 2020)

katalina dijo:


> Lo único que he hecho es declarar y crear las funciones de la lcd y del pic


Si no nos dices, no nos damos cuenta. 
O sea que entre lo que hiciste, y nada, es prácticamente lo mismo.

Te sugiero que busques el código fuente para PC de una calculadora básica, lo estudies y posteriormente lo transcribas al microcontrolador.


----------



## katalina (May 6, 2020)

_*Voy a intentarlo gracias! *_


D@rkbytes dijo:


> Si no nos dices, no nos damos cuenta.
> O sea que entre lo que hiciste, y nada, es prácticamente lo mismo.
> 
> Te sugiero que busques el código fuente para PC de una calculadora básica, lo estudies y posteriormente lo transcribas al microcontrolador.


-, - vale gracias


----------



## DOSMETROS (May 6, 2020)




----------



## el_patriarca (May 6, 2020)

Podría ser un error sintáctico... pero no, todo el código está escrito con keyborad


----------



## Scooter (May 6, 2020)

Así compilará sin pegas


----------

