Programa con 16F84A (contador de piezas)

Hola a todos!

En primer lugar espero no haber metido la pata creando el post aqui indevidamente, no sabia donde meterlo

Estoy algo desquiciado con un programilla que estoy haciendo con el 16F84, he visto por aqui que alguno tambien tiene problemas con cosas parecidas y bueno, me ha tanquilizado un poco jeje.

El caso es que tengo que hacer un contador de miles de piezas. Se trata de un octoacoplador, cuyos impulsos los cuenta el TMR0 pero dividiendo dicho contaje entre un valor del divisor de frecuencia o preescaler interno.

El valor entre el que divide el preescaler el numero de impulsos depende del estado logico que introducen los interruptores I1 I2 e I3 segun esta tabla:

I2---- I1---- I0 ---- Factor de division
0---- 0 ---- 0 ---- 1:2
0 ---- 0 ---- 1 ---- 1:4
0 ---- 1 ---- 0 ---- 1:8
0 ---- 1---- 1 ---- 1:16
1 ----0---- 0 ---- 1:32
1 ---- 0 ----1---- 1:64
1 ---- 1 ---- 0 ---- 1:128
1 ---- 1 ---- 1 ---- 1:256

Aqui es donde me empiezo a liar, el contaje se tiene que visualizar en diodos led y estoy absolutamente perdido. Si alguien me pudiera echar una mano o enseñarme un poco que camino tengo que seguir se lo agradeceria mucho porque no tengo ni la menor idea :(

El programa lo tengo que hacer con el simupic (sim84)

Gracias de antemano chicos
 
Primero, estás usando el pic16f84 o el pic16f84a?.
Bueno, creo que lo más eficiente sería que utilizaras el TMR0, en modo contador asíncrono para que cuente los pulsos en la pata RA4 (ver figura 5-1 hoja de datos pic16f84a).
Esto siempre y cuando no precises el TMR0 para otra cosa.
Suponiendo que efectivamente usas el TMR0 para eso, se puede cambiar el pre-escalador (bits PS2, PS1, PS0) por software mientras el temporizador está funcionando (como dice en la sección 5.2.1), y están disponibles todas las escalas que especificás (desde 1:1 hasta 1:256 en múltiplos de 2).
Entonces tu programa lo que tiene que hacer es, primero, inicializar los puertos de entrada/salida, el contador TMR0.
Luego, en el lazo infinito del programa, chequeás las entradas I0, I1, I2; si cambió respecto del valor previo configurás el pre-escalador de TMR0, y actualizás las salidas (siempre) con el valor de la cuenta TMR0.
Me imagino que utilizarás display 7 segmentos para visualizar la cuenta, tendrías que aclarar cuántos son.

No he usado el simupic, solo quería darte alguna idea básica de como encarar la programación.
Saludos
 
Hola!

Bueno la verdad es que me has ayudado algo, hasta ahora he conseguido hacer esto:

org 0x00 ;Vector de Reset
goto Inicio
org 0x05

List p=16F84 ;Tipo de procesador
include "P16F84.INC" ;Definiciones de registros internos

org 0x00 ;Vector de Reset
goto Inicio
org 0x05 ;Salva vector de interrupción

Inicio clrf PORTB ;Borra los latch de salida
bsf STATUS,RP0 ;Selecciona banco 1
clrf TRISB ;Puerta B se configura como salida
movlw b'00011111'
movwf TRISA ;RA0-RA4 entradas
movlw b'00111111'
movwf OPTION_REG ;Preescaler de 256 para el WDT. El TMR0 evoluciona a
;cada flanco descendente aplicado por RA4
bcf STATUS,RP0 ;Selecciona banco 0

Me sabrian decir si voy bien? me estoy volviendo loco

El display es de 7 segmentos. Muchas gracias por todo
 
Bueno bueno, no es para volverse loco, tranquilidad que todo se aprende.

Te recomiendo usar seleccionar el banco de registros la macro banksel.
En vez de andar buscando a qué banco corresponde tal registro, ponés banksel TRISB por ejemplo, y ya te fija los bits en el registro de estado en forma automática.

Otra cosa, el display 7 segmentos es de ánodo común o cátodo común?.
Para manejarlo lo podés hacer directamente desde el microcontrolador, o lo podés manejar a través de un registro de desplazamiento (74LS164 por ejemplo), o un decodificador BCD a 7 segmentos. Usar un registro de desplazamiento te da ventaja de necesitar solo dos pines del PIC para manejar el display de 7 segmentos, en contraparte con los 7 pines que precisarías usar si lo manejás desde el pic directamente. El decodificador de 7 segmentos sería una opción intermedia (usas 4 pines del pic para manejar el display).
Esas son las opciones para el manejo del display, por lo menos las que se me ocurren por ahora.

Bien, vamos ahora a tu código, veo que configuraste bien las entradas/salidas, una vez que decidas como vas a manejar el display 7 segmentos vas a tener incluir la configuración de salidas correspondiente.

En cuanto al TMR0, yo decía de usar el escalador para el TMR0 y no para el watchdog. Si querés que el escalador te quede para el watchdog, entonces vas a tener que hacer la división por software, que no es difícil (en vez de tomar la cuenta como el valor de TMR0 en forma directa, solo tomás los 7,6,5, etc bits más significativos para obtener división por 2, 4, 8, etc).

Bueno, entonces te queda esa decisión también, aparte de como manejar el display.
Ya te podrías ir armando un esquemático del circuito y postearlo para la próxima, y tener una idea de cómo manejarías la lectura de las entradas y la escritura de las salidas (es decir, lo que va dentro del bucle infinito).

Saludos
 
Hola:

El display supongo que es de anodo comun pero no estoy seguro. El escalador prefiero usarlo para el TMR0 pero no se muy bien como hacerlo. Muchas de estas cosas me suenan a chino aun, no se por que me esta costando tanto entender todo esto la verdad es que no se me dan mal estas cosas pero la mitad de lo que me preguntas no sabria que contestarte y me siento un poco idiota :)

Entonces banksel TRISB donde lo sustituyo? si me pudieses modificar la configuracion que puse arriba lo entenderia mucho mejor (no pretendo que me hagas todo el programa tampoco). Siento molestarte tanto es que estoy muy perdido, pero gracias

Saludos
 
Ok, asignación del escalador, página 27 de la hoja de datos del pic16f84:

The prescaler is shared between the Timer0 Module
and the Watchdog Timer. The prescaler assignment is
controlled, in software, by control bit PSA
(OPTION_REG<3>). Clearing bit PSA will assign the
prescaler to the Timer0 Module. The prescaler is not...

O sea, si PSA es = 1 va al watchdog, si es = 0 va al TMR0

el uso de banksel:

Código:
Inicio clrf PORTB ;Borra los latch de salida
bsf STATUS,RP0 ;Selecciona banco 1
clrf TRISB ;Puerta B se configura como salida

en vez de eso, ésto:

Código:
Inicio clrf PORTB ;Borra los latch de salida
banksel TRISB ;Selecciona el banco que corresponde a TRISB
clrf TRISB ;Puerta B se configura como salida

El programa tendría una estructura como la siguiente:
Código:
Inicio:
  configurar puertos (cuales son entradas y cuales son salidas)
  configurar TMR0 como contador con prescaler
Lazo:
  prescaler TMR0 = entradas I0, I1 e I2
  escribir salidas para manejar el display
  saltar a Lazo
FIN

Para saber si es de ánodo común o cátodo común, con el tester en modo probador de diodos probá entre la pata del medio (de cualquiera de las dos filas de pines del display) y cualquier de las otras patas de la fila. Probá en ambos sentidos hasta que el tester te de una lectura. Cuando te da una lectura deberías poder ver un segmento (o el punto decimal) que se enciende, aunque por ahí muy levemente.
Entonces, si te da la lectura con el común puesto en la pata del medio, es un display de cátodo común, si te da lectura con el vivo (pinza roja digamos) puesto en la pata del medio, es de ánodo común.

Viendo tanta confusión, creo que lo más simple va a ser que uses un decodificador BCD a 7 segmentos para manejar el display (si es uno solo).
Si buscás con el google vas a encontrar un montón de esquemas de como manejar un display de 7 segmentos, leyendo un rato te vas a sacar todas las dudas respecto a eso.

Saludos
 
Hola de nuevo:

Hice lo que me dijiste, es un display de catodo comun. Entonces:

Inicio ------clrf PORTB ;Borra los latch de salida
banksel TRISB ;Selecciona el banco que corresponde a TRISB
clrf TRISB ;Puerta B se configura como salida

Y despues

movlw b'00011111'
movwf TRISA ;RA0-RA4 entradas
movlw b'00111111'
movwf OPTION_REG ;Preescaler de 256 para el WDT. El TMR0 evoluciona a
;cada flanco descendente aplicado por RA4
bcf STATUS,RP0 ;Selecciona banco 0

Hasta aqui habiamos llegado verdad? ahora para el tema de las salidas del display se podria hacer algo asi?

Loop ------ movf PORTA,W
andlw b'00001111' ;Lee las entradas RA0-RA3
xorlw b'11111111' ;Complementa el valor leído (el TMR0 es ascendente)
addlw .1
movwf TMR0 ;Carga el TMR0 con el valor leído
bsf PORTB,1 ;Activa la entrada de pulsos a contar
bcf INTCON,T0IF ;Repone el flag del TMR0

 
Yo no entiendo tu duda. Vos queres mostrar los conteos que realizas median R4, y hacerlo por interrupción, no le veo ninguna complicación.
Lo que hace tu programa es desplegar todo el tiempo, el valor de los digitos que conforman la cantidad de numeros a mostrar, es decir, unidad, decena, centena, unidad_de_mil, etc.
En la interrupción, incremenas todos los contadores, y en caso de que no exista moviemiento alguno en la cuenta, rellenas con NOPs, para tener siempre la misma cantidad de ciclos por operación y hacerlo lo más estable y simétrico posible. Lo demás son operaciones con registros y configurar bien el TMR0 para su funcionamiento como contador.

Podés mirar esta nota de aplicación de Pablin

http://www.pablin.com.ar/electron/circuito/mc/contador/index.htm

Bien sencillo.

Saludos
 
Bueno despues de todo he conseguido hacer el programa (y entenderlo que era lo mas importante)

Despues de ensablar el programa me daba unos cuantos errores que he conseguido solucionar (con la ayuda de un compañero mio tambien)

Muchas gracias por todo lo que me habeis ayudado, gracias Ardogan.
 
Ok, me alegra que lo hayas solucionado. Cuando tenía que empezar a diseñar algo también me pasaba algo similar, no sabía por donde arrancar, como seguir, estaba inseguro porque no tenía experiencia (sigo sin tenerla en muchas cosas, pero ya no lo veo como una traba), pasaba del diseño del soft al diseño del hard al diseño del programa para la PC y siempre iba y venía sin terminar de completar nada, muchas me iba en detalles que sumaban horas de trabajo pero ningún resultado que lo justifique.
En fin, esos errores no creo que los vuelva a cometer, aunque sí sería una buena idea de un post con pautas generales para encarar un proyecto genérico, pasando por el diseño, determinar si es un producto redituable o no, fabricación, comercialización, etc.
Saludos
 
hola a todos una consulta, estuve haciendo unos ejercicios con el timer del pic 16f84a pero me queda una duda, al configurar el pin 4 para recibir pulsos de conteo, esta automaticamente queda configurada como entrada (RA4) o se tiene que usar antes la intruccion trisa para poner el pin RA4 como entrada?

ademas sobre la pagina de pablin que citaron , con que programa se emsamblan? porque cuando uso el mplab o el pic simulation ide me da una lista de errores apesar de incluirle en la cabecera el list e include, gracias de antemano por ambas respuestas
 
hola yo tengo una pregunta, estoy diseñando un temporizadr con un pic16f84 y queria saber si al pin RA4 podia usarlo como salida para activar un rele. y si cualquier pin RA puedo configurarlo como salida independiente de los demas.

muchas gracias.
 
Atrás
Arriba