#include <16F877A.h>
#device adc=10
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#include<lcd_flex.h>
void main(void)
{
float duty=0,dutylcd=0, rpm=1200, vref=5,vref2=0,adc=0;
//set_tris_a(0x00); Ver si hace falta poner todo como salida.
set_tris_b(0xFF);
set_tris_c(0x00);
set_tris_d(0x00);
/*output_a(0);
output_b(0); Ver si hace falta poner todo en cero.
output_c(0);
output_d(0);*/
lcd_init();
delay_ms(10);
output_b(0);
output_c(0);
//Configuracion del ADC:
setup_adc_ports(NO_ANALOGS);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
enable_interrupts(int_rb);
enable_interrupts(global);
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
//Configuracion del PWM:
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,65.66667,1);
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
duty=vref*204.6; //(1023/100%)*dutylcd = 10.23*dutylcd = 10.23*20*vref=204.6*vref
set_pwm1_duty(duty);
lcd_gotoxy(10,1);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
while(1)
{
if(vref2!=vref)
{
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
duty=20*vref; //(100%/5V)*vref
lcd_gotoxy(10,1);
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
duty=vref*204.6; //(1023/100%)*dutylcd = 10.23*dutylcd = 10.23*20*vref=204.6*vref
set_pwm1_duty(duty);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
}
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
delay_ms(1);
}
}
#int_rb
void frec(void)
{
if(input(pin_B4)==1)
output_high(pin_C0);
if(input(pin_B5)==1)
output_low(pin_C0);
}
Actualizacion 1: Recien llego del lab, en PWM esta a la frecuencia que quiero (15kHz), pero no el ciclo de trabajo. Lo que yo quiero es sea lineal la variacion con una tension de referencia (para la que uso el ADC), pero me parece que estoy asignando mal la funcion set_pwm1_duty(duty); El valor de la variable duty tiene que ser el valor del duty propiamente? es decir, de 0 a 100 o tengo que hacer una regla de 3 simples, con 100% de duty son 1023 por los 10 bits que utiliza el pwm?? Gracias!!
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
//Configuracion del PWM:
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,66,1);
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
//duty=vref*204.6; //(1023/100%)*dutylcd = 10.23*dutylcd = 10.23*20*vref=204.6*vref
delay_ms(10);
set_pwm1_duty(511); //Para que arranque en 50%.
lcd_gotoxy(10,1);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
while(1)
{
if(vref2!=vref)
{
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
duty=20*vref; //(100%/5V)*vref
lcd_gotoxy(10,1);
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
//duty=(int) vref*204.6; //(1023/100%)*dutylcd = 10.23*dutylcd = 10.23*20*vref=204.6*vref
duty=read_adc();
delay_ms(10);
set_pwm1_duty(duty);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
}
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
delay_ms(1);
}
}
Estas trabajando a 4MHz, Frecuencia del PWM 14925.37Hz con PR2=66, resolución 8.066, entonces 0% ->0, 100% -> 268.
Saludos!
Calculo bien la resolucion, pero como lo relacionas con los bits?
Declare globalmente para poder usarlo en el main y en las distintas funciones y me da un error cuando compilo: A numeric expression must appear here. Aclaro, estoy haciendo q=1 o q=0
#include <16F877A.h>
#device adc=10
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#include<lcd_flex.h>
void control(float dutylcd);
#define q1=PIN_C4
#define q2=PIN_C5
#define q3=PIN_C6
#define q4=PIN_C7
void main(void)
{
int duty=0; //VER SI duty SE LO DECLARA COMO FLOAT!
float dutylcd=0, rpm=1200, vref=5,vref2=0,adc=0;
//set_tris_a(0x00); Ver si hace falta poner todo como salida.
set_tris_b(0xFF);
set_tris_c(0x00);
set_tris_d(0x00);
/*output_a(0);
output_b(0); Ver si hace falta poner todo en cero.
output_c(0);
output_d(0);*/
lcd_init();
delay_ms(10);
output_b(0);
output_c(0);
//Configuracion del ADC:
setup_adc_ports(NO_ANALOGS);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
enable_interrupts(int_rb);
enable_interrupts(global);
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
//Configuracion del PWM:
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,66,1);
//Resolucion = log(Fosc/Fpwm)/log(2)=8,066 --> 2^(Resolución)=268
//DUTY: 0% ->0, 100% -> 268
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
duty=2.68*dutylcd; //(268/100%)*dutylcd%=2.68*dutylcd
set_pwm1_duty(duty);
delay_ms(1);
lcd_gotoxy(10,1);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
while(1)
{
if(vref2!=vref)
{
vref2=vref;
lcd_gotoxy(1,1);
printf(lcd_putc,"V:+%.2fv",vref);
duty=20*vref; //(100%/5V)*vref
lcd_gotoxy(10,1);
dutylcd=20*vref; //(100%/5V)*vref = 20*vref
duty=2.68*dutylcd; //(268/100%)*dutylcd%=2.68*dutylcd
set_pwm1_duty(duty);
delay_ms(1);
printf(lcd_putc,"D:%.1f",dutylcd);
lcd_putc('%');
lcd_gotoxy(3,2);
printf(lcd_putc, "RPM: %.1f",rpm);
control(dutylcd);
}
vref=(float) read_adc()*0.0048828125; // (5v/1024)=0,0048828125=4,88mV
delay_ms(1);
/*setup_adc_ports(RA1_ANALOG);
adc=read_adc();*/
}
}
#int_rb
void frec(void)
{
if(input(pin_B4)==1)
output_high(pin_C0);
if(input(pin_B5)==1)
output_low(pin_C0);
}
void control(float dutylcd)
{
if(dutylcd<48)
{
q1=1;
q2=0;
q3=1;
q4=0;
}
if(dutylcd>=48 && dutylcd<=52)
{
q1=0;
q2=0;
q3=1;
q4=1;
}
if(dutylcd>52)
{
q1=0;
q2=1;
q3=0;
q4=1;
}
}
#bit q=0x07.1 // Creo que el 0x07 es el puerto C :mrgreen:
Ahi funciono, pero si en el 16f877.h tiene #define PIN_C0 56 no deberia andar??
Otra duda,,,,,necesito estar sensando constantemente otra tension, para lo ke pensaba usar el ADC del pin A2, tengo ke ir "apagando" el ADC del pin A1 y "prender" el del A2 y luego al reves??el ADC es uno solo, lo que multiplexas es el canal.
ext_int_edge(L_TO_H);
enable_interrupts(int_ext);
enable_interrupts(global);
#int_ext
void ext_isr(void)
{
output_high(PIN_C0);
delay_ms(200);
output_low(PIN_C0);
}