Calculadora con PIC + teclado + LCD

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
 
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...
 
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.

Código:
#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();
  
  
  }
  }
  
  }


}
 
Última edición por un moderador:
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
 

Adjuntos

  • CALCULADORA.rar
    13.2 KB · Visitas: 1,042
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?

Código:
    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?
 
Última edición por un moderador:
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.
 

Adjuntos

  • Librerias y ejemplos teclado 4x4 LCD Retardos.rar
    19.3 KB · Visitas: 512
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.

HTML:
#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);
}
 
Última edición:
Última edición por un moderador:
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.
C:
#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);
}
 
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
 
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 ?
C:
#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) {

        
       }
 
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.
 
Atrás
Arriba