TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: sergioa en 29 de Julio de 2010, 20:15:18
-
HOLA SOY NUEVO ESTOY PROGRAMANDO PIC HACE 6 MESES Y QUIERO HACER UN CONTROLADOR DE UN MOTOR DC CON PWM Y Q MIDA LA VELOCIDAD Y LA CORRIJA, USA TECLADO EN EL PUERTO B PARA INGRESAR DATOS Y LCD EN EL PUERTO D PARA MOSTRAR , USO EL TIMER 1 PARA CONTAR PULSOS , EL TIMER0 COMO INTERRUPCION , Y LA SALIDA DEL PWM ES LA CCP1 ESTO SE PUEDE ??
#include <16f877A.h>
#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#include <lcd.c>
#include <math.h>
#INCLUDE <kbd.C>
#define radios 4 //Encoder de 4 radios
float n;
int16 pulsos;
int16 interrupcion;
int16 velocidad_s;
float uni=0;
float dec=0;
float cen=0;
float mil=0;
char tec='0';
int16 vel_r=0;
int16 vel_d=0;
int16 valor=0;
int16 dif=0;
#int_RTCC
RTCC_isr()
{
pulsos=get_timer1(); //Se entra en la interrupción cada 10ms
interrupcion++;
if(interrupcion==500) //10ms · 500 = 5s
{
n=pulsos;
velocidad_s=floor(n+(n-floor(n))); //Redondea n, por si recibe algún pulso
//de más ó de menos
vel_r=velocidad_s*60;
lcd_putc('\f'); //Borra display
lcd_gotoxy(1,1);
printf(lcd_putc,"vel des=%lu r.p.m.",vel_d); //rev/s
lcd_gotoxy(1,2);
printf(lcd_putc,"vel real=%lu r.p.m.",vel_r); //r.p.m.
if (vel_d<vel_r) {
dif=vel_r-vel_d;
if(dif>=50) valor=valor-50;
else{
if(dif>=10) valor=valor-10;
else{
if(dif>=1) valor=valor-1;
}
}
}
else{
dif=vel_d-vel_r;
if(dif>=50) valor=valor+50;
else{
if(dif>=10) valor=valor+10;
else{
if(dif>=1) valor=valor+1;
}
}
}
interrupcion=0;
set_pwm1_duty(valor);
set_timer1(0);
set_rtcc(217); //Inicializa el TMR0
}
else
{
set_pwm1_duty(valor);
set_rtcc(217); //Inicializa el TMR0
set_timer1(pulsos); //Recupera los pulsos
}
}
void main()
{
set_tris_c(0x01); //Entrada de pulsos por RC0
enable_interrupts(GLOBAL);
enable_interrupts(INT_RTCC);
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_256);
set_rtcc(217); //10ms -> 10000us -> 10000/256=39,0625 -> 256-39=217
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
set_timer1(0);
interrupcion=0;
lcd_init();
kbd_init();
PORT_B_PULLUPS(TRUE);
printf(lcd_putc,"Control de vel \n con pwm");
delay_ms(400);
printf(lcd_putc, "\f\fPresione * \n para comenzar");
while(1)
{
tec=kbd_getc();
if (tec=='*')
{
DISABLE_interrupts(int_timer1);
DISABLE_interrupts(global);
tec=0;
printf(lcd_putc, "\f Ingrese 1er \n numero",);
delay_ms(1000);
do{
tec=kbd_getc();
}
while(tec==0);
tec= tec - 48;
mil=tec;
printf(lcd_putc, "\f 1er \n numero= %f",mil);
delay_ms(100);
tec=0;
printf(lcd_putc, "\f Ingrese 2DO \n numero",);
delay_ms(100);
do{
tec=kbd_getc();
}
while(tec==0);
tec= tec - 48;
cen=tec;
printf(lcd_putc, "\f 2do \n numero= %f",cen);
delay_ms(100);
tec=0;
printf(lcd_putc, "\f Ingrese 3er \n numero",);
delay_ms(100);
do{
tec=kbd_getc();
}
while(tec==0);
tec= tec - 48;
dec=tec;
printf(lcd_putc, "\f 3er \n numero= %f",dec);
delay_ms(100);
tec=0;
printf(lcd_putc, "\f Ingrese 4to \n numero",);
delay_ms(100);
do{
tec=kbd_getc();
}
while(tec==0);
tec= tec - 48;
uni=tec;
printf(lcd_putc, "\f4to \n numero= %f",uni);
delay_ms(100);
mil= mil * 1000;
printf(lcd_putc, "\f \n MIL= %f",mil);
delay_ms(100);
cen= cen * 100;
printf(lcd_putc, "\f \n CENT= %f",cen);
delay_ms(100);
dec= dec * 10;
printf(lcd_putc, "\f \n DOCE= %f",dec);
delay_ms(100);
vel_d= mil+cen+ dec+ uni;
printf(lcd_putc, "\f VEL DES \n num= %LU",vel_d);
valor=vel_d/10;
delay_ms(100);
setup_timer_2(T2_DIV_BY_16,255,1);
enable_interrupts(global);
}
}
}
-
quizás te vaya bien mi proyecto:
-
si eres nuevo en esto quizas visitando aqui (http://www.todopic.com.ar/foros/index.php?action=globalAnnouncements;id=1) te puedas ayudar un poco.
Cuando dices que si esto se puede, a que especificamente te refieres, este código lo has probado? lo has simulado? si es así, que es lo que hace que no te gusta como ha quedado?
Con respecto a la rutina de atencion a la interrupcion como que me parece un poco larga, pero eso es a gusto personal, mucho de lo que haces ahi puedes hacerlo en el bucle principal de tu programa.
Con respecto al uso del encoder, yo usaria la interrupcion externa, creo que es por RB0, tendrias que ver tu pic cual es. Yo uso esa porque hago control tipo servo y debe girar para ambos lados.
Saludos, Willy