TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: ALFREDOSKY en 30 de Mayo de 2014, 17:45:39
-
Hola a todos, estoy tratando de mover un motor con pwm, he revisado códigos en esta misma pagina y en otros lados y he realizado, basicamente, el mismo programa pero con algunos cambios, pero no se genera la señal a pesar que todo, aparentemente, esta correcto. El código completo intenta controlar el giro del motor hasta cierto punto, luego de ese punto, debe regresar al estado inicial, en realidad esa, por ahora es una cuestión secundaria si es nunca se mueve el motor. Pego el código para ver si alguien me puede dar una mano :mrgreen:
#include <16c63a.h>
#fuses XT,NOPROTECT,NOBROWNOUT,NOWDT
#use delay(clock = 4000000)
#use standard_io(b)
#use standard_io(c)
int pulse = 0;
#int_ext
void encoder()
{
pulse = pulse + 1;
}
void motor_right()
{
set_pwm1_duty(255); //mover a la derecha a toda marcha
set_pwm2_duty(0);
}
void motor_left()
{
set_pwm1_duty(0); //motor detenido
set_pwm2_duty(0xFF);
}
void motor_stop()
{
set_pwm1_duty(0); //motor detenido
set_pwm2_duty(0);
}
void main()
{
int right = 0;
set_tris_b(0x01); //RB0 entrada
set_tris_c(0x00); //RC1 y Rc2 como salida
enable_interrupts(INT_EXT); //interrupcion externa por pin RB0 habilitado
enable_interrupts(GLOBAL); //interrupciones globales habilitado
ext_int_edge(L_TO_H); //interrupcion por flanco de subida
setup_timer_2(T2_DIV_BY_1,255,1);
setup_ccp1(CCP_PWM); //mudulo ccp1 como pwm
setup_ccp2(CCP_PWM); //modulo ccp2 como pwm
motor_stop();
while(1)
{
motor_right();
if(right == 0)
{
motor_right();
if(pulse == 12)
{
motor_stop();
delay_ms(500);
pulse = 0;
right = 1;
motor_left();
}
}
if(right == 1)
{
if(pulse == 12)
{
motor_stop();
delay_ms(500);
right = 0;
}
}
}
}
he usado el mismo codigo en un 16f877a, pero igual, sigue sin funcionar
-
el motor_right() debajo del while debe borrarse para cumplir con la logica del funcionamiento, pero como dije, sino se genera el pwm, no tiene sentido discutir sobre los pulsos del encoder, primero debo resolver la generacion de la señal, despues se vera lo otro
-
a primera vista te puedo decir que el valor máximo del pwm es 1023, no 255, tal vez por eso no se mueve, con 255 solo le estas aplicando una cuarta parte de la potencia al motor.
Saludos
-
Me atreveria a decir que el problema puede estar aqui :D
setup_timer_2(T2_DIV_BY_1,255,1);
Bajalo a 125 por ejemplo y nos dice si ahora se mueve el motor :mrgreen:
Saludos
-
gracias por sus respuestas, rivale y RALF2; en la simulación en Proteus tenía unos LOGIC TOGGLE que estaban en conflicto con las entradas del puente H (realizado con transistores), los borre y ya corrió :-/ ;tienes razón rivale, debería ir 1023(10 bits) para ir a toda marcha, ya lo corregí, vas mas rápido; tambien reduje el periodo del timer2, y también corrió más rápido...pero ahora, con mi rústico control del encoder(usando uno de los canales) mediante RB0, en Proteus el motor no se detiene del todo y no regresa pero veo que titila el pin del ccp2, es decir, mando el pwm para ir a la izquierda :x, en el MPLAB hice debugg paso-a-paso(simulando flancos de subida) y la lógica está correcta...dejo mi código modificado, porfavor si me pueden ayudar les agradecería infinitamente
#include <16c63a.h>
#fuses XT,NOPROTECT,NOBROWNOUT,NOWDT
#use delay(clock = 4000000)
#use standard_io(b)
#use standard_io(c)
int pulse = 0;
#int_ext
void encoder()
{
pulse = pulse + 1;
}
void motor_right()
{
set_pwm1_duty(0x3FF); //mover a la derecha a toda marcha
set_pwm2_duty(0);
}
void motor_left()
{
set_pwm1_duty(0);
set_pwm2_duty(0x3FF); //mover a la izquierda a toda marcha
}
void motor_stop()
{
set_pwm1_duty(0); //motor detenido
set_pwm2_duty(0);
}
void main()
{
int right = 0;
set_tris_b(0x01); //RB0 entrada
set_tris_c(0x00); //RC1 y Rc2 como salida
enable_interrupts(INT_EXT); //interrupcion externa por pin RB0 habilitado
enable_interrupts(GLOBAL); //interrupciones globales habilitado
ext_int_edge(L_TO_H); //interrupcion por flanco de subida
setup_timer_2(T2_DIV_BY_1,125,1);
setup_ccp1(CCP_PWM); //mudulo ccp1 como pwm
setup_ccp2(CCP_PWM); //modulo ccp2 como pwm
motor_stop();
while(1)
{
if(right == 0)
{
motor_right();
if(pulse == 12)
{
motor_stop();
delay_ms(1000);
pulse = 0;
right = 1;
motor_left();
}
}
if(right == 1)
{
if(pulse == 12)
{
motor_stop();
delay_ms(1000);
pulse = 0;
right = 0;
}
}
}
}
-
Coloca a demas la simulacion y/o el esquema del circuito que estas empleando :mrgreen:
-
ok :lol:
-
Tu puedes trabajar el duty con valores de 0 a 255 (8 bits) o con valores de 0 a 1023 (10 bits)
Para ello puedes utilizar las siguientes formulas y tu programa funcionaria tambien haciendo solo el cambio que te comente arriba :mrgreen:
set_pwm1_duty(duty cycle);
El periodo del pwm: (1/clock)*4*t2div*(period+1)
el duty cycle:
Para (duty cycle) 8 bits: value*4*(1/clock)*t2div
Para (duty cycle) 10bits: value*(1/clock)*t2div
Si realizas los calculos con estas formulas veras porque no te funciono el pwm :mrgreen:
Saludos
-
ok RALF2 gracias por el dato, el manual del ccs no dice mucho sobre pwm, leyendo el datasheet del pic y tu información la cosa queda mas clara ((:-))
-
jajajaja de nada ALFREDOSKY
Para eso estamos en el foro :mrgreen:
Saludos
-
Depende de como configures tu módulo ccp trabajas a 10, 8 o menos bits, como bien lo indico Ralf
no recuerdo si en ccs menciona como calcular la resolución del pwm, pero eso lo ves mas claro en la hoja de especificaciones de cada pic.
Saludos
-
La resolucion depende de la frecuencia del cristal y la frecuencia a la que quieras operar el pwm :mrgreen:
El data sheet del pic que estes utilzando te indica como calcularlo.
-
Es verdad, ya lo revise y esta bien...pero no consigo que el motor se detenga e inicie su marcha de regreso :?
-
Es verdad, ya lo revise y esta bien...pero no consigo que el motor se detenga e inicie su marcha de regreso :?
Creo que el problema puede estar en la conexion de los transistores del puente H. No es del todo correcta, ya que los transistores cuyos emisores estan a positivo, no conmutan correctamente al faltarles la referencia de masa.
Podrias utilizar parejas de NPN+PNP o mejor aun MOS-FET, pero en cualquier caso asegurate de referenciar las bases o las puertas siempre al emisor o drenador. Esto puedes hacerlo con circuitos especializados, como el IR2112 y similares.
Saludos.