Autor Tema: solucion como hacer una calculadora de varios digitos y otros ejemplos mas  (Leído 11608 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
Buenos dias señores de antemano gracias a MLO por su colaboracion para la terminacion de este programa el me ayudó a concatenar las variables para formar una sola para poder operar con ellas aqui comparto ese ejemplo y otros mas.


//julian alvaran 25_03_09
//calculadora de 5 digitos
//ojo los calculos cuyo resultado sea mayor a 11 digitos incluyendo el punto
//decimal son inciertos el resto no hay problema
//la interface de la lcd es de 4 bits
//
//conexion en ths2008 hardware propio
//en el cual cuando envio un alto por las columnas y se oprime un boton
//se ve un bajo en los pines de las filas
//
// teclado matricial 4x4
//
//          C0 C1 C2 C3
//       F0 [1][2][3][A]
//       F1 [4][5][6]
//       F2 [7][8][9][C]
//       F3
  • [0]
  • [D]

//
//       DESCRIPCION PINES TECLADO
//
//        C1  C2  C3  C4  F1  F2  F3  F4
//       RC1/RC2/RD0/RC0/RD1/RC5/RD3/RD2
//

///////////////////////////////////////////////////////////////////////////
//definimos tipo de pic, fuses, y clock////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

//////////////////////////////////////////////////////////////////////////
//con estas librerias utilizamos los puertos como in o out////////////////
//////////////////////////////////////////////////////////////////////////

#use standard_io(b)
#use standard_io(c)
#use standard_io(d)

//////////////////////////////////////////////////////////////////////////
//libreria que controla la lcd dentro de esta se defines los pines////////
//del pic que controlaran la lcd//////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

#include <flex_lcd.c>

//////////////////////////////////////////////////////////////////////////
//declaracion de constantes y variables///////////////////////////////////
/////////////////////////////////////////////////////////////////////////

int codigo_tecla[16]={1,2,3,'+',4,5,6,'-',7,8,9,'X','*',0,'=','/'};//distibucion de simbolos en teclado
                                                                   //se cambia segun distribucion en el mismo
                                                                   //empezando por cero codigo_tecla[0]=1
   
float resultado;
byte  i_op=0,cont_tecla, i_col, i_fil,operacion=0;
int   operando[5],operador[5];
float operador_total,operando_total;
//////////////////////////////////////////////////////////////////////////
//constantes utilizadas para manejo de lcd (opcional)/////////////////////
//////////////////////////////////////////////////////////////////////////

#define  sig         0x06
#define  clear       0x01
#define  cursor_no   0x0C
#define  lin1        0x85
#define  ren1        0x80
#define  ren2        0xC0

//////////////////////////////////////////////////////////////////////////
//declaro los pines utilizados para teclado///////////////////////////////
//////////////////////////////////////////////////////////////////////////

int  columna[4]   =  {pin_c1,pin_c2,pin_d0,pin_c0};//aqui se pueden cambiar los pines de las columnas
int  fila[4]      =  {pin_d1,pin_c5,pin_d3,pin_d2};//aqui se pueden cambiar los pines de las filas



//////////////////////////////////////////////////////////////////////////
//se encarga de selecionar tipo de operacion
//////////////////////////////////////////////////////////////////////////

void operacion_mat(){

   switch (codigo_tecla[cont_tecla]){
   
      case '+':operacion=1;i_op=0;break;
      case '-':operacion=2;i_op=0;break;
      case 'X':operacion=3;i_op=0;break;
      case '/':operacion=4;i_op=0;break;
                   
   }
   
}

void total(){


   switch (operacion){      //operacion vale 1 si es suma,2 si es resta, 3 si es *, y 4 si es /. 
   
      case 1:  resultado=operando_total + operador_total;
               i_op=0;
               break;
     
      case 2:  resultado=operando_total - operador_total;
               i_op=0;
               break;
               
      case 3:  resultado=operando_total * operador_total;
               i_op=0;
               break;
               
      case 4:  resultado=operando_total / operador_total;
               i_op=0;
               break;                 
   }
   
   
   lcd_gotoxy(5,2);
   printf(lcd_putc,"%f ",resultado);
   operacion=0;
 
}

void guarda_variables(){

   if (operacion>0){
   
      if(i_op>0){
     
         operador[i_op]=codigo_tecla[cont_tecla];
         operador_total=operador_total*10;
         operador_total=operador_total+operador[i_op];
         ++i_op;
       
         return;
         
         }
      operador[i_op]=codigo_tecla[cont_tecla];
      operador_total=operador[i_op];
      ++i_op;
      return;
   }
   
   if(i_op>0){
   
         operando[i_op]=codigo_tecla[cont_tecla];
         operando_total=operando_total*10;
         operando_total=operando_total+operando[i_op];
         ++i_op;
       
         return;
         
         }
       
      lcd_send_byte(0,clear);
      delay_ms(10);
      operando[i_op]=codigo_tecla[cont_tecla];
      operando_total=operando[i_op];
      ++i_op;
     
}

//////////////////////////////////////////////////////////////////////////
//subrutina encargada de revisar las columnas y filas, para asignar un
//valor segun columna y fila testeada asigna el valor correspondiente
//////////////////////////////////////////////////////////////////////////

void key_press () {
 
   
   
   delay_ms(200); //retardo para evitar armonicos
   cont_tecla=0;  //borramos contador codigo_tecla
   i_col=0;       //borramos subid de columna este determina la col utilizada
   i_fil=0;       //borramos subid de fila este determina la fila utilizada
     
no_pulsa:         //si no hay tecla pulsada

      output_high(columna[i_col]);//enviamos alto a la col
     
      if (!input(fila[i_fil]))   //si es cero se pulsó una tecla(segun hardware), se puede cambiar a (input(fila[i_fil]))
                 //si lo que esperamos es un alto
         goto tecla_pulsada;     //vamos a tecla_pulsada si es cero
      output_low(columna[i_col]);//enviamos un bajo a la columna
      ++cont_tecla;  //incrementa contador de la tecla, determina el valor en codigo_tecla[cont_tecla]
      ++i_col;       //incrementa la col a revisar
      if (i_col==4){ //si se revisaron las 4 col incrementa la fila y volvemes a col cero
         i_col=0;
         ++i_fil;
      }
     
      if (i_fil==4){                              //si se revisaron las 4 filas salimos de subrutina
         return;
      }
     
      goto no_pulsa;                            //si no se an revisado las 4 col y 4 filas volvemos a no pulsa
     
   
tecla_pulsada:                                         //si se pulsa tecla
   
   
   
   if (codigo_tecla[cont_tecla]<10){ //si es un #
      guarda_variables();
      printf(lcd_putc,"%u",codigo_tecla[cont_tecla]); //"%u"para visualizar enteros delo contrario veremos el ascii
      output_low(columna[i_col]);//bajo para limpiar puerto
     
      return;
   }
   printf(lcd_putc,"%c",codigo_tecla[cont_tecla]);    //"%c" para visualizar caracteres
   output_low(columna[i_col]);//bajo para limpiar puerto
 
   if(codigo_tecla[cont_tecla]=='='){
      total();
      return;
   }
   
   operacion_mat();
       
}

void main() {
 
   lcd_init();       //inicializa lcd
   lcd_gotoxy(1,1);  //empieza en la 1ra pos de la 1er fila
   operacion=0;
   do {
     
      key_press ();  //bucle infinito para revisar el teclado
     
     
   } while (TRUE);
}


entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #1 en: 10 de Abril de 2009, 18:28:40 »
//por julian alvaran 06_04_09
//en la libreria flex_lcd.c se definen los pines que van al lcd
//este programa muestra caracteres personalizados de 2x2 caracteres
//en una lcd de 2x16


#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define  sig         6     //0x06
#define  clear       1     //0x01
#define  cursor_no   12    //0x0C
#define  cursor_si   14    //0x0E
#define  cur_blink   15    //0x0F
#define  dezp_izq    24
#define  dezp_der    28
#define  gen_car     64
#define  lin1        133   //0x85
#define  ren1        128   //0x80
#define  ren2        192   //0xC0

#include <flex_lcd.c>
#include <big_char.c>

byte  car;


void main() {
 

   lcd_init();
 
   car=0;
   
   do{
   
   delay_ms(1000);
   
   genera_char(0,car);
   
   lcd_gotoxy(1,1);
   lcd_putc(0);
   lcd_putc(1);
   lcd_gotoxy(1,2);
   lcd_putc(2);
   lcd_putc(3);
   
   
 
   genera_char(1,car);
   
   lcd_gotoxy(3,1);
   lcd_putc(4);
   lcd_putc(5);
   lcd_gotoxy(3,2);
   lcd_putc(6);
   lcd_putc(7);
   
   ++car;
   if(car==10)
      car=0;
   }while(true);
   

entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #2 en: 10 de Abril de 2009, 18:30:06 »
libreria big_char.c




//por julian alvaran 07_04_09
//
//esta libreria se encarga de generar caracteres de tamaño 2x2 posiciones de la lcd
//solo se pueden mostrar 2 tipos diferentes de caracteres en la lcd porque para
//cada caracter se necesitan 4 posiciones de la cgram de la lcd y solo contamos
//con 8 posiciones lo que me permite solo generar 2 caracteres al mismo tiempo.
//el 2,4,8,9 tienen problemas no se porque
//para generar se llama:
//
//generar_char(pos,caracter)
//
//donde pos es 0 ó 1 y caracter entre 0 y 9
//

   
   byte i_cg,i_chr;
   
   byte mem_cgram[2][4]={64,72,80,88,     //posiciones cgram para gen 1er caracter
                         96,104,112,120}; //posiciones cgram para gen 2do caracter


   byte big_char[4][32]= {0x07,0x0F,0x18,0x18,0x18,0x18,0x18,0x19,   //
                          0x1C,0x1E,0x07,0x0F,0x0B,0x1B,0x13,0x13,   //codigo para
                          0x19,0x1B,0x1E,0x1C,0x1C,0x0F,0x07,0x00,   //generar el cero
                          0x03,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00,   //
                 
                 
                          0x07,0x0F,0x1F,0x1F,0x1B,0x03,0x03,0x03,   //
                          0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,   //codigo para
                          0x03,0x03,0x03,0x03,0x03,0x0F,0x0F,0x00,   //generar el 1
                          0x18,0x18,0x18,0x18,0x18,0x1E,0x1E,0x00,
                         
                         
                          0x07,0x0F,0x1C,0x18,0x00,0x00,0x00,0x00,   //
                          0x1E,0x1F,0x03,0x03,0x07,0x0E,0x0C,0x18,   //codigo para
                          0x01,0x03,0x07,0x0E,0x1C,0x1F,0x1F,0x00,   //generar el 2*
                          0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,
         
         
                          0x1F,0x1F,0x10,0x00,0x00,0x01,0x03,0x01,   //
                          0x1F,0x1F,0x07,0x0E,0x1C,0x18,0x10,0x00,   //codigo para
                          0x00,0x00,0x18,0x18,0x18,0x0F,0x07,0x00,   //generar el 3
                          0x1C,0x0E,0x07,0x03,0x03,0x1E,0x1C,0x00
                         
                         
                          0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0X18,   //
                          0X1C,0X1C,0X1C,0X1C,0X0C,0X0C,0X0C,0X00,   //codigo para
                          0X1F,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,   //generar el 4*
                          0X1F,0X1F,0X0C,0X0C,0X0C,0X0C,0X0C,0X00
                         
                          0x1F,0x1F,0x18,0x18,0x1F,0x1F,0x00,0x00,   //
                          0x1F,0x1F,0x00,0x00,0x1C,0x1E,0x07,0x03,   //codigo para
                          0x00,0x00,0x18,0x18,0x1C,0x0F,0x03,0x00,   //generar el 5
                          0x03,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00
                         
                         
                          0x03,0x07,0x0E,0x1C,0x18,0x18,0x1F,0x1F,   //
                          0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1E,   //codigo para
                          0x1F,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,   //generar el 6
                          0x1F,0x03,0x03,0x03,0x07,0x1E,0x1C,0x00
                         
                          0x1F,0x1F,0x00,0x00,0x00,0x01,0x03,0x07,   //
                          0x1F,0x1F,0x07,0x0E,0x1C,0x18,0x10,0x00,   //codigo para
                          0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,   //generar el 7
                          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                         
                          0x07,0x0F,0x18,0x18,0x18,0x18,0x0F,0x07,   //
                          0x1C,0x1E,0x03,0x03,0x03,0x03,0x1E,0x1C,   //codigo para
                          0x0C,0x18,0x18,0x18,0x18,0x0F,0x07,0x00,   //generar el 8 *                                                                                   
                          0x06,0x03,0x03,0x03,0x03,0x1E,0x1C,0x00
                         
                          0x07,0x0F,0x18,0x18,0x18,0x18,0x0F,0x07,   //
                          0x1C,0x1E,0x03,0x03,0x03,0x03,0x1F,0x1F,   //codigo para
                          0x19,0x1B,0x1E,0x1C,0x1C,0x0F,0x07,0x00,   //generar el 9*
                          0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x00};
                         
                         
                         
                         
                         
                         
                         
                         
                         
                         
               
void genera_char(int1 pos_cgram,byte simbolo){

   i_cg=0;
   i_chr=0;
   
inc_men_cgram:

   lcd_send_byte(0,mem_cgram[pos_cgram][i_cg]); //selecciona posiciones de la cgram
                                                //donde se guardaran los fragmentos
                                                //de caracter

aun_no:

   lcd_putc(big_char[simbolo][i_chr]);          //forma simbolo segun la declaracion inicial y la peticion
   ++i_chr;                                     //desde programa
   
   if(i_chr==8||i_chr==16||i_chr==24){          //cada vez que se forma un fragmento inc la dir cgram
      ++i_cg;                                   //para formar otro frag
      goto inc_men_cgram;
   }
   
   if(i_chr==32)                                //cuando se forman los 4 frag retornamos o salimos
      return;
   
   goto aun_no;
}
   
entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #3 en: 10 de Abril de 2009, 18:32:16 »
si alguien descubre el problema al generar el 4,8 y 9 le agradeceria mucho que lo compartiera, creo que es por la memoria en el pic pero la verdad es solo una hipotesis.
entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #4 en: 10 de Abril de 2009, 18:35:04 »
////////////////////////////////////////////////////////////////////////////////
////programa para visualizar el voltaje en los puertos analogos A0,A1,A2 en una lcd
////////////////////////////////////////////////////////////////////////////////
#define (__PCH__)
#include <18f452.H>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT   
#use delay(clock=20000000)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)

#include <flex_lcd.c>


   
#define  sig         0x06
#define  clear       0x01
#define  cursor_no   0x0C
#define  interfaz    0x38
#define  lin1        0x85
#define  ren1        0x80
#define  ren2        0xC0

#define  m           0.0048828125 // pendiente segun ecuacion de la recta
                                  // 5/1024=m
float voltaje;                                 
int i,lcd_pos;

int16 ana;

///////////////////////////////////////////////////////////////////////////////
////subrutina que ejecuta la conversion analoga, hace el calculo del voltaje
////y envia el resultado a la lcd
///////////////////////////////////////////////////////////////////////////////
void envia_analogo_lcd(byte canal)
{

   
   delay_ms(10);
   lcd_gotoxy(1,1);
   delay_ms(10);
   lcd_putc("voltaje en a0_a2");
   set_adc_channel(canal);
   delay_us(10);
   ana = read_adc();
   voltaje = m * ana; //ejecuta ecuacion
   delay_ms(10);
   lcd_gotoxy(lcd_pos,2);
   delay_ms(10);
   printf(lcd_putc,"\%f",voltaje);
   delay_ms(10);
   
}

///////////////////////////////////////////////////////////////////////////////
////bloque principal
///////////////////////////////////////////////////////////////////////////////
void main()

{

   lcd_init();                      //inicia la lcd
   
   setup_port_a( ALL_ANALOG );      //todo el puertoA analogo
   setup_adc(ADC_CLOCK_internal );  //reloj interno del conversor   
       
   
  do{   
     
     lcd_pos=1;
     
     for (i=0;i<=2;++i){
     envia_analogo_lcd(i);
     lcd_pos=lcd_pos+6;
     }
   
  }while(true);//Bucle infinito
 
}

entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #5 en: 10 de Abril de 2009, 18:37:39 »
//por julian alvaran 06_04_09
//en la libreria flex_lcd.c se definen los pines que van al lcd
//este programa muestra un texto desplazandose hacia la derecha
//cuando se desplaza 16 posiciones empieza a desplazarce hacia la izquierda

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#define  sig         6     //0x06
#define  clear       1     //0x01
#define  cursor_no   12    //0x0C
#define  cursor_si   14    //0x0E
#define  cur_blink   15    //0x0F
#define  dezp_izq    24
#define  dezp_der    28
#define  gen_car     64
#define  lin1        133   //0x85
#define  ren1        128   //0x80
#define  ren2        192   //0xC0

#include <flex_lcd.c>

int1  z;
int   i;

void main() {
 

   lcd_init();
 
   lcd_putc("julian   techno   julian   techno    ");
   
   i=0;
   z=0;
   
   do{
   
   delay_ms(400);
   
   if(i==16)
      z=1;
   if(i==0)
      z=0;
   switch (z){
      case 0:
               ++i;
               lcd_send_byte(0,dezp_der);break;
      case 1:
               --i;
               lcd_send_byte(0,dezp_izq);break;
      }
   }while(true);
   
   

entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #6 en: 13 de Abril de 2009, 13:14:58 »
dudas, sugerencias, opiniones. les agradeceria
entre mas se, me doy cuenta que no se nada

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #7 en: 14 de Abril de 2009, 14:55:34 »
felicidades por tu proyecto terminado, y dime hay video del equipo funcionando?  :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #8 en: 15 de Abril de 2009, 14:00:19 »
gracias microcadaver por el momento no tengo video pero seguro lo hago y lo subo. la verdad es un ejemplo para estudiantes de universidad, la idea es seguir desarrollandola para implementar funciones.
entre mas se, me doy cuenta que no se nada

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #9 en: 15 de Abril de 2009, 14:01:59 »
viniendo de ti las felicitaciones es mas un halago, y motivacion suficiente, para seguir
entre mas se, me doy cuenta que no se nada

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #10 en: 15 de Abril de 2009, 16:12:36 »
Hola.

Felicitaciones por terminarlo. Alguna simulacion? o un videillo?

Saludos
El papel lo aguanta todo

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #11 en: 15 de Abril de 2009, 16:18:43 »
viniendo de ti las felicitaciones es mas un halago, y motivacion suficiente, para seguir

 :shock: ni que yo fuera que ...

bueno una idea que puedo aportar es que lo implementes con una pantalla grafica para mas adelante te hagas una tipo HP, creo que con dspic ya se podria hacer calculos que permitan graficar ecuaciones no? o estoy hablando piedras?  :-)
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado setshomaru

  • PIC12
  • **
  • Mensajes: 66
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #12 en: 17 de Abril de 2009, 11:15:06 »
muchas gracias MLO, y microcadaver, que gran halago, apenas el tiempo me de y sepa como subir archivos mayores a 300k publico las fotos, cualquier colaboracion, seria de gran ayuda. 
entre mas se, me doy cuenta que no se nada

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #13 en: 17 de Abril de 2009, 11:38:16 »
Hola.

Para subir fotos puedes usar el Imageshack, es un hosting gratuito.

Saludos
El papel lo aguanta todo

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: solucion como hacer una calculadora de varios digitos y otros ejemplos mas
« Respuesta #14 en: 17 de Abril de 2009, 12:11:31 »
para archivos documentos etc puedes usar 4shared.
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com