Autor Tema: Problema con calculadora  (Leído 2399 veces)

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

Desconectado andyta

  • PIC10
  • *
  • Mensajes: 28
Problema con calculadora
« en: 14 de Junio de 2010, 13:15:21 »
Hola a todos!
Sigo haciendo mi calculadora!
Pero tengo  problemas:
1 Introduccion.- Esta es la idea, quiero hacer un menu, y quiero una introduccion, el programa se mantiene en la introduccion hasta que presiono alguna tecla del teclado y de la intro sale a otro submenu.

La forma que me idee de hacerla es con un arreglo que guarde las palabras de la intro, en el LCD se vaya mostrando la palabra que correspode a la poscicion del arreglo,cada ves que muestre una palabra pregunte si se pulso alguna tecla y aumente la posicion del arreglo.

El problema es que tengo que presionar varias veces alguna tecla para que salga de la intro, es por los delay, miestras mas pequeños sean mejor reconocen la tecla pulsada, pero necesito mostrar las letras por lo menos 250ms para que puedan leer las palabra.
Nose si me pueden recomdar algo, o si hay una mejor forma de realizar un menu.

2 recoleccion de datos.- Necesito usar numeros maximo de tre cifras, tengo un metodo para capturar los numero, pero no me funciona para numeros mayores a 255, cambio el int por el long, segun mi metodo deberia funcionar, pero no lo hace...

3.-operacion.-  no me funcionan la divicion.

Aprecio mucho todas su sugerencias, les adjunto aqui el codigo y la simulacion.
Muchas gracias de antemano....
« Última modificación: 14 de Junio de 2010, 13:17:44 por andyta »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con calculadora
« Respuesta #1 en: 14 de Junio de 2010, 14:27:03 »
¿Podrías subir el archivo del programa del menú? para simularlo...

Se me ocurre, así en el aire, que podrías usar la configuración del display para manejarlo sólo con cuatro líneas de datos, para ahorrar pines. También podrías destinar la parte alta del puerto B (RB4..RB7) sólo al manejo del teclado y habilitando las interrupciones. De esa manera cuando presiones una tecla, se generará la interrupción y podrás atender la lectura del teclado inmediatamente.

De todas maneras, viendo el archivo .C que subiste me parece que el mayor error es que inicializás el display constantemente.
La sentencia lcd_init();    //inicio LCD  la tendrías que poner antes del bloque While...
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado andyta

  • PIC10
  • *
  • Mensajes: 28
Problema con calculadora
« Respuesta #2 en: 15 de Junio de 2010, 11:12:24 »
Muchas gracias por lo del Lcd, ya lo cambie y respecto a lo de:

También podrías destinar la parte alta del puerto B (RB4..RB7) sólo al manejo del teclado y habilitando las interrupciones. De esa manera cuando presiones una tecla, se generará la interrupción y podrás atender la lectura del teclado inmediatamente.
Soy nuevita en esto del c,  :shock:¿como puedo hace eso?
Lo del menu, esta ahi en un metodo void menu()...
Mi mayor problema es lo del tamaño de las variables, como hago para usar numeros mayores a 255 y para colmo poder realizar operaciones.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con calculadora
« Respuesta #3 en: 15 de Junio de 2010, 17:58:26 »
Hace rato que no uso CCS y de hecho no lo tengo instalado, por eso es que no pude compilar tu programa para simularlo.

Para entender el tema de las interrupciones quizá te convenga leer el datasheet del integrado o buscar algo de información en este foro, que seguramente ya estará tratado y explicado mucho mejor de lo que yo podría hacerlo.

Quizá me apresuré un poco, no vi que usabas una librería para el manejo del teclado. Habría que ver en dicha librería como se maneja el tema de los puertos y si es que se puede hacer lectura del teclado haciendo uso de interrupciones. Quizá en la ayuda del CCS puedas encontrar algo.

Básicamente cuando se genera una interrupción, el programa principal se detiene y se salta a una función de interrupción. En dicha función podemos hacer varias cosas y luego retornamos al programa principal. Es muy similar a cuando uno llama a una función, sólo que en el caso de las interrupciones es el propio microcontrolador el encargado de hacer la llamada.
CCS tiene una forma muy sencilla de habilitar/deshabilitar interrupciones y también una forma muy sencilla para asignar una función diferente para cada tipo de interrupción.

Sigo leyendo el programa y encuentro...
Código: C
  1. void main(){
  2. while(true){
  3.     lcd_init();    //inicio LCD  
  4.     if(k==0){
  5.     Introduccion();}
  6.     lcd_putc("\fintro num1:\n");  //Pido que se introdusacan dos numeros
  7.     lcd_putc("intro num2:") ;  
  8.     captura(13,1);                //me captura los numero intro duciodos
  9.     cap1=e ;        
  10.     e=0;
  11.     captura(13,2);
  12.     cap2=e;
  13.     delay_ms(200);
  14.     menu();
  15.     //delay_ms(500);
  16. }
  17.     }
En lugar de hacer cap1=e y luego cap2=e, tendrías que hacer cap1=captura(13,1) y luego cap2=captura(13,2). Porque justamente definiste a la función captura para que devuelva INT
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Problema con calculadora
« Respuesta #4 en: 15 de Junio de 2010, 18:24:28 »
Hola andyta,

Intenté compilar tu programa, pero me falta esta librería: #include<kbd3x4.c>

La librería lcd2.c usa el LCD a 8bits, la librería lcd.c del mismo CCS usa el lcd a 4 bits, también existen las librerías flex_lcd, que son a 4 bits también, ojo que esto del LCD no es por programar en C, ya que en cualquier lenguaje se puede usar un LCD a 8, 4bits o por los pines que a un usuario le sea más práctico.

supongo que no haz manejado las interrupciones en C, en ASM lo haz hecho?

saludos.
.

Desconectado andyta

  • PIC10
  • *
  • Mensajes: 28
Problema con calculadora
« Respuesta #5 en: 16 de Junio de 2010, 13:33:56 »
Gracias Angelgris, ya estoy haciendo mis modificacones.
Y si, Cryn... nose por que no se me ocurrio intentar realizar mi menu usando interrupcioes... eh susado nterrupciones en asm, esta va a ser la rpimera ves que voy a usar una interrupcion en c, voy a buscar info.
Lo de la librerias del LCD es solo para ahorro de bits, ¿no es asi? (eso les he entendido  :mrgreen:) Voy a  buscar esas librerias.
Lo que sigo sin entender porqu no me genera el long para numero mayores a 255, ya cambie lo de "int Capturar" por un "long Capturar" pero sigue sin funcionar bien. A mucha prueba y error descubri que para valores mayores a 255, almacena la diferencia de valor y 256, por ejemplo, si introdusco los numero 456, en capturar de devuelve 201. en otras palabras: 456 - 256.  :shock: enves del mismo 456.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Problema con calculadora
« Respuesta #6 en: 16 de Junio de 2010, 17:47:50 »
Lo de la librerias del LCD es solo para ahorro de bits, ¿no es asi? (eso les he entendido  :mrgreen:) Voy a  buscar esas librerias.
Si, solo para ahorrar bits. Pero puedes usar un teclado y un lcd compartiendo el mismo puerto y además usar el teclado por interrupción por cambio de estado en el nibble alto del puertoB.

Lo que sigo sin entender porqu no me genera el long para numero mayores a 255, ya cambie lo de "int Capturar" por un "long Capturar" pero sigue sin funcionar bien. A mucha prueba y error descubri que para valores mayores a 255, almacena la diferencia de valor y 256, por ejemplo, si introdusco los numero 456, en capturar de devuelve 201. en otras palabras: 456 - 256.  :shock: enves del mismo 456.
me falta tu archivo kbd3x4.c para que pueda compilar y ver lo de ese problema.

saludos.
.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con calculadora
« Respuesta #7 en: 17 de Junio de 2010, 11:12:15 »
  Aquí dejo un programa que hice, en el cual corroboro que el valor que almaceno en una variable int es de 3 digitos y se corresponde con lo presionado.
  El programa está compilado con HiTech y con rutinas propias para el manejo del LCD, también manejo el teclado por interrupciones y hay funciones de delay que no son del propio HiTech.
  Fijate como está hecha la función Captura(), que sirve perfectamente para números de 3 dígitos.

  La línea que más importa es "numero= (numero * 10) + (tecla - 48);" Aclaro, tecla es el valor ascii del numero presionado, por ello le resto 48 (que es el ascii del 0)
  Básicamente lo que hace es que cada vez que se presione una tecla, se multiplica por 10 el numero anterior y se le suma el valor del número presionado.

  A ver si lo puedo explicar con un ejemplo.... inicialmente la variable numero es 0; supongamos que presionas el 5; ahora la variable numero es... (0 * 10) + (ascii del 5 - 48).. numero es 5; presionas como segunda tecla el 9; ahora numero es..
(5 * 10) +(ascii del 9 -48).. 50 + 9.. numero es 59; presionas como tercer tecla el 2; numero es.. (59 * 10) + (ascii del 2 - 48)..
590 + 2.. numero es 592.



Código: C
  1. #include <htc.h>
  2. #include "Def16f87xa.h"
  3. #include <stdlib.h>
  4.  
  5. #define _XTAL_FREQ 10000000
  6. #define PIC_CLK 10000000
  7.  
  8. #include "delayhd.h"
  9.  
  10. #include "NewLCD.c"
  11.  
  12. unsigned char presionada;
  13. unsigned char tecla;
  14. int numerocapturado;
  15.  
  16. void DelayAntiRebote(void)
  17. {
  18.   unsigned char retardo;
  19.  
  20.   for (retardo= 40; retardo > 0; retardo--)
  21.   {
  22.     DelayUs(250);
  23.   }
  24. }
  25.  
  26. void delay_2s(void)
  27. {
  28.   int retardo;
  29.  
  30.   for (retardo=8000;retardo>0;retardo--)
  31.   {
  32.     DelayUs(250);
  33.   }
  34. }
  35.  
  36. void interrupt isr(void)
  37. {
  38.   DelayAntiRebote();
  39.   PORTB= 1;
  40.   tecla= PORTB;
  41.   if ((tecla & 0xF0) != 0)
  42.   {
  43.     switch (tecla)
  44.     {
  45.       case 0b10000001: {
  46.                                              tecla= 49;
  47.                                              break;
  48.                                            }
  49.       case 0b01000001: {
  50.                                              tecla= 52;
  51.                                              break;
  52.                                            }
  53.       case 0b00100001: {
  54.                                              tecla= 55;
  55.                                              break;
  56.                                            }
  57.     }
  58.     presionada= 1;
  59.   }
  60.   else
  61.   {
  62.     PORTB= 2;
  63.     tecla= PORTB;
  64.     if ((tecla & 0xF0) != 0)
  65.     {
  66.       switch (tecla)
  67.           {
  68.         case 0b10000010: {
  69.                                                    tecla= 50;
  70.                                                    break;
  71.                                                  }
  72.         case 0b01000010: {
  73.                                                    tecla= 53;
  74.                                                    break;
  75.                                                  }
  76.         case 0b00100010: {
  77.                                                    tecla= 56;
  78.                                                    break;
  79.                                                  }
  80.         case 0b00010010: {
  81.                                                    tecla= 48;
  82.                                                    break;
  83.                                                  }
  84.           }
  85.       presionada= 1;
  86.     }
  87.     else
  88.     {
  89.           PORTB= 4;
  90.       tecla= PORTB;
  91.       if ((tecla & 0xF0) != 0)
  92.       {
  93.         switch (tecla)
  94.                 {
  95.           case 0b10000100: {
  96.                                                          tecla= 51;
  97.                                                          break;
  98.                                                    }
  99.           case 0b01000100: {
  100.                                                          tecla= 54;
  101.                                                          break;
  102.                                                    }
  103.           case 0b00100100: {
  104.                                                          tecla= 57;
  105.                                                          break;
  106.                                                    }
  107.                 }
  108.             presionada= 1;
  109.       }
  110.     }
  111.   }
  112.   PORTB= 15;
  113.   RBIF= 0;
  114.   return;
  115. }
  116.  
  117.  
  118. int captura(void)
  119. {
  120.   unsigned char digitos= 3;
  121.   int numero;
  122.  
  123.   do
  124.   {
  125.     if (presionada == 1)
  126.     {
  127.       WriteCharLcd(tecla);
  128.       numero= (numero * 10) + (tecla - 48);
  129.       presionada= 0;
  130.       digitos--;
  131.     }
  132.   }
  133.   while(digitos != 0);
  134.   return numero;
  135. }
  136.  
  137. void main(void)
  138. {
  139.   const char *presentacion= "Calculadora";
  140.   const char *mensaje= "Ingresar";
  141.   const char *mensaje1= "Numeros";
  142.   unsigned char numeroentexto[3];
  143.  
  144.   TRISB= 0b11110000;
  145.   PORTB= 15;
  146.   setup_comparator(NC_NC_NC_NC);
  147.   setup_adc(ADC_OFF);
  148.   setup_adc_ports(NO_ANALOG);
  149.   InitLcd(07);
  150.   WriteStrLcd(presentacion);
  151.   delay_2s();
  152.   ClearLcd();
  153.   WriteStrLcd(mensaje);
  154.   GotoxyLcd(1,2);
  155.   WriteStrLcd(mensaje1);
  156.   delay_2s();
  157.   ClearLcd();
  158.   enable_interrupt(INT_RB);
  159.   enable_interrupt(GLOBAL);
  160.   while (1)                                             // este seria el ciclo infinito para ingresar los numeros
  161.   {
  162.     if (presionada == 1)
  163.     {
  164.       numerocapturado= captura();
  165.       itoa(numeroentexto,numerocapturado,10);
  166.       GotoxyLcd(1,2);
  167.       WriteStrLcd(numeroentexto);
  168.     }
  169.   }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado andyta

  • PIC10
  • *
  • Mensajes: 28
Re: Problema con calculadora
« Respuesta #8 en: 17 de Junio de 2010, 13:10:45 »
gracias AngleGris, que buen algoritmo... acabo de leer tu codigo, ahora me toda hacer la prueba! Te voy a estar comentando como me fue.
Aqui te adjunto la libreria que te hace falta.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Problema con calculadora
« Respuesta #9 en: 19 de Junio de 2010, 13:17:08 »
Listo, por fin pude verlo andyta,

Tienes unos errores con los tipos de dato, porque la variable que era de resultado era de 8 bits y aunque hagas el casting, siempre se iba a ver la diferencia, que es producto de un desborde de una variable de 8 bits, o en este caso, solo está tomando los 8 primeros bits de tu suma.

En tu resta creo que el resultado tendría que ser en un signed long, 16bits con signo.

La división no compilaba porque había un error de sintaxis, debería ser %3.2f, y no %3,2f, lo he probado y da con valores de 8 bits, con mayores parece que haya algunos problemas, te tocará ver esa parte...

La parte de respuesta de tu teclado en la introducción, se puede arreglar con un ciclo for con un delay más corto y preguntando por el teclado dentro del for, repitiendo algunas veces el for, hasta llegar al tiempo que buscas para que se pueda ver los mensajes y no pasen volando, también se puede obviar el delay_ms y en el for contar muchas más veces, hasta 1000 5000, pero eso más es para calibrar en hardware real.

Creo que es todo, te adjunto tu código en el que hice algunas modificaciones y he colocado comentarios con //****** en las partes que aumenté o corregí

Espero que te sirva y puedas seguir con tu calculadora

saludos.
.

Desconectado andyta

  • PIC10
  • *
  • Mensajes: 28
Re: Problema con calculadora
« Respuesta #10 en: 23 de Junio de 2010, 10:34:29 »
 :oops: gracias... no puedo creerlo.. tantos errores... 
ya pude hacerla funcionar... gracias a todos!


 

anything