| |
TÉCNICAS EN
C
|
|
| |
Tareas
Comunes Realizadas
en
C
|
|
| |
Esta serie de contenidos
titulada Técnicas en C pretende
mostrar con ejemplos comentados la forma de implementar ciertos
procesos muy usuales durante el uso de los Microcontroladores PIC de
las series 16F y 18F. |
|
|
|
Generando
un pulso. 2ª Parte. Onda cuadrada simétrica mediante INTCCP |
|
| |
| A.-
Conceptos involucrados: |
|
|
- Seguimos dándole vueltas al mismo
concepto que en todas las Técnicas
en C anteriores. Si lo deseáis podéis repasar esto mismo en
cualquiera de ellas.
|
|

|
- Volvemos a generar un pulso de Periodo
T con dos semiperiodos iguales, simétrico, y de unos 2 Khz de
frecuencia: unos 0.25 ms en alto y otros 0.25 ms en bajo, total 0.5 ms
de periodo.
|
| |
| B.-
Técnica a Aplicar: |
|
|
- Para generar el periodo T de
nuestro pulso vamos a utilizar de nuevo el módulo CCP del que
disponen la gran mayoría de los PIC's, tanto los de la serie 18F como
los 16F.
|
- Recordemos: En la Técnica
Midiendo un pulso. 2ª Parte. Tiempo en
Alto con INTCCP hacíamos uso de este mismo módulo utilizando su modo
Capture en el que cuando detectábamos un flanco externo se nos
capturaba el valor en ese momento del TMR1. Jugando
con los sucesivos valores obteníamos la duración del pulso.
|
- En ésta técnica que ahora describimos
vamos a hacer lo diametralmente opuesto: Vamos a utilizar el CCP
en modo Compare para que el CCP vaya comparando
automáticamente el valor de TMR1 con un valor de referencia
que le damos, CCP_x, y en cuanto lo alcance se realice la
conmutación del Pin asociado a él y nos dispare la Petición de
Servicio de Interrupción (ISR) INT_CCPx correspondiente.
|
- En el código de esta interrupción
volvemos a hacer lo mismo pero configurando el Compare para que
cuando TMR1 alcance el valor de referencia conmute nuestro Pin
CCP al estado contrario.
|
- Si ambos valores de TMR1 de
referencia, para el Compare a Alto y el Compare a bajo, son iguales
tendremos un tren de pulsos simétricos, están el mismo tiempo en
alto que en bajo, o sea que tienen un Duty Cycle del 50%. En caso
contrario estarán mas tiempo en un estado que en otro y será una onda
asimétrica, o sea que tendrá un Duty Cicle distinto del 50%.
|
- El periodo será la suma de ambos
tiempos, el que permanece en estado alto mas el que está en estado
bajo.
|
- Calculando cuidadosamente dichos
tiempos podremos generar una onda del periodo que deseamos. Pondremos
a 0 siempre TRM1 y cargaremos CCP_x con el número de
Ticks de TMR1 en que deseamos que se dispare nuestra
conmutación/interrupción.
|
|
|
| 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 interrupción CCP
utilizaremos lo siguiente:
|
|
|
| |
|
|
| |
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Alto
enable_interrupts(int_ccp2); // Habilito la interrpción INT_CCP2
enable_interrupts(global); // Habilito las interrupciones necesarias
|
|
| |
|
|
|
|
- Con esta configuración inicial podemos
ya escribir nuestra rutina ISR que es muy simple ya que únicamente
selecciona mediante un flag si debe el siguiente cambio es a
Alto o a Bajo y colocar el tiempo en que deseamos en que esto se
produzca:
|
|
|
| |
|
|
| |
#int_ccp2
void handle_ccp2_int(){
if(++flagConmuta==1){
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 modo
COMPARE cambiando a Bajo
} else{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo
COMPARE cambiando a Alto
}
CCP_2=0;
// Pongo a cero el valor a comparar ...
set_timer1(0);
// y el TMR1.
CCP_2 = 1250;
// Quiero que se dispare cada 0.25 ms ...
// luego pongo los Ticks de TMR1 para ese tiempo.
} |
|
| |
|
|
|
|
- Notad que estoy trabajando con una
configuración particular a la que me sujeta el Hardware específico del que
dispongo: El módulo CCP2 y un cuarzo de 20 Mhz.
|
- Con un Cristal de 20 Mhz los cálculos me
indican que el número de Ticks de TMR1 necesarios para realizar una
conmutación cada 0.25 ms es de 1250 (0.00025 / (1/ FOSC)*4)
|
- Con todo esto el programa completo para
nuestro Generar una Onda Cuadrada Simétrica de
2 Khz de Frecuencia queda así:
|
|
|
| |
|
|
| |
/////////////////////////////////////////////////////////////////////////////////////
//
// Generando_un_pulso_6_INTCCP.c
//
// SERIE: "Técnicas en C" para el Foro TODOPIC
//
// (c) 11.2006 by RedPic
//
// Propósito: Generar un pulso de 2 Khz (0.5 ms de periodo)
//
// Técnica Empleada: Habilitar INTCCP para conmutar el PIN CCP2 cada
semiperiodo
// utilizando el recurso CCP en modo compare.
//
////////////////////////////////////////////////////////////////////////////////////
#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
////////////////////////////////////////////////////////////////////////////////////
//
// Variables en RAM
//
////////////////////////////////////////////////////////////////////////////////////
int1 flagConmuta=0;
////////////////////////////////////////////////////////////////////////////////////
//
// Interrupción CCP por Compare TMR1
//
////////////////////////////////////////////////////////////////////////////////////
#int_ccp2
void handle_ccp2_int(){
if(++flagConmuta==1){
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 modo
COMPARE cambiando a Bajo
} else{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo
COMPARE cambiando a Alto
}
CCP_2=0;
// Pongo a cero el valor a comparar ...
set_timer1(0);
// y el TMR1.
CCP_2 = 1250;
// Quiero que se dispare cada 0.25 ms ...
// luego pongo los Ticks de TMR1 para ese tiempo.
Output_Toggle(LED);
// Monitorizo visualmente con el 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_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo COMPARE
cambiando a Alto
enable_interrupts(int_ccp2);
// Habilito la interrpción INT_CCP2
enable_interrupts(global);
// Habilito las interrupciones necesarias
printf("\r\nGenerando un pulso : INTCCP Compare\r\n");
printf("By Redpic para Foro TODOPIC\r\n\n");
do {
} while (TRUE);
}
|
|
| |
|
|
|
|
|
D.- Ejemplo
funcionando: |
|
|
|
 |
|
|
|
|
|
|
Esta página se modificó el
27/12/2008
|