Generando un pulso. 1ª Parte. Onda simétrica con INTRTCCA.- 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:
GeSHi (c):
setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT); // Ajusto divisor de TMR1 para RTC cada 0,8192 ms
enable_interrupts(int_rtcc);
enable_interrupts(global); // Habilito las interrupciones necesarias
Con esta configuración inicial podemos ya escribir nuestra
rutina ISR que es extremadamente simple:
GeSHi (c):
#int_rtcc
void handle_rtcc_int(){
Output_Toggle(OUT); // Conmuto PIN de Salida;
Set_timer0(177);
}
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í:
GeSHi (c):
////////////////////////////////////////////////////////////////////////////////////
//
// Generando_un_pulso_5_INTRTCc.c
//
// SERIE: "Técnicas en C" para el Foro TODOPIC
//
// (c) 10.2006 by RedPic
//
// Propósito: Generar un pulso de 2 Khz (0.5 ms de periodo)
//
// Técnica Empleada: Habilitar INTRTC para conmutar un PIN cada semiperiodo
//
////////////////////////////////////////////////////////////////////////////////////
#include <18f4550.h>
#fuses HS,MCLR,CCP2B3,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
////////////////////////////////////////////////////////////////////////////////////
//
// Defines y Constantes
//
////////////////////////////////////////////////////////////////////////////////////
#define LED PIN_E0 // Defino el Pin del Led
#define OUT PIN_B3
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción por Externa por Cambio de Flanco en RB0
//
////////////////////////////////////////////////////////////////////////////////////
#int_rtcc
void handle_rtcc_int(){
Output_Toggle(OUT); // Conmuto PIN de Salida;
Set_timer0(177);
Output_Toggle(LED); // Conmuto PIN de Led;
}
////////////////////////////////////////////////////////////////////////////////////
//
// Main
//
////////////////////////////////////////////////////////////////////////////////////
void main() {
////////////////////////////////////////// INICIALIZACIONES GENERALES
delay_ms(333); // Espero a que todo se estabilice e ...
disable_interrupts(global); // Inicializo el Micro y ...
disable_interrupts(int_timer1); // deshabilitando todo lo no necesario ...
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
delay_ms(333);
/////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION
setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT); // Ajusto divisor de TMR1 para RTC cada 0,8192 ms
enable_interrupts(int_rtcc);
enable_interrupts(global); // Habilito las interrupciones necesarias
printf("\r\nGenerando un pulso : RTCC\r\n");
printf("By Redpic para Foro TODOPIC\r\n\n");
do {
} while (TRUE);
}
D.- Ejemplo funcionando:Y esto es todo por hoy, amigos.

Mañana, más.