El sistema esta basado en un microcontrolador PIC16F883, pero podría ser cualquier otro, básicamente se elige este porque el costo es reducido y tiene una cantidad de pines que nos permitirá interconectar todo sin problemas.
El sistema funciona con oscilador externo (no es critico porque el reloj en si sera externo entonces no tenemos una necesidad precisa en el microcontrolador, por ende lo podremos poner como oscilador interno sin problemas.
El corazón de este proyecto es un RTC (Reloj en tiempo real) en base al DS1302, pero podríamos usar cualquier otro RTC, sinceramente use este porque lo tenia a mano.
Este RTC tiene 3 pines de datos, pero en realidad usaremos 2 como dato y 1 como sincronismo que es el que nos entregara un pulso cada 1s exactamente.
Este RTC cuenta con un oscilador a cristal de 32768Hz y una pila de 3V de backup para que el sistema siga en hora aunque apaguemos el circuito.
Los 6 displays están en paralelo (en cuanto a los segmentos) y controlaremos el encendido de cada uno de forma independiente con el común de cada uno.
En este caso se utilizan display cátodo común, pero podríamos usar de ánodo común, es lo mismo ya que en el firmware tenemos que invertir los bits del puerto que genera el numero nada mas.
En mi caso lo ideal es usar 3 displays dobles ya que vienen interconectados, digo de usarlos así para separarlos por HH MM SS mediante dos leds redondos quedando HH : MM : SS, pero podríamos dejarlo sin los dos puntos y el resultado sera el mismo, empleando display triples o cuádruples, también podemos hacerlo con display simples pero tendremos que cablear mas o realizar un PCB mas complejo.
El proceso de muestra en los displays es multiplexado, para ello usamos el timer0 y en el elegimos el display a activar y el dato a mostrar en ese display, es decir, activamos display 1, mostramos dato de display 1, activamos display 2 y mostramos el dato del display 2, así sucesivamente para los 6 displays de una forma muy rápida que a la visión aparecen los 6 dígitos encendidos cada uno con su valor correspondiente.
Luego definimos un vector donde pondremos los 10 valores posibles de los display del 0 al 9, y este vector sera el que llamaremos continuamente para elegir los valores a mostrar.
Luego tendremos la configuración del timer y del microcontrolador en si y por ultimo la función principal que sera la que realiza la repetición de proceso.
En esta función principal tendremos 3 etapas:
1) El if del botón en pin RC5, este botón configura los minutos del reloj, es decir, cada vez que presionemos este botón se incrementara en una unidad el minutero, si mantenemos presionado se incrementara automáticamente, por cada incremento realiza la actualización al DS1302 mediante la función rtc_set_datatime();
2) El if del botón en pin RC4, este botón configura las horas del reloj, es decir, cada vez que presionemos este botón se incrementara en una unidad las horas, si mantenemos presionado se incrementara automáticamente, por cada incremento realiza la actualización al DS1302 mediante la función rtc_set_datatime();
3) El resto del código funcionara siempre que no estén presionados los botones de hora o minuto, este ultimo bloque realiza la función rtc_get_time(); donde toma el tiempo que va contando el DS1302 y lo guarda en las tres variables de su argumento HH, MM y SS, luego estas tres variables las separaremos en unidades y decenas mediante la división por 10 y el resto de esa división, por ultimo tomaremos las 6 variables correspondientes a cada dígito y la enviaremos a la función timer0_mux() para que se actualice en los displays.
La función rtc_get_time() como se puede ver se ejecutara casi a tiempo de proceso del microcontrolador pero no cambiara su valor hasta que el DS1302 lo decida, es decir el segundero se actualizara cada un segundo por mas que llamemos a la función rtc_get_time() cada 1us, por ello no es necesario usar un cristal externo en el microcontrolador y podremos utilizar el interno del mismo.
- #include <16F883.h>
- #FUSES NOWDT
- #FUSES XT
- #FUSES MCLR
- #use delay(clock=4000000)
- #define RTC_RST PIN_C0
- #define RTC_SCLK PIN_C1
- #define RTC_IO PIN_C2
- #include <DS1302.C>
- #int_timer0
- void timer0_mux(int8 horD, int8 horU, int8 minD, int8 minU, int8 segD, int8 segU){
- output_a(0b00000001);
- output_b(horD);
- delay_ms(3);
- output_a(0b00000010);
- output_b(horU);
- delay_ms(3);
- output_a(0b00000100);
- output_b(minD);
- delay_ms(3);
- output_a(0b00001000);
- output_b(minU);
- delay_ms(3);
- output_a(0b00010000);
- output_b(segD);
- delay_ms(3);
- output_a(0b00100000);
- output_b(segU);
- delay_ms(3);
- set_timer0(0);
- }
- int valorDisp[10]={0b00111111,0b00000110,
- 0b01011011,0b01001111,
- 0b01100110,0b01101101,
- 0b01111101,0b00000111,
- 0b01111111,0b01101111};
- int8 horU, horD, minU, minD, segU, segD, HHSet, MMSet, HH, MM, SS;
- void main(){
- setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
- set_timer0(0);
- enable_interrupts(INT_TIMER0);
- enable_interrupts(GLOBAL);
- while(TRUE){
- if(input(PIN_C5)==1){
- MMSet = MMSet + 1;
- if(MMSet > 59)
- MMSet = 0;
- minD = MMSet/10;
- minU = MMSet%10;
- timer0_mux(valorDisp[horD], valorDisp[horU], valorDisp[minD],
- valorDisp[minU], valorDisp[0], valorDisp[0]);
- rtc_set_datetime(0,0,0,0,HHSet,MMSet);
- delay_ms(200);
- }
- if(input(PIN_C4)==1){
- HHSet = HHSet + 1;
- if(HHSet > 23)
- HHSet = 0;
- horD = HHSet/10;
- horU = HHSet%10;
- timer0_mux(valorDisp[horD], valorDisp[horU], valorDisp[minD],
- valorDisp[minU], valorDisp[0], valorDisp[0]);
- rtc_set_datetime(0,0,0,0,HHSet,MMSet);
- delay_ms(200);
- }
- rtc_get_time(HH,MM,SS);
- horD = HH/10;
- horU = HH%10;
- minD = MM/10;
- minU = MM%10;
- segD = SS/10;
- segU = SS%10;
- timer0_mux(valorDisp[horD], valorDisp[horU], valorDisp[minD],
- valorDisp[minU], valorDisp[segD], valorDisp[segU]);
- }
- }
En cuanto al circuito podremos ver que es muy simple, el microcontrolador, los 6 displays, el RTC y por ultimo los transistores del multiplexado que en este caso los tengo representados por compuertas NOT para la simulación pero estoy usando 2N3904 con una resistencia de 2k2 en su base.
Podremos utilizar el pin de sincronismo del DS1302 para activar un transistor extra y este puede activar los leds separadores de dígitos para que se de el aspecto HH : MM : SS, pero también puede quedar fijo como en algunos relojes.
Hola buen blog aprendo muchas cosa gracias.solo un par de preguntas no entiendo esta parte del codigo
ResponderBorrartimer0_mux(valorDisp[horD], valorDisp[horU], valorDisp[minD],
valorDisp[minU], valorDisp[segD], valorDisp[segU]);
Podrias explicarmela por favor
Y la otra es para ver los numeros en una matriz en vez de un display supongo que solo habria que cambiar la parte donde se ponen los datos para desplegar los numeros en los display por los de la matriz esta bien??
Gracias por tu tiempo
Hola como estas?, Gracias!
BorrarLo que hace la función timer0_mux(); es el multiplexado de los dígitos de 7 segmentos, es decir, es la que hace el barrido dígito a dígito, y en el argumento de la función le pasas los valores que queres que muestre, en la declaración de la función tenes timer0_mux(int8 horD, int8 horU, int8 minD, int8 minU, int8 segD, int8 segU), después vos la llamas en el programa como imer0_mux(valorDisp[horD], valorDisp[horU], valorDisp[minD], valorDisp[minU], valorDisp[segD], valorDisp[segU]); lo que hace es asignar cada valor de cada dígito, si queres hacer una prueba para comprender mas fácil por tramos, podes hacer imer0_mux(1, 2, 3, 4, 5, 6); y te va a mostrar (de forma fija) el numero 12:34:56 en los 6 dígitos.
Para usar una matriz tenes que hacer algunas cosas mas ya que tenes el concepto de frames por segundo, tenes que refrescar el mapa de bits de la matriz cada tanto para que no se vea y tenes que crear los caracteres o números para después llamarlos, te diría que mires alguno de mis otros post de matrices de led de 8x8 o 8x32 para tener una idea.
Saludos!
perfecto ya quedo entendido lo probe con un ds1307 y su libreria y funciono perfecto
ResponderBorrargracias
Buenísimo!, Cualquier cosa avísame!, Saludos!
Borrarcon el Ds1307 como quedaria el codigo puedes mandarme
BorrarComo seria el programa con un DS3231
ResponderBorrarHola, el núcleo del programa no cambia mucho, pero hay que hacer la biblioteca para el sensor, es decir, acá se usa la biblioteca "#include " habría que hacerla para este otro... Leer el datasheet y hacer todo el manejo de registros que requiera. Pero el programa no cambia mucho.
BorrarSaludos.
Hola seba te pido por favor si podrias mandar cuales serian las modificaciones necesarias para usarlo con el Ds1307 lo que pasa es que estuve probando con varias librerias y no me funcionan
ResponderBorrarGracias
Hola, a nivel programa no cambia casi nada, pero tendria que ver la biblioteca del 1307 para ver si funciona bien en base a lo que mencionas que no te funciona la biblioteca. En si el 1307 es i2c lo cual deberia ser sencillo de implementar hasta sin la biblioteca porque se puede acceder a los registros por el i2c directamente., pero no lo he probado, dejame ver y lo subo al post.
BorrarSaludos.
buenos dias, podrian ayudarme con la programacion para arduino
ResponderBorrarhola buenos dias queria saber la palabra de configuracion del pic
ResponderBorrarBuenas noches, me podrian pasar la libreria 16F883.h
ResponderBorrarhttps://github.com/electgpl/Firmware-Electronica/tree/master/CCS
BorrarHola lo arme, no se por que el display sale 00 63 y cuando muevo los botones parece cambiar pero se regresa a ese valor alguna sugerencia?
ResponderBorrarHola, pudiste simularlo en Proteus?, te dio algun warning la compilacion?
BorrarSi me da 2 warnings la compilacion en proteus si funciona pero en proteus da igual si dejo o no los resistores que van a 5v del DS1302 ahorita ya lo hice en PCB pero me hace cosas raras
BorrarEstoy haciendo el reloj pero no con Dispalys leds sino con unos dispositivos que se llaman tubos numitron, son visualizadores incandescentes ,le paso el circuito que arme
Borrarhttp://www.mediafire.com/file/94pavwwgs81xs1w/PCB2.pdsprj/file
Este comentario ha sido eliminado por el autor.
BorrarEl warning que sale en simulacion es "Logic contention(s) detected on net #00002." por lo que veo en internet ese warning es por corto y es en el nodo de la pata de i/o del RTC
BorrarPude armarlo en breadboard y funciono pero ahora no se que es lo que esta pasand
BorrarHola, me parece que el problema era algun tipo de ruido de mi fuente de laboratorio (hecha por mi) añadi un pequeño condensador a la entrada y parece ser que se solucioo el problema
BorrarPD quite el oscilador externo en el pic y cambie las salidas de control de los catodos par ponerlos directo sin transistor por el momento
ResponderBorrarPodrias tener una sobre carga de corriente, cuando tengas los segmentos encendidos en simultaneo, al no usar driver.
BorrarEstoy usando un PIC16F887
ResponderBorrarHaha no se que tenia pero ya, un detalle con el codigo la ultima señal de control en la linea 29 dura mas que los otros pulsos, no dura 3ms dura como 5,4 ms por la instruccion que sigue, eso provoca que el digito de las unidades de los segundos brille mas, simplemente despues de ese retardo apague todas las señales de control y listo. saludos
ResponderBorrarSi, puede ser, habria que ver bien los ciclos de demora de las instrucciones como para calcularlo bien. o usar un timer.
BorrarSaludos.
Este comentario ha sido eliminado por el autor.
ResponderBorrarHola, hiciste el reloj en grande ???, dijiste que ibas a subir el circuito, lo hiciste????
ResponderBorrarHola! Por favor dime qué compilador o versión de C estás usando. Esto funcionaría con el pic 16f873? Gracias por responder! La idea es armarlo de buen tamaño, con al menos 4 leds por segmento. Debo estudiarlo para usar drivers uln2003 y subir el voltaje de alimentacióin de los leds. Saludos desde Colombia!
ResponderBorrarHola! Por favor dime qué compilador o versión de C estás usando. Esto funcionaría con el pic 16f873? Gracias por responder! La idea es armarlo de buen tamaño, con al menos 4 leds por segmento. Debo estudiarlo para usar drivers uln2003 y subir el voltaje de alimentacióin de los leds. Saludos desde Colombia!
ResponderBorrarHola. acabo de haacer una simulacion en proteus y me sale algo raro. porque seria? quero decir que las cifras no me salen enteras.
ResponderBorraral compilar el codigo me salen dos errores:
Borrar''warring 216 ''reloj'' Line 76(1,2): intrrerupts disabled during call to prevent re-entrancy: (timer0_mux);
''warring 216 ''reloj'' Line 76(1,2): intrrerupts disabled durring call to prevent re-entrancy:(@delay_ms1):
y se trata de la ultima linea
Igual 2 advertencias
ResponderBorrar''warring 216 ''reloj'' Line 76(1,2): intrrerupts disabled during call to prevent re-entrancy: (timer0_mux);
ResponderBorrar''warring 216 ''reloj'' Line 76(1,2): intrrerupts disabled durring call to prevent re-entrancy:(@delay_ms1):
y se trata de la ultima linea
HOLA MI NOMBRE ES IRWIN.
ResponderBorrarCOMO SE LLAMA EL PROGRAMA EN DONDE CREO EL PROGRAMA
buen dia
ResponderBorraren que software fue desarroyado el programa
Dónde lo puedo adquirir
ResponderBorrar