Problemas con un contador para pic16f877a

#1
Hola que tal, he buscado por muchos lados, no se si he buscado mal o no entiendo mucho el tema..
lo que pasa es que necesito programar un contador no muy normal...
La idea general es que el pic, cuente pulsos de entrada ejemplo un interruptor,
si se aprieta el interruptor 10 veces dentro de 20 seg. haga algo por ejemplo parpalee un led cada medio segundo y si se aprieta 20 veces dento de los 20 seg. parpalee el led pero cada 100 mS

ojala alguien pueda ayudarme aunque sea con la idea o algo similar a lo que necesito hacer..
confio en la experiencia de las personas que se encuentran en el foro..

saludos..Antonia
 
#2
Si es eso solo, con un pic enano te alcanza.
El problema de los contadores no es tan difícil.
Son dos: uno mide los 20 segundos y el otro cuenta pulsaciones de un botón.
El primero lo podés hacer usando los desbordes del timer0, y acumulando tiempos hasta un segundo.
El otro contador puede ser de dos formas: o leyendo constantemente el puerto (pooling) y detectando cuándo cambió de estado, o con las interrupciones (INT, o las de cambio de estado de bits de PORTB/GPIO).
Configurá bien el bit de Pull-up y asegurate de que no se te produzcan repiques en el interruptor con filtros RC de 5 a 10 ms.
Cuando el contador 1 llegue a 20, el pic se fija en qué valor está el contador 2 y decide qué hacer.
 
#3
Hola Perkan, lo que dice Alejandro Sherar igual es una buena opción.
El 16F877 tiene 3 temporizadores y dos de ellos poseen pines externos para su uso. Te puedo recomendar que uses por ejemplo al TMR0 para contar los pulsos de entrada y al TMR1 para los 20 seg, habilitas el PIN TOCKI como entrada de reloj para el TMR0, lo configuras como flanco de subida (rising) o flanco de bajada (Falling). Con lo único que deberías tener cuidado sería con el "rebote" o debounce de los switch, pero puedes poner un circuito "pasabajos" a la entrada de los pines que es una resistencia en serie y un capacitor en paralelo al PIN. Una ves que se venzan los 20seg solo checas cuanto pulsos contó el TMR0 y ejecutas la rutina adecuada.
Saludos
 
#6
solo una pregunta en q lenguaje deseas programar en c o en ensamblador, igual forma podrias explicarnos un poco mas sobre tu idea de un contador si quieres q sea interno o con un display de siete segmentos o q encienda un led, de igual forma estoy para ayudar, bueno t dejar un ejemplo en ensamblador.


PHP:
; En un display de 7 segmentos conectado al Puerto B se visualiza la cantidad leída por
; el Puerto A. Así por ejemplo si por la entrada lee "---0101" en el display visualiza "5".
;
; ZONA DE DATOS **********************************************************************

    __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
    LIST       P=16F877A
    INCLUDE  <P16F877A.INC>

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0            ; El programa comienza en la dirección 0.
Inicio
    bsf    STATUS,RP0        ; Acceso al Banco 1.
    clrf    PORTB            ; Las líneas del Puerto B se configuran como salida.
    movlw    b'00011111'        ; Las 5 líneas del Puerto A se configuran como entrada.
    movwf    PORTA
    bcf    STATUS,RP0        ; Acceso al Banco 0.
Principal
    movf    PORTA,W        ; Lee la entrada
    andlw    b'00001111'        ; Máscara para quedarse con el valor de las
                    ; entradas correspondientes al nibble bajo.
    call    Binario_a_7Segmentos    ; Convierte código binario a 7 segmentos del display.
    movwf    PORTB            ; Resultado se visualiza por el puerto de salida.
    goto     Principal

; Subrutina "Binario_7Segmentos" --------------------------------------------------------
;
Binario_a_7Segmentos            ; Tabla para display de 7 segmentos.
    addwf    PCL,F    
Tabla    retlw    3Fh            ; El código 7 segmentos para el "0".
    retlw    06h            ; El código 7 segmentos para el "1".
    retlw    5Bh            ; El código 7 segmentos para el "2".
    retlw    4Fh            ; El código 7 segmentos para el "3".
    retlw    66h            ; El código 7 segmentos para el "4".
    retlw    6Dh            ; El código 7 segmentos para el "5".
    retlw    7Dh            ; El código 7 segmentos para el "6".
    retlw    07h            ; El código 7 segmentos para el "7".
    retlw    7Fh            ; El código 7 segmentos para el "8".
    retlw    67h            ; El código 7 segmentos para el "9".
    retlw    77h            ; El código 7 segmentos para el "A".
    retlw    7Ch            ; El código 7 segmentos para el "B".
    retlw    39h            ; El código 7 segmentos para el "C".
    retlw    5Eh            ; El código 7 segmentos para el "D".
    retlw    79h            ; El código 7 segmentos para el "E".
    retlw    71h            ; El código 7 segmentos para el "F".

    END                ; Fin del programa.

de igual forma t dejo un ejemplo en lenguaje de c, el lenguaje que sea de tu agrado


// Contador 0 al 9 cada vez que pulsemos el boton y vuelta a empezar. Tener
// en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida. Cuando agregamos un boton a nuestro circuito hay que tener en cuenta
// que este dispositivo genera 'rebotes' que hay que ser eliminados para
// una correcta visualizacion en el display del digito seleccionado. Esta vez
// la eliminacion de 'los rebotes' se ha realizado mediante software.
// Cuando por el pin A0 del porta se introduce un '0' logico(low), se
// incrementa un digito en el display BCD.
//
// Conexiones: A0 -> boton
// B0 -> a
// B1 -> b
// B2 -> c
// B3 -> d
// BCD:
// d c b a NUM
// 0 0 0 0 0
// 0 0 0 1 1
// 0 0 1 0 2
// 0 0 1 1 3
// 0 1 0 0 4
// 0 1 0 1 5
// 0 1 1 0 6
// 0 1 1 1 7
// 1 0 0 0 8
// 1 0 0 1 9
//////////////////////////////////////////////////////////////////////////////////

#include <16f877a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3)
#use standard_io(A)

///PROGRAMA
void main(void)
{
char i=0; //contador para tabla BCD
int tabBCD[10]={0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0110,0b0111,0b1000,0b1001}; //BCD 0-9

set_tris_a(0xFF); //porta como entrada
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

output_b(tabBCD[ i ]); //inicializa displayBCD digito 0

for( ; ; ){ //bucle...
if(!input(PIN_A0)) //¿se ha pulsado el boton?
{
delay_ms(151); //SI -> retardo para evitar los rebotes
i++; //incremento contador indice tabBCD
if(i>9) //¿se ha mostrado digito 9?
i=0; //SI -> restaura valor indice(para mostrar digito 0)
output_b(tabBCD[ i ]); //muestra por portb digito 7 segmentos
}
} //...infinito
}
espero q t sirvan
 
Última edición por un moderador:
#7
si bueno el lo que quiero es que cuando presiono el pulsador (se pone a 1)se prenda un led y si suelto el pulsador (se pone a 0)el led se mantenga encendido.
si vuelvo a presionar el pulsador (se pone a 1) se apague y a si repetir lo mismo.

gracias por tu interes

es indiferente que puertos voy a usar
 
Última edición:
#8
Holaa disculpen me podran ayudar necesito hacer un programa en ensamblador que tenga de entrada un switch en un puerto para tener a la salida 2 display de 7 segmentos y poder representar con el switch un numero en binario y me lo presente en los display espero me aya explicado bien :confused: tengo la idea pera en samblador no soy bueno jeje si es muy dificil podrias hacerlo en C por tu tiempo Gracias

:aplauso::aplauso::aplauso::aplauso::aplauso::aplauso::aplauso::aplauso::aplauso::aplauso::aplauso:
 
Arriba