Autor Tema: Timer0 a 56khz  (Leído 2620 veces)

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

Desconectado championx

  • PIC10
  • *
  • Mensajes: 22
Timer0 a 56khz
« en: 01 de Marzo de 2006, 10:59:00 »
que tal, este es el codigo que supuestamente genera una interruppcion cada 18us que es aproximadamente el periodo de una onda cuadrada de 56khz, pero no anda como deberia, alguien podria ayudarme?

#include <16f88.h>                    // Selecciona el PIC
#fuses XT,NOPROTECT, PUT, NOWDT, BROWNOUT, NOMCLR, NOLVP // Opciones de configuración
#use delay(clock=4000000)              // Velocidad del Cristal : 4 Mhz

#define led_off  output_high(PIN_A2)
#define led_on output_low(PIN_A2)


#int_RTCC                              // Interrupción por desbordamiento
RTCC_isr()
{


led_off;
delay_us(17);
set_timer0(238);

}



void main(void)
{

  setup_counters(RTCC_INTERNAL,RTCC_DIV_1);// TIMER0: Clock Interno
  enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC
  enable_interrupts(global);                 // Habilito Interrupciones
  set_timer0(238);


while (true)
   {
   led_on;
   }

}

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
RE: Timer0 a 56khz
« Respuesta #1 en: 01 de Marzo de 2006, 13:00:00 »
Prueba a hacerlo de esta manera:

Codigo:

#include <16f88.h>
#fuses XT,NOPROTECT, NOPUT, NOWDT, BROWNOUT, NOMCLR, NOLVP
#use delay(clock=4000000)

#define led_off output_high(PIN_A2)
#define led_on output_low(PIN_A2)

int1 Flag=0; // Flag que cambia cada interrupcion

#int_RTCC // Interrupción por desbordamiento
RTCC_isr() {
   
   ++Flag;
   if(Flag==1){
      led_on;
   }
   else{
      led_off;
   }
   set_timer0(252);
}

void main(void)
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);// TIMER0: Clock Interno
   enable_interrupts(INT_RTCC); // Habilito Interrupción RTCC
   set_timer0(252);
   enable_interrupts(global); // Habilito Interrupciones


   do{
   }while(true);
}



Imagino que para una frecuencia de 56 Khz el led debe estar la mitad del tiempo
encendido y la otra mitad apagado para obtener una onda cuadrada de 0.018 ms
de periodo (0.009 ms de semiperiodo) Para ello tenemos que fijar la RTCC cada
0.009 ms y que una vez salte encienda el led y a la siguiente lo apague con lo que
obtendremos el tipo y la frecuencia requeridos. Y cogiendo la calculadora vemos
que aproximadamente saltará cada 0.009 ms con un valor de contador de 252
que es lo que fijamos al inicio y cada vez que salte RTCC.

Prueba y me cuentas.



Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado championx

  • PIC10
  • *
  • Mensajes: 22
RE: Timer0 a 56khz
« Respuesta #2 en: 01 de Marzo de 2006, 21:26:00 »
gracias redpic por la respuesta, pero lamentablemente no funciona Enfurruñado mido la frecuencia y me marca algo de 7khz...



Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
RE: Timer0 a 56khz
« Respuesta #3 en: 02 de Marzo de 2006, 00:39:00 »
Amigo Championx:

Esta tarde, hora española, voy a montar la prueba en casa y como tengo osciloscopio voy a ver qué es lo que está mal. (Un poco de paciencia, que dicen es la madre de la ciencia Giño  )

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Timer0 a 56khz
« Respuesta #4 en: 02 de Marzo de 2006, 02:59:00 »
Creo que con un clock de 4MHz va a ser muy difícil obtener esa frecuencia, porque sólo la rutina de la interrupción ya ocupa más de 14 ciclos de instrucción, a los que habrá que añadir el tiempo de desborde puesto que la precarga del timer se está configurando al salir de la interrupción.

He modificado un poco el programa, reduciendo la interrupción a sólo 7 ciclos de instrucción, y poniendo el set_timer al principio.

Codigo:
#include <16f88.h>
#fuses XT,NOPROTECT, NOPUT, NOWDT, BROWNOUT, NOMCLR, NOLVP
#use delay(clock=4000000)

#define led_off output_high(PIN_A2)
#define led_on output_low(PIN_A2)

int1 Flag=0; // Flag que cambia cada interrupcion

#int_RTCC // Interrupción por desbordamiento
RTCC_isr() {
   
   set_timer0(252);
   output_toggle(PIN_A2);
}

void main(void)
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);// TIMER0: Clock Interno
   enable_interrupts(INT_RTCC); // Habilito Interrupción RTCC
   set_timer0(252);
   enable_interrupts(global); // Habilito Interrupciones


   do{
   }while(true);
}


De todas formas, lo que nos sacará de dudas, es la prueba de Diego y su envidiado osciloscopio.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
RE: Timer0 a 56khz
« Respuesta #5 en: 02 de Marzo de 2006, 13:55:00 »
Bien, bien, tre-bien ...

1º Adoptado como hijo propio la modificación de Nocturno al WinkIntC_56Khz.c
(¡Ay pájaro, pájaro, que te has sacado de la manga el output_toggle que yo no conocía)

2º Compilado con el CCS PICC PCM Versión 3.242

3º Programado sobre un PIC 16F268, montado en la ultra-famosa RRBOARD1 provista de un cristal cuarziforme de 4 Mhz, mediante el lujo de programadores GTP-USB+

4º Sondeado el PIN_A2 (tras la resistencia del Led que tengo conectado a dicha patilla) mediante el sin par Groundig MO20 cuyos ajustes son :

- t/division 50 microsegundos
- V/division 1 V
- Sonda x1

Los resultados son (si no me equivoco) :  el pulso tiene un periodo de 120 microsegundos, lo que corresponde a una frecuencia de 8.33 Khz

Conclusión : Como dice Nocturno, o ponemos un cristal mas rápido o lo tenemos mu dificil desquiciado



Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
RE: Timer0 a 56khz
« Respuesta #6 en: 04 de Marzo de 2006, 07:09:00 »
desquiciado  desquiciado  desquiciado  desquiciado  desquiciado

He conseguido los puñeteros 56Khz pero a base de frustración y encono ....

desquiciado  desquiciado  desquiciado  desquiciado  desquiciado

De todas formas he aprendido mucho de varios temas y creo interesante
publicar las vicisitudes por las que he pasado ....

1º Que efectivamente, como decía Nocturno, con un cristal de 4 Mhz iba a
ser dificil el poder conseguirlo. Así que me fuí al saco de los Xtales a por
alguno gordo ... y la primera en la frente: solo había por encima de 4 Mhz
uno solo de 6 Mhz ... doble cambio por molinete y me fuí corriendo a mi
tendero electrónico favorito y me traje un puñado de 10, 12 y 20 Mhz

2º Con el Xtal de 20 Mhz en la RRBOARD1 y modificado correspondientemente
el programa para usar esta frecuencia me encuentro con que el 16F628 se queda
tieso como un plátano de mármol. Una y otra vez lo intento y parece como
muerto, como ausente que diría Neruda. Entonces caí en la cuenta ... y corrí
a cambiar el 16F628 por el 16F628A (Recordé aquello de que los dos son iguales
pero el tipo A es más igual)

3º Como no hay dos sin tres, el cabrón tampoco quería funcionar. Una hora de
desesperación después y caí en la cuenta de cambiar el puñetero fuse XT (cristal)
por el mas adecuado fuse HS (Hight Speed) y por fín salió andando ...

4º Continuamos para bingo y el programa tal como lo dejó Nocturno no era capaz
de generar pulsos por debajo de 30 us de periodo. Seteando el TIMER0 con cualquier
valor inferior a 240  el pulso siempre era superior a esos 30 us ....

5º Mirando el fichero C/ASM que genera el CCS vi que hiciese lo que hiciese
siempre incluía un TRIS antes de conmutar el estado del PIN_A2 ... así que
quité el output_toggle() y puse en su lugar las otras instrucciones ASM que
hacían efectivamente la conmutación .... y logré que el pulso bajase a unos
25 us ... y eso fué todo ... Con la gestión de la interrupción que hace CCS
metía unas 20 instrucciones ASM con lo que bajar mas era imposible.

y 6º Quité la interrupción y lo puse a güevo en el main(). Si el TIMER0 es igual
a 0 lo pongo a 234 y conmuto PIN_A2 con dos instrucciones ASM. El resultado
en ASM de esta mezcla Pastor Alemán y Yegua son exactamente 8 instrucciones
ASM que conforman el main() y que os pego mas abajo.

Resultado : Un pulso de 20 us según mi osciloscopio. Cualquier intento de
lograr que baje hasta los 18 us resulta vano, sale encefalograma plano en
el putoscopio y hasta aquí hemos llegado .... Doctores tiene la Iglesia que
sabrán explicar exactamente el porqué de las cosas.

Codigo:

// Wink56Khz.c

#include <16f628a.h>
#fuses HS,NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOMCLR, NOLVP
#use delay(clock=20000000)

void main(void)
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);     // TIMER0: Clock Interno
   disable_interrupts(global);                   // Deshabilito Interrupciones
   output_low(PIN_A2);                          // Para forzar TRIS inicial

   do{
      if(get_timer0()==0){
         set_timer0(234);
         #asm
         MOVLW  04      // Wink bit 2 del puerto A
         XORWF  05,F
         #endasm
      }
   }while(true);
}




Y el main() es en realidad esto otro:

Codigo:

....................    do{
....................
....................       if(get_timer0()==0){
0023:  MOVF   01,W
0024:  BTFSS  03.2
0025:  GOTO   02A
....................          set_timer0(234);
0026:  MOVLW  EA
0027:  MOVWF  01
....................          #asm
....................          MOVLW  04      // Wink bit 2 del puerto A
0028:  MOVLW  04
....................          XORWF  05,F
0029:  XORWF  05,F
....................          #endasm
....................       }
....................
....................    }while(true);
....................
.................... }
002A:  GOTO   023




Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
RE: Timer0 a 56khz
« Respuesta #7 en: 04 de Marzo de 2006, 12:24:00 »
¡Ea¡ Rebotado Rebotado Rebotado

Championix: Ahí tienes 56Khz clavados en un 16F628 con un Xtal de 20Mhz.
(Medidos en el osciloscopio con un error de +-0.2 uS)

Codigo:

// Wink56Khz.c

#include <16f628a.h>
#fuses HS,NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOMCLR, NOLVP
#use   delay(clock=20000000)

void main(void)
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);     // TIMER0: Clock Interno
   disable_interrupts(global);                   // Deshabilito Interrupciones

   output_low(PIN_A2);                          // Para forzar TRIS inicial

   do{
      output_toggle(PIN_A2);
      delay_us(7);
   }while(true);
}



Corto y cierro.

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania