Realizar lectura y escritura en EEPROM de un sensor

#1
Hola. ¿Qué tal, amigos? Espero que estén muy bien.

Bueno, el motivo de este tema es para pedir apoyo de su información y experiencia.

Lo que pasa es que necesito realizar el conteo de revoluciones de un motor, pero para esto se necesitan guardar el número de vueltas que realiza dicho motor, el numero de ciclos
Es decir, gira izquierda y gira derecha = a un ciclo, un botón para guardar ambos datos y el de inicio.
Posteriormente por medio de un sensor, detectar las vueltas y detenerse cuando termine los ciclos deseados.
Ésto sólo se mostrará en 2 displays de 7 segmentos, pero lo más critico es que solo se debe realizar en un PIC16F84A. :cry:
Aunque se tiene la opción de que el contador se quede en un microcontrolador y el control en otro, pero no hallo como hacer la comunicación de ambos microcontroladores.

Solo he podido hacer que se guarden los datos como un simple contador, pero no he podido hacer el inicio del conteo y demás.

Estoy trabajando en PIC C Compiler de CCS, pues es en donde más he practicado.

Les comparto lo poco que he desarrollado.

Por su atención, muchas gracias.
 

Adjuntos

Última edición por un moderador:
#2
Posteriormente por medio de un sensor, detectar las vueltas y detenerse cuando termine los ciclos deseados.
Ésto sólo se mostrará en 2 displays de 7 segmentos, pero lo más critico es que solo se debe realizar en un PIC16F84A. :cry:
Sí que es bastante problema tener que usar un PIC muy limitado.
Al tener sólo un timer de 8 bits las cosas se complican, ya que usando dos timers tendrías el problema resuelto.

El problema es que la multiplexación de los displays se verá afectada por la rutina de conteo.
Esta rutina debe ejecutarse libremente, y al estar anidada, cuando se usan retardos, la conmutación se detendrá y eso ocasionará molestos destellos en la visualización.

Quiero suponer que usarás sensores en lugar de pulsadores.
Así que se me ocurre que puedes realizar el conteo por el pin T0CKI (Entrada de reloj del Timer 0)
y lo demás lo tendrás que realizar por poleo pero sin usar retardos.

Observaciones de programa y diseño:
En la rutina que nombras; "EXT_isr" que es en donde realizas las tareas con la EEPROM, por el nombre que le das, parece tratarse de un servicio de interrupción externa.
Pero para que funcione como servicio de interrupción, debe estar precedida por #INT_EXT
De otra forma, se comportará como una subrutina cualquiera que deberá ser llamada.

Algo importante:
Si esta rutina de servicio de interrupción externa estuviera en funcionamiento, se ejecutaría constantemente.
Ésto pasaría porque tienes conectado el pin RB0 al decodificador 7447.

También debes aumentar la velocidad de conmutación de los displays y ejecutar la simulación a la misma frecuencia con la que trabajará el microcontrolador.
Cuando simulas, debes hacerlo a baja frecuencia para no sobrecargar al simulador, a 1 o 4 MHz está bien.
Pero tanto programa como simulación deben tener la misma velocidad.
Ya cuando realices el circuito físicamente, entonces compilas con la frecuencia normal de operación.
 
#3
yo hice este display con un 16f628, utiliza timers "sencillos" para otras funciones...y solo utiliza 3 pines del pic.


el display lo hice serial y no es por barrido, si te sirve busco el esquema (porque no recuerdo donde esta XD), si no te sirve asi lo dejamos.

el codigo esta en basic pero esta muy sencillo migrarlo a C para un 16f84A
 
Última edición:
#4


yo hice este display con un 16f628, utiliza timers "sencillos" para otras funciones...y solo utiliza 3 pines del pic v=ZhiQpook1E8[/url]

el display lo hice serial y no es por barrido, si te sirve busco el esquema (porque no recuerdo donde esta XD), si no te sirve asi lo dejamos.

el codigo esta en basic pero esta muy sencillo migrarlo a C para un 16f84A
Y se guardan los valores en la eeprom?? Disculpa me podrias compartir tu programa para apoyarme un poco y ver si puedo pasar a c porfa??



Sí que es bastante problema tener que usar un PIC muy limitado.
Al tener sólo un timer de 8 bits las cosas se complican, ya que usando dos timers tendrías el problema resuelto.

El problema es que la multiplexación de los displays se verá afectada por la rutina de conteo.
Esta rutina debe ejecutarse libremente, y al estar anidada, cuando se usan retardos, la conmutación se detendrá y eso ocasionará molestos destellos en la visualización.

Quiero suponer que usarás sensores en lugar de pulsadores.
Así que se me ocurre que puedes realizar el conteo por el pin T0CKI (Entrada de reloj del Timer 0)
y lo demás lo tendrás que realizar por poleo pero sin usar retardos.

Observaciones de programa y diseño:
En la rutina que nombras; "EXT_isr" que es en donde realizas las tareas con la EEPROM, por el nombre que le das, parece tratarse de un servicio de interrupción externa.
Pero para que funcione como servicio de interrupción, debe estar precedida por #INT_EXT
De otra forma, se comportará como una subrutina cualquiera que deberá ser llamada.

Algo importante:
Si esta rutina de servicio de interrupción externa estuviera en funcionamiento, se ejecutaría constantemente.
Ésto pasaría porque tienes conectado el pin RB0 al decodificador 7447.

También debes aumentar la velocidad de conmutación de los displays y ejecutar la simulación a la misma frecuencia con la que trabajará el microcontrolador.
Cuando simulas, debes hacerlo a baja frecuencia para no sobrecargar al simulador, a 1 o 4 MHz está bien.
Pero tanto programa como simulación deben tener la misma velocidad.
Ya cuando realices el circuito físicamente, entonces compilas con la frecuencia normal de operación.
muchas gracias disculpa entonces me recomiendas utilizar otro micro como el 16f628 o se podra realizar todo eso en 2 f84 como había comentado?



Y bueno si utilizare botones para seleccionar las vueltas necesarias las cuale seran sensadas una ves q realice el conteo se detendra y realizara otra cuenta de vueltas pero al lado contrario generando un ciclo de trabajo y asi trabajar los ciclos necesarios ya guardados
 
Última edición:
#5
Claro que es mejor usar un PIC16F628/A porque cuenta con 3 timers, 2 de 8 bits y uno de 16 bits.
Éste PIC es muy superior al 16F84A porque cuenta con varios módulos que también te pueden servir.
Pero mencionaste que sólo lo podías hacer con el PIC16F84A.

Con el 16F628/A ya no necesitas utilizar dos microcontroladores.
Y si lo quieres hacer con dos 16F84A, también se puede y los comunicas usando RS-232 por software.
 
#6
Ok intentare realizarlo con el 628 solo tengo una duda es que no logro hacer que despues de guardar el numero de vueltas como lograr que comience el conteo en automatico
 
#9
Actualmente estoy realizando unas practicas con displays de 7 segmentos multiplexados.
Éstas son las funciones que estoy utilizando por el momento, te las dejo por si te sirven.
El tiempo por dígito es de 1 ms.
PHP:
//Funciones de control para 3 digitos con display de 7 segmentos a led. 
//Retorna valor: Byte
//Numero a mascara tipo digito display 7 segmentos
//_get7seg, retorna la mascara de los segmentos a activar
Int8 _get7seg(Int8 _numero) {
   Const Int8 _mascara[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x80};
   Return _mascara[_numero];
}
//_get7seg1, retorna la mascara de los segmentos a activar con punto decimal
 Int8 _get7seg1(Int8 _numero) {
   Const Int8 _mascara[] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef, 0x80};
   Return _mascara[_numero];
}
//Selecciona el Display de 7Segmentos activo e imprime el digito.
//_numero a imprimir, _power = 1 display on
Void _Display(Int16 _numero, int1 _power) {
   Int8 i = 1;
   Static Int8 n = 0;
   Int8 _digito = 0;  
   
   If (_numero > 999) _numero = 999; //Acota superior el numero
   //Descompone en digitos para numero >= 100
   If (_numero >= 100) { 
      If (n == 2) _digito = _numero / 100;
      else If (n == 1) _digito = ((_numero / 10) % 10);
      else If (n == 0) _digito = _numero % 10;
   }
   else If (_numero >= 10) { //Descompone en digitos para numero >= 10
      If (n == 1) _digito = _numero / 10;
      else If (n == 0) _digito = _numero % 10; 
   }
   else If (n == 0) _digito = _numero; //Extrae el digito para numero < 10
   
   If (n == 1) PORTB = _get7seg1(_digito); //Asigna la mascara del digito con punto decimal 
   else PORTB = _get7seg(_digito); //Asigna la mascara del digito sin punto decimal

   If (_power == 0) i = 0; //Apaga el display
   PORTA = i << n; //Selecciona el digito a iluminar.
   n++;
   if (n > 2) n = 0; //Numero de digitos +1
}
 
Última edición por un moderador:
Arriba