sábado, 28 de septiembre de 2013

Reloj con DS1307, 18F452 y LCD 16x2 en assembler

 Hola a todos: Les dejo un pequeño proyecto de reloj con un DS1307 para 18F452 y salida en display 16x2, se pueden ajustar el día de la semana, el mes y cada uno de los dígitos mostrados mediante dos pulsadores, uno conectado al pin RB5, llamado MODO que se utiliza para acceder a cada una de las variables y el otro conectado a RB4 llamado MAS para modificar el valor de dicha variable seleccionada, dentro de ciertos límites posibles.

 La parte de comunicación I2C está basada en el trabajo que realizó el amigo BRUNOF y que generosamente publicó en este link: Ejemplo de utilizacion del Modulo I2C del 16F877a Aunque adaptado para el micro 18F452 y con algunas modificaciones, como por ejemplo el carecer del aviso de error en la comunicación I2C y utilizar el set de instrucciones extendido de la familia 18F entre otras cosas. Adjunto el programa completo en este post.

 La inspiración, análisis y también gran parte del diseño del modulo para el DS1307 provienen de este hilo: Real Time Clock o el DS1307 desatado obra del maestro REDPIC.




Pido disculpas por la calidad del video, en el cual no se aprecia mucho detalle, pero que intenta mostrar como voy modificando la fecha y la hora mediante los pulsadores, Spielberg y Lucas pueden dormir tranquilos...



El esquema es muy simple, aunque no he realizado el mismo en un PCB, simplemente he utilizado los módulos de mi placa de pruebas casera.


 El programa Comienza inicializando puertos y variables como es normal, luego lee la memoria del DS1307 y verifica los bits de configuración del módulo y en caso de estar mal seteados los corrige para que empiece a funcionar el reloj, aparte de hacer pulsar todos los dígitos en el display para indicar que se debe ajustar la fecha y la hora. Una vez hecho esto, los números pasan a mostrarse en forma normal.
 Para elegir la variable a ajustar se debe pulsar el botón MODO. Para ajustar las variables se debe pulsar el botón MAS. Las variables ajustables son las siguientes: Día de la semana, mes, decena y unidad de fecha, de año, de hora, de minutos y de segundos. 

 Se debe tener cuidado al poner los valores ya que el DS1307 no reconoce los errores y sus contadores pueden seguir hasta valores extraños.

Descarga el programa en assembler.



lunes, 5 de agosto de 2013

Rutina en ASM para el manejo del generador DTMF HT9200A de HOLTEK

El circuito integrado HT9200 de la firma Holtek es un generador de tonos DTMF  (Dual-Tone Multi-Frequency) para el discado automático en líneas telefónicas.
El modelo "A" es controlado de modo serial mediante un microcontrolador como se muestra en la figura de ejemplo de la nota de aplicación de Holtek:

Como se puede apreciar utiliza una línea de datos serial, un Clock y una señal de habilitación (Chip Enable) hacia el microcontrolador. Además necesita un cristal del valor especificado en la figura para el oscilador interno del CI.

Para obtener el tono de discado deseado el pin CE debe estar en bajo y se debe enviar en forma serial un número de 5 bits de acuerdo al tono que deseemos discar (Ver tabla adjunta), además todo esto sincronizado con los pulsos de reloj (CLK).

Primero se transmite el bit "D0" (el bit menos significativo), hasta el bit "D4".
El CI toma el dato cuando el pulso de reloj baja, según se va en el gráfico de tiempos:



Acá les dejo la rutina para el control del integradito generador de DTMF. 

Antes de llamar a la subrutina dtmf se debe cargar el valor del dígito a transmitir en W.
en este ejemplo utilicé rb4 como terminal de clock y rb3 como dato, tiene además este integrado un terminal de CS (Chip Select) en lógica negada, osea que cuando está en uno el integrado se apaga y cuando está en cero se enciende.
En mi caso no lo utilicé ya que detiene el tono enviandole un 31 en decimal, aparte el control por el CS genera un ruido bastante molesto en la salida, espero que les sirva, saludos.


                 movlw .5                   ;en este caso envía el 5
                 call dtmf                    ;llama a la subrutina
                 call retardo_60ms      ;llama a la sub de retardo
                                                 ;para que suene unos 60ms
                 movlw .31                 ;con este número detiene la salida del tono
                                                 ;puede ser cualquier número que termine con 5 unos...
                 call dtmf                    ;lo envía
                 call retardo_40ms      ;suponiendo que enviamos otro dígito
                                                 ;tiene que haber un tiempo con silencio
                                                 ;entre dígito y dígito.
.
.
.
.
.

dtmf            movwf digito            ;carga el número a enviar en dígito
                  movlw d'5'                ;carga el contador en 5
                  movwf contador        ;va a contar cinco veces
                  bsf portb,rb4             ;se asegura que el pulso del clock esté en uno, en este caso es rb4
dtmf_bucle  bsf portb,rb3             ;saca el dato a transmitir por rb3
                  btfss digito,0             ;si el bit a transmitir es uno lo deja como está
                  bcf portb,rb3             ;si no lo pone en cero
                  bcf portb,rb4             ;flanco de bajada del clock, transmite el bit
                  nop                          ;el tiempo de retardo es 5 uS
                  nop                          ;para una frecuencia de 100khz aprox.
                  nop                 
                  nop                    
                  bsf portb,rb4             ;sube el pulso de reloj
                  rrf digito,1                ;va rotando el bit a transmitir
                  bcf status,c               ;limpia el carry
                  decfsz contador,1      ;si llegó a cero el contador, sale del bucle
                  goto dtmf_bucle        ;Sino vuelve al bucle
                  return                      ;retorna al programa