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.
Imagen 1. Ejemplos de ciclo de trabajo en PWM
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