Autor Tema: Serie Técnicas en C : Generando un pulso. 1ª Parte. Onda simétrica con INTRTCC  (Leído 3391 veces)

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

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5377
    • Picmania by Redraven
Generando un pulso. 1ª Parte. Onda simétrica con INTRTCC

A.- Conceptos involucrados:

Decíamos en Midiendo un pulso. 4ª Parte. El pulso completo. El Periodo y la Frecuencia que ... dadle un vistazo porque vamos a tratar con los mismos elementos, o mejor aún: los vamos a repetir en este mismo hilo.

Decíamos allí que el Tiempo T que transcurre ente dos flancos sucesivos de subida (o de bajada) es lo que conocemos como Periodo del Pulso (Period), o sea: lo que dura un pulso completo.

Cada T segundos (ó milisegundos, ó microsegundos) tenemos un nuevo pulso completo.

Como vemos, cada pulso tiene un Tiempo en Alto (High Time) y un Tiempo en estado Bajo (Low Time). La suma de los dos es el Periodo T del pulso.



Como vemos en la imagen superior un pulso completo comienza con un flanco de subida en T1, sigue con uno de bajada en T2 y concluye en el nuevo flanco de subida T3.

Entre T1 y T2 permanece el pulso en Alto, Wh, mientras que entre T2 y T3 lo hace en bajo, Wl.

El tiempo transcurrido entre T1 y T3 es el Periodo del Pulso. Si este periodo lo expresamos en Segundos entonces su inverso, 1 / Periodo, es la Frecuencia del tren de pulsos.

Estos dos valores son los quie vamos a generar con nuestro PIC: el Periodo T y la frecuencia F.

B.- Técnica a Aplicar:

Para generar el periodo T de nuestro pulso vamos a utilizar dos recursos  de los que disponen la gran mayoria de los PIC's, tanto los de la serie 18F como los 16F:

El TIMER0 y la Interrupción Por Desbordamiento de TIMER.

Sobre el TMR0 podeís leer lo escrito anteriormente en los hilos que preceden a éste hablando del TMR1 ...

Aquí solo recordar que el TMR0 es un contador que incrementa su valor cada FOSC*4 segundos y que cuando alcanza su valor máximo, 255 en TMR0 de bits ó 65535 en los PIC en que TMR0 es de 16 bits, dispara una Petición de Servicio por Interrupción llamada RTCC.

Esta interrupción se produce cada 256*FOSC*4 segundos si el TMR0 es de 8 bits o cada 65536*FOSC*4 si es de 16 bits.

Recordad tmbién que podemos aplicar distintos divisores a estas velocidades, preescaler, de tal forma que podemos ralentizar su cronometraje a 1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:128 ó 1:256 con lo que la formula anterior queda automaticamente multiplicada por el divisor que usemos. El mínimo es 1:2.

Además de todo esto tenemos también otro grado de libertad con estos recursos: Podemos asignar un valor determinado al TMR0 distinto de 0 cada vez que se nos dispare la interrupción RTCC. Con ello conseguimos que el contador al no empezar en 0 sino en un valor mayor n no deba completar su recorrido para disparar de nuevo la interrupción, sino que solo deba contar 255-n ó 65535-n según el tipo de TMR0 que estemos usando.

Así entre FOSC (el cristal que oscila a una determinada frecuencia), el divisor de frecuencia aplicado (preescaler) y el valor de TMR0 asignado cada RTCC (offset) tenemos una gran capacidad de maniobra para poder contar tiempos bastante precisos.

Como en las Técnicas anteriores medíamos una onda de entrada cuya frecuencia era aproximadamente de 2 Khz (0.5 ms de periodo) vamos en esta técnica a generar este mismo tipo de onda.

Asi lo que vamos a hacer es generar una RTCC cada semiperiodo de onda conmutando el estado del Pin de alto a bajo y viceversa: la mitad del periodo con el Pin en Alto y la otra mitad con el Pîn en bajo.

Cada RTCC volvemos a poner TMR0 a 177 para que recorra sólo 255 - 177 = 78 Ticks de TMR0.

C.- Implementación en C:

Para implementar nuestro Código en C vamos a centrarnos en los puntos que hemos descrito en la sección anterior.

Para configurar la interrpción RTCC utilizaremos lo siguiente:

Código: C
  1.    setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT);  // Ajusto divisor de TMR1 para RTC cada 0,8192 ms
  2.    enable_interrupts(int_rtcc);
  3.    enable_interrupts(global);                // Habilito las interrupciones necesarias
  4.  

Con esta configuración inicial podemos ya escribir nuestra rutina ISR que es extremadamente simple:

Código: C
  1. #int_rtcc
  2. void handle_rtcc_int(){
  3.    Output_Toggle(OUT);                       // Conmuto PIN de Salida;
  4.    Set_timer0(177);
  5. }
  6.  

Fijaos que en la rutina ISR anterior lo único que hacemos es conmutar el Pin de Salida y poner el offset del TMR0 a 177 para obtener los 255-177 ticks de TMR1 que necesitamos para hacer saltar RTCC aproximadamente cada 0.25 ms.


Con todo esto el programa completo para nuestro Generar una Onda Cuadrada Simétrica de 2 Khz de Frecuencia queda así:

Código: C
  1. ////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Generando_un_pulso_5_INTRTCc.c
  4. //
  5. // SERIE: "Técnicas en C" para el Foro TODOPIC
  6. //
  7. // (c) 10.2006 by RedPic
  8. //
  9. // Propósito: Generar un pulso de 2 Khz (0.5 ms de periodo)
  10. //
  11. // Técnica Empleada: Habilitar INTRTC para conmutar un PIN cada semiperiodo
  12. //
  13. ////////////////////////////////////////////////////////////////////////////////////
  14.  
  15. #include <18f4550.h>
  16. #fuses HS,MCLR,CCP2B3,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
  17. #use delay(clock=20000000)
  18.  
  19. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  20.  
  21. ////////////////////////////////////////////////////////////////////////////////////
  22. //
  23. // Defines y Constantes
  24. //
  25. ////////////////////////////////////////////////////////////////////////////////////
  26.  
  27. #define LED PIN_E0                          // Defino el Pin del Led
  28. #define OUT PIN_B3
  29.  
  30. ////////////////////////////////////////////////////////////////////////////////////
  31. //
  32. // Interrupción por Externa por Cambio de Flanco en RB0
  33. //
  34. ////////////////////////////////////////////////////////////////////////////////////
  35.  
  36. #int_rtcc
  37. void handle_rtcc_int(){
  38.    Output_Toggle(OUT);                       // Conmuto PIN de Salida;
  39.    Set_timer0(177);
  40.    Output_Toggle(LED);                       // Conmuto PIN de Led;
  41. }
  42.  
  43. ////////////////////////////////////////////////////////////////////////////////////
  44. //
  45. // Main
  46. //
  47. ////////////////////////////////////////////////////////////////////////////////////
  48.  
  49. void main() {
  50.  
  51.     ////////////////////////////////////////// INICIALIZACIONES GENERALES
  52.  
  53.    delay_ms(333);                           // Espero a que todo se estabilice e ...
  54.    disable_interrupts(global);              // Inicializo el Micro y ...
  55.    disable_interrupts(int_timer1);          // deshabilitando todo lo no necesario ...
  56.    disable_interrupts(int_rda);
  57.    disable_interrupts(int_ext);
  58.    disable_interrupts(int_ext1);
  59.    disable_interrupts(int_ext2);
  60.    setup_adc_ports(NO_ANALOGS);
  61.    setup_adc(ADC_OFF);
  62.    setup_spi(FALSE);
  63.    setup_psp(PSP_DISABLED);
  64.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  65.    setup_timer_0(RTCC_OFF);
  66.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  67.    setup_timer_2(T2_DISABLED,0,1);
  68.    setup_timer_3(T3_DISABLED);
  69.    setup_comparator(NC_NC_NC_NC);
  70.    setup_vref(FALSE);
  71.    port_b_pullups(FALSE);
  72.    delay_ms(333);
  73.  
  74.    /////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION
  75.  
  76.    setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT);  // Ajusto divisor de TMR1 para RTC cada 0,8192 ms
  77.    enable_interrupts(int_rtcc);
  78.    enable_interrupts(global);                // Habilito las interrupciones necesarias
  79.  
  80.    printf("\r\nGenerando un pulso : RTCC\r\n");
  81.    printf("By Redpic para Foro TODOPIC\r\n\n");
  82.  
  83.    do {
  84.  
  85.    } while (TRUE);
  86. }
  87.  

D.- Ejemplo funcionando:


Y esto es todo por hoy, amigos.  :mrgreen:
Mañana, más.

« Última modificación: 24 de Octubre de 2014, 09:59:29 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania