Autor Tema: HELP, contador por medio de RB0 o TMR0, ayuda please!!  (Leído 5468 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado huacaracho

  • PIC10
  • *
  • Mensajes: 3
HELP, contador por medio de RB0 o TMR0, ayuda please!!
« en: 01 de Febrero de 2009, 15:14:43 »
Hola amigos de este gran foro. ME gustaría recibir ayuda dado que soy novato en el tema de programación de PICs por medio de PIC C de CCS y simulando en proteus 7.2. Estoy tratando de hacer un simple programa que lea los pulsos de entrada por medio del pin RB0. Hice que cuente 5 pulsos en la entrada RB0 y por cada 5 pulsos de entrada genera 1 de salida. El problema es que el programa funciona perfecto para frecuencias bajo los 100 khz pero cuando aumento a 1mhz por ejemplo, no funciona o mejor dicho cuenta muchos más pulsos.

Pregunta del millón, ¿cual es el error que estoy comentiendo? :lol:

El código es el siguiente ( :-/ adjunto envío un archivo RAR con el codigo de PICC y el diseño en proteus por si a alguien le interesa o si alguien me puede guiar un poco para ver cual es el error que cometo)

/*
INTERRUPCION DEL PINRB0
UNA VEZ QUE SE INTERRUMPE EN EL PIN RB0 SE DETIENE EL PROGRAMA PRINCIPAL
Y SE SALTA A LA RUTINA EXT_ISR()
*/
#include <16f877A.h>
#include <math.h>
#fuses HS, NOWDT, PUT, NOWRT
#use delay(clock=10000000)
#BYTE trisb=0x86
#BYTE portb=0x06
#BYTE trisc=0x87                 //PUERTO C
#BYTE portc=0x07
int var=0;
#INT_EXT                         //******FUNCION DE INTERRUPCION EN RB0******
ext_isr(){
var++;
if (var==5) {
disable_interrupts(GLOBAL);     //deshabilito interrupción externa
output_bit(PIN_B1,1);
delay_us(1);
output_bit(PIN_B1,0);
enable_interrupts(INT_EXT);
var=0;
}
}

void main(){
int cont;
bit_set(trisb,0);                //RB0 como entrada
bit_clear(trisb,1);              //RB1 como salida
bit_clear(portb,1);              //apaga led en RB1
port_b_pullups(TRUE);            //activo pull up en portb


enable_interrupts(INT_EXT);      //habilito interrupción en RB0
ext_int_edge(L_TO_H);            //detección en flanco de subida
enable_interrupts(GLOBAL);       //habilitación global de interrupción
while(true){                       //LOOP INFINITO QUE ESPERA INTERRUPCIÓN

}
}

De antemano muchas gracias a todos los que mantienen este foro pues es una verdadera biblia para los que deseamos aprender cada vez mas de este interesante tema que son los PICs.

Saludos y un abrazo desde Chile a todos.

Desconectado geronimoo

  • PIC10
  • *
  • Mensajes: 34
    • Divide & Conquer
Re: HELP, contador por medio de RB0 o TMR0, ayuda please!!
« Respuesta #1 en: 01 de Febrero de 2009, 15:50:43 »
Hola!
Una interrupcion con frecuencia de 100Khz significa una interrupcion cada 10uS.
Creo que no le da el cuero a la frecuencia del pic, proba usando un cristal mayor a 10MHz.
Otro detallecito, tengo entendido que el pic mismo deshabilita las interrupciones globales cuando atiende una interrupcion, a menos que vos le digas lo contrario.
Si esto fuera asi, hay 2 lineas al vicio en la rutina de interrupcion, y si css las esta compilando y tu pic ejecutando, son un desperdicio de tiempo de proceso
#INT_EXT                         //******FUNCION DE INTERRUPCION EN RB0******
ext_isr(){
var++;
if (var==5) {
disable_interrupts(GLOBAL);     //No necesaria, el pic lo hace solo
output_bit(PIN_B1,1);
delay_us(1);
output_bit(PIN_B1,0);
enable_interrupts(INT_EXT);     //No necesaria, el pic recupera solo el estado de las interrupciones, como estaban antes de entrar en esta INT
var=0;
}
}

Si estoy pifiado or favor corrijanme
Saludos!
.::GERO::.

Desconectado huacaracho

  • PIC10
  • *
  • Mensajes: 3
Re: HELP, contador por medio de RB0 o TMR0, ayuda please!!
« Respuesta #2 en: 02 de Febrero de 2009, 11:31:16 »
Gracias geronimo!!!

Sabes que estuve aplicando lo que me dices, es decir le subí la frecuencia al PIC y al final, para leer 150khz de entrada tenía que aplicar un oscilador de 40 mhz, lo cual ya supera al máximo de trabajo del pic16f877. En otras palabras, parece que no se la puede para muestrear así nomás la entrada a una frecuencia de esa indole.

¿Alguna idea de como ser capaz de contar frecuencias mas grandes con el pic?. ¿Alguna sugerencia por ahi?. Yo pensaba que quizas si se usa un subcontador o algo por el estilo en logica TTL externa quizás el pic podria interpretar una frecuencia mas alta. Algún consejo por ahí en la galaxia????


Saludos y gracias nuevamente

Desconectado geronimoo

  • PIC10
  • *
  • Mensajes: 34
    • Divide & Conquer
Re: HELP, contador por medio de RB0 o TMR0, ayuda please!!
« Respuesta #3 en: 02 de Febrero de 2009, 15:22:17 »
mmmm que probelma!
entonces l podes solucionar mediante hardware externo.
como dices puedes usar un contador que se resetee cada 5 cuentas =D
Asi usas el contador como divisor de frecuencia.
O podes usar un conversor frecuencia-tension y leer la tension con el adc del pic...
O sino podes usar el modulo CCP y capturar el ancho de un pulso, y en base a este calcular la frecuencia...
.::GERO::.

Desconectado huacaracho

  • PIC10
  • *
  • Mensajes: 3
Re: HELP, contador por medio de RB0 o TMR0, ayuda please!!
« Respuesta #4 en: 03 de Febrero de 2009, 09:33:22 »
Vale, gracias geronimo0, te pasaste nuevamente. Voy a probar con alguna cosa extra y de ahi doy los resultados. De todos modos,cualquier otra sugerencia es bienvenida. Esa es la idea del foro. :P

Desconectado jhon364

  • PIC10
  • *
  • Mensajes: 6
Re: HELP, contador por medio de RB0 o TMR0, ayuda please!!
« Respuesta #5 en: 16 de Febrero de 2009, 13:39:43 »
Holas mira recuerda que el 877 tiene un contador de 16 bits en TIMER1 lo puedes utilizar y no necesitas hardware externo....

lo unico que tienes que tener claro es q debes cargar el valor cuando lo necesites y listo el te cuenta a la velocidad q quieras por lo general son muy rapidos los de los pic.

la manera de cargarlo es la siguiente

contu=get_timer1();

si tu variable contu es de int16 para que pueda almacenar este valor

y este realiza una interrupcion cuando llegue a 65535 cuando este se desborde pero puedes jugar con esto cualquier cosa escribes como te fue y leete el datashet del micro para que veas como se configura pero si estas en CCS es así;

setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);


y la interrupcion es:

#int_TIMER1
TIMER1_isr()
{
set_timer1(0);
contu=65536;
}

y listo ya estas muestreando pulsos rapidamente es decir contando.


 

anything