Problema al leer pulsos con PIC

Que tal, estoy iniciando en el mundo de la programacion de micros (18F452 de microchip), programo en C. Pero he tenido problemas al hacer un programa que lea un "pulso" y aumente un contador. El pblema está en que si esta el uno sigue contando y solo deberia incrementar una sola ves hasta que vuelva a cambiar de estado. Espero que alguien me pueda ayudar. El programa lo hago en C
 
Hola, en C no te puedo ayudar, pero simplemente si utilizas:

Si pin=1 entonces a=a+1
etiqueta:
Si pin=1 then etiqueta
.....
.....
.....
De ese modo, te aseguras que mientras tengas a la entrada un 1 no seguirá contando sin antes haber pasado por cero. No sé si te valdrá lo que te he comentado.
Gracias y saludos.
 
Hola, no se mucho de los pic 18F, por lo que ví en el datasheet, tiene tres pines para interrupciones externas (RB0, RB1, RB2). Yo he programado 16F hasta ahora.. y tienen una interrucción externa. Con ella se puede hacer por ejemplo que entre a una función donde se haga el a=a+1; solo cuand hay un flanco ascendente o descendente. O sea cuenta flancos y no estados altos que pueden durar mucho tiempo y por ende la cuenta seguiría incrementandose el tiempo que este esté en alto.

Salu2..
 
Deves de hacerlo como te indica loren, pero en el caso de utilizar pulsadores para aplicar los pulsos tienes que tener muy encuenta los rebotes producidos a la conexion y desconexion.
Puedes eliminarlos con un condensador o bien mediante programacion, añadiendo un retardo de 20mseg
 
Última edición:
Hola, no se bien como sea el proyecto en si.. pero soy más partidario de las interruciones, porque por ejemplo si tu programa a demás de tener que contar pulsos tiene que ir prendiendo led's que no tengan que ver con el conteo de pulsos (por ejemplo un led titilando que indique que el micro está funcionando y ejecutando instrucciones), podria caer uno de los pulsos en el momento en que se está prendiendo o apagando el led y se perdería.. en cambio con la interrucción esté haciendo lo que esté haciendo el pic, deja de ejecutar la instrucción y atiende a la interrucción, incrementando el contador de pulsos. Si no tenes que hacer nada más que contar los pulsos el programa que dice loren está bien.. pero cuando hay que hacer más cosas se complica (me puse a simularlo en proteus y perdía muchos pulsos con solo ponerle un led titilando como te decía). Y lo que tiene mucha razón pepechip es que si la fuente de los pulsos es un pulsador ponele un delay de 20ms o un capacitor, a un compañero le trajo muchos problemas el tema de los rebotes de los pulsadores.

Salu2..
 
Hola mira yo hace días hice la misma pregunta pero a ver si me ayudaban en PicBasic pero al final después de buscar un buen rato encontré algo mira el pic que yo utilice fue un 16F876a si te bajas el datasheet y buscas en el OPTION_REG en ese registro puede decirle al pic que flanco es el que quieres utilizar, al final te coloco un ejemplo en basic:

optionreg.jpg


alli dice que el bit 6 INTEDG: Interrupt Edge Select bit
1 = Interrupt on rising edge of RB0/INT pin ' falco de subida
0 = Interrupt on falling edge of RB0/INT pin ' flanco de bajada

ahora bien para ver cuando cambia el flanco tienes que ver un registro de flags como lo haces solo tienes que ir a un registro que se llama INTCON

intcon.jpg


el bit 1 INTF: RB0/INT External Interrupt Flag bit
1 = The RB0/INT external interrupt occurred (must be cleared in software)
0 = The RB0/INT external interrupt did not occur

osea que si esta en 1 el bit 1 de ese registro a habido un cambio de flaco, alli dice que el registro debe ser cambiado manualmente despues deque miras, osea que despues que has mirado ese bit tienes que ponerle una parte al programa para que este se cambie a cero

aqui el ejemplo:


Define LCD_DREG PORTB
Define LCD_DBIT 4
Define LCD_RSREG PORTB
Define LCD_RSBIT 2
Define LCD_EREG PORTB
Define LCD_EBIT 3
TRISB = %00000011 ' en el puerto B coloco el pin 0 y el 1 como entradas y el resto como salidas
OPTION_REG = %10000000 ' mira que coloco el bit 6 cero osea flanco descendente
contador var byte ' Create adval to store result
contador = 0
Pause 500 ' Wait .5 second
loop:

Lcdout $fe, 1 ' Clear LCD
OPTION_REG = %10000000 'creo que esto no es necesario
pause 50
if INTCON.1 = 1 then ' mira aqui esta donde tienes que ver si la bandera cambio bit 1 del registro INTCON
contador = contador + 1
lcdout "suma de flan=", dec contador
pause 50
INTCON.1 = 0 ' mira cuando termina el programa tienes que poner tu mismo la bandera en cero
endif
Goto loop ' Do it forever
End
 
Última edición:
Digamos que es CCS C y usas WDT:

el programa viene de la deteccion del pulso, el mismo digamos que es detectado en RB0

pulsos++;
delay_ms(10); // No se si es boton o que, esto es un antirrebote
do { restart_wdt(); } while(input(PIN_B0));

Si tenes que hacer otras cosas mientras ese pulso transcurre, entonces podes usar:
a)- El contador T0CKI, o T1CKI (externos) dependiendo si pulsos sera de 8 o 16bits
b)- Interrupciones
 
Atrás
Arriba