Práctica 8 con Miuva. Led RGB: ADC, PWM y pulsador con PIC C

En esta práctica utilizaremos el ADC para variar el ciclo de trabajo de un PWM y de esta forma modificar la intensidad del led rgb, también se hará que al presionar el pulsador se cambie el color del led.

PWM

Un PWM o modulador por ancho de pulso es una señal cuadrada que mantiene la misma frecuencia pero en la cual puedes cambiar el tiempo en alto, esto funciona para manejar la intensidad de leds, controlar la velocidad de motores en DC, entre otras aplicaciones. El ciclo de trabajo es la relación entre la parte en alto y la parte en bajo de la señal.

Imagen1. Ejemplos de ciclo de trabajo en PWM

Recordemos que las interrupciones por timer0 se realizan cada determinado tiempo, por lo cual podemos ajustar este tiempo para que tenga una frecuencia constante, y de forma similar a la práctica del servomotor calcularemos el tiempo que tiene que tardar en desbordarse dependiendo del tiempo que estuvo en alto.

También crearemos una variable donde almacenaremos el color que se tiene que encender, y la cual cambiará cada que se presiona el pulsador (similar a la práctica de las tres posiciones del servomotor).

Con esto podemos crear el siguiente código:

Código en PIC C:

#include <18f4550.h>          // la librería del PIC
#device ADC = 10           //Bits del ADC
#Fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL2, CPUDIV1, VREGEN
#use delay (clock=48M)        //Seleccionamos la frecuencia de reloj de 48MHz
#use standard_io(e)
#use standard_io(c)
#include <MLCD.c>

unsigned int16 carga;
int16 adc, TIEMPO_ALTO;
float v;
int led = 1;

#int_TIMER0
void timer0_isr(){
   if (led == 1){
   output_low(PIN_E0);
   delay_us(TIEMPO_ALTO);
   output_high(PIN_E0);
   }
   else if (led == 2){
      output_low(PIN_E1);
      delay_us(TIEMPO_ALTO);
      output_high(PIN_E1);
   }
   else{
      output_low(PIN_E2);
      delay_us(TIEMPO_ALTO);
      output_high(PIN_E2);
   }
   carga = 333 - TIEMPO_ALTO - 2.5;    //Para calcular el tiempo de
   carga = carga*48.0/8.0;         //la precarga del timer0
   carga = 65535 - carga;
   set_timer0(carga);
}

void main(){
   lcd_init();
   set_tris_e(0x00);
   set_tris_c(0x00);
   output_e(0x07);
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
   enable_interrupts(int_TIMER0);
   enable_interrupts(GLOBAL);
   set_adc_channel(0);
   delay_us(20);
   while(true){
      if (input_state(PIN_C0)){
         delay_ms(100);
         led++;
         if (led >= 4){
            led = 1;
         }
      }
      //TIEMPO_ALTO dado en nanosegundos entre 1 y 333
      adc = read_adc();    
      v = adc*5.0/1024.0;
      TIEMPO_ALTO = v*325.0/5.0;
      printf(lcd_putc, "n%3lu %1.3f", TIEMPO_ALTO, v);
   }
}

Conexiones

Observa el video demostrativo

Descarga el proyecto en PIC C o Mikro C

Menú