PicManía by RedRaven
 

Búsqueda personalizada

 

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


Esta página usa la letra Ñ

Nota pública importante sobre las consultas al Webmaster de PicManía.


Sugerencias a Picmanía... (que serán leídas pero seguramente no podrán ser contestadas)

Esta página pertenece al grupo de páginas de Diego RedRaven

 

 



Nota: Esta página Web esta repleta de imágenes, textos, logotipos y demás material extraídos de los mas variados medios de los que no soy ni autor ni depositario de los correspondientes derechos de autor, uso y/o reproducción. Si Ud. es depositario de dichos derechos y desea que el material correspondiente sea eliminado de esta Web no dude en ponerse en contacto conmigo mediante e-mail y será inmediatamente retirado. Gracias.
 
Visitas
Totales : 10724 Hoy: 2 Activas: 1 Vistas: 10724

Esta página fue modificada el 07-08-2010 15:42:34

           
 DmSoft WAMP Escribir Unreal