/******************************************************************************
GENERADOR DE PWM REGULABLE MEDIANTE POTENCIÓMETROS
Diseñado con PIC18F14K50, trabajando con oscilador interno a 32MHz
- Usamos los canales ADC 4 y 5 (pines 15 y 16)
- Salida PWM en el pin 5
Uno de los potenciómetros regulará la frecuencia de trabajo entre 3KHz y 8MHz
El otro regula el duty entre 0% y 100%. Lógicamente, a mayor frecuencia, menor
resolución.
Nocturno-2014
www.micropic.es
******************************************************************************/
#include <18F14K50.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(internal=32MHz)
#define ResolucionADC 1024
void main()
{
unsigned int16 adc_duty,frecuencia;
unsigned int8 i;
setup_adc_ports(sAN4|sAN5);
setup_adc(ADC_CLOCK_INTERNAL);
setup_ccp1(CCP_PWM|CCP_SHUTDOWN_AC_L|CCP_SHUTDOWN_BD_L);
set_pwm1_duty((int16)0);
while(TRUE)
{
frecuencia=adc_duty=0;
// Leemos los dos canales ADC para obtener el promedio de 16 lecturas
for (i=0;i<16;i++) {
set_adc_channel(4);
frecuencia += read_adc();
set_adc_channel(5);
adc_duty += read_adc();
}
// Calculamos el promedio de ambas variables
frecuencia=frecuencia>>4;
adc_duty=adc_duty>>4;
// Establecemos la nueva frecuencia del PWM
setup_timer_2(T2_DIV_BY_1,frecuencia>>2,1);;
// Establecemos el nuevo duty del PWM, proporcional a la frecuencia
set_pwm1_duty((int16)((int32)adc_duty*frecuencia/ResolucionADC));
}
}