No funciona PWM en PIC18F2550

Hola tengo este código que hice basándome en varios ejemplos de Internet, es para controlar la velocidad de giro de un motoreductor.

Muevo el potenciometro y se ajusta el PWM y con ello la velocidad



Código:
#include <18F2550.h>
#device adc=8
#fuses INTRC,NOMCLR,NOWDT,NOLVP,NODEBUG,CPUDIV1
#use delay(clock=4000000)

unsigned int8 valor;

void main()
{
set_tris_A(0b0000001); ///Lo declare asi para que sea entrada el adc 
set_tris_C(0); //Asi porque el CPP1 es salida
output_low(PIN_C2);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_64, 255, 1);  //Esto no se que hace
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(50);

while(true)
{
   valor=read_adc();
   set_pwm1_duty(valor);
   delay_ms(5);
}

}

Bueno funciona bien con un led conectado pero le conecto un transistor para manejar el motor (un cooler de los que traen foquito del pc) y este parpadea como estrobo. le conecto un motor y funciona pero si lo tomo con las manos se apaga todo y ya no enciende hasta que desconecto y cxonecto

Espero y me ayuden si no pues ni modo ...
 
Los ventadores de pc suelen llevar una controladora que seguramente "se pelee" con el pwm. Si fuese un motor "tonto" funcionaría.
 
¿Cuantas lineas tiene el Bus del ventilador, 2, 3, o 4? Cuando lo paras con la mano ¿has probado a girar manualmente las aspas dándoles impulso a ver si vuelve a girar?
 
Los ventadores de pc suelen llevar una controladora que seguramente "se pelee" con el pwm. Si fuese un motor "tonto" funcionaría.

Si tiene la controladora pero hice esto mismo con el arduino y este motor y funcionaba perfecto.

¿Cuantas lineas tiene el Bus del ventilador, 2, 3, o 4? Cuando lo paras con la mano ¿has probado a girar manualmente las aspas dándoles impulso a ver si vuelve a girar?
Tiene 2 lineas y si lo probe y ya no funciona :LOL:



para mi que a tu diseño le faltan condesadores como filtros podrias publicar exactamente como lo tienes conectado en un diagrama?

Asi Segun yo asi cae en corte y saturacion el transistor :LOL:
Se me ocurre que es problema de la frecuencia a la que trabaja el PWM o que el transistor no sirve para altas frecuencias no se :LOL:
 

Adjuntos

  • Sin título.jpg
    Sin título.jpg
    50.7 KB · Visitas: 28
Última edición:
Circuito rrrrrraro rrrrrrrrraro.
Pon el emisor a negativo, la carga en el colector, un diodo volante y una resistencia de base.
Los pwm suelen ir en torno al kHz así que de alta frecuencia nada.

Creo que el circuito de salida de los pic tiene dos corrientes de salida programables, mira a ver si no has activado algo así.
 
Última edición:
Si tiene la controladora pero hice esto mismo con el arduino y este motor y funcionaba perfecto.
Prueba con las siguientes modificaciones al programa que subiste y checa si ahora ya funciona con tu motor.

Lo probé con un motor DC normal de 12V y anduvo bien así como se muestra en el esquema adjunto.

Suerte.
 

Adjuntos

  • Motor DC controlado por PWM.jpg
    Motor DC controlado por PWM.jpg
    91.9 KB · Visitas: 55
  • 18F2550 PWM controlado por ADC.rar
    111.1 KB · Visitas: 46
Última edición:
al diseño de darkbytes le agregaria condesadores de 100nF en la alimentacion, MCLR (lo mas cerca posible de los pines) y uno en paralelo al motor(lo mas cerca de los bornes).
 
Última edición:
Muchas gracias a todos ya sirvió con ese ultimo circuito

si no me equivoco es un transistor con polarización por divisor de tensión
pero que función tienen los diodos ??

Lo del capacitor en los bornes del motor para que es ??
Creo era para corregir el factor de potencia o no recuerdo bien tenia eso en mi libreta pero la eche a la basura :LOL:
 
Lo del capacitor en los bornes del motor para que es ??
para reducir los EMF
MAGkz.jpg


pero que función tienen los diodos ?
D1 es para evitar que se destruya el transistor.

opino lo mismo "R3 y D2 sobran" pero no son dañinos :D.
 
Última edición:
al diseño de darkbytes le agregaria condesadores de 100nF en la alimentacion, MCLR (lo mas cerca posible de los pines) y uno en paralelo al motor(lo mas cerca de los bornes).

Pero lei no recuerdo donde que un diodo rectificador polarizado inversamente, tiene cierta capacitancia como un varicap, y entonces ya no seria necesario el capacitor paralelo al motor


Y funciona igual si lo alimento en lugar de 12v con 5v???
Porque lo habia armado pero olvide el MCLR y no funciono bien, asi que lo armare otra vez bien :LOL:
 
Ya funciono, el problema era que conecte el motor y pic a los 5v por eso se reiniciaba el pic y parecia estr0bo pero le pusse una fuente para el motor y ya funciono gracias a todos
 
Buenos días bella gente de la comunidad electrónica, estoy realizando un proyecto de pwm con el pic 18f2550 para radio-frecuencia, en la simulación de proteus no me da la frecuencia que estoy configurando, pero utilizo otro pic como el 16f877 con el mismo programa me da exacto,es decir con el pic 877 da axacto (1ms exacto), pero con el 2550 no(4ms) 4 veces el periodo de lo que tiene que dar, tienen experiencia con la simulación del pwm con el 18f2550?, realice un programa de prueba ya se los paso para ver si me pueden ayudar, de antemano muchaaaaas gracias por su aporte.

para una frecuencia de 1Khz, el periodo es de 1ms, la formula que utilizo para configurar el pwm es:

Tpwm = (cargatimer2 + 1) * 4 * (prescalertimer2) * T(oscilador) * Postcaler

al despejar la carga del timer2 :

cargatimer2 = (Tpwm / (4 * (prescalertimer2) * T(oscilador) * postcaler) - 1

cargatimer2 = 249

con este valor al carga el timer2 debe dar en el simulador un periodo de 1mseg.

para configurar el timer2 se utiliza la comando:

septup_timer_2(t2_div_by_4,249,1); //como pueden ver utilizo el prescaler de 4.

1585506231426.pngdiagrama.JPG
 
La palabra de configuración para ese tipo de PIC no es correcta.
Usa la siguiente:
C:
#fuses NOFCMEN, NOIESO, NOVREGEN
#use delay (CRYSTAL = 4 MHz, CLOCK = 4 MHz)
Con esa configuración se debe obtener lo siguiente:
18F2550 - Fuses XT, NOUSB.jpg
 
Buenos días d@rkbytes si lo simule y funciona correctamente muchas gracias. Y lo del código lo tendré en cuenta
Para el mismo proyecto de radio frecuencia tengo un programa prototipo, tiene un menú de bienvenida, selección de modo de trabajo (menú principal) y run, en el menú principal, el diseño que quiero es que titile ítem que voy a seleccionar, si lo hace, pero si conoces una manera mas eficiente para el pic 18f2550 para comparar te lo agradezco, ya te paso el código.

CSS:
#include <18f2550.h>
#fuses NOFCMEN, NOIESO, NOVREGEN
#use delay (CRYSTAL = 4 MHz, CLOCK = 4 MHz) 
#define LCD_DATA_PORT getenv("SFR:PORTB")
#define lcd_enable_pin pin_c5
#define lcd_rs_pin pin_c6
#define lcd_rw_pin pin_c7
#include <lcd.c>
#use standard_io(c)
#use standard_io(a)
int a=0;
int b=150;
enum funciones{fac,corp}; // asigno variables a la funcion

void facial()
{
output_high(pin_c1); //activa rele
setup_timer_2(t2_div_by_1,249,1);           // configuracion pwm para una frecuencia de 1khz
setup_ccp1(ccp_pwm);                      // configura el modo de del registro pwm

while(true){

lcd_gotoxy(8,1);
printf(lcd_putc,"*** MENU RUN ***");
lcd_gotoxy(1,2);
printf(lcd_putc,"Ap. FACIAL");
delay_ms(100);
set_pwm1_duty(b);                         // configura la resolucion del pwm

if(input(pin_a0)==1){                     // aumenta el ancho de pulso
a=a+50;
}

if(input(pin_a1)==1){                     // disminuye el ancho de pulso
a=a-50;
}

if(input(pin_a4)==1){
output_low(pin_c1);              //desactivar rele
lcd_putc('\f');
set_pwm1_duty(0);                         //se apaga el pwm
return;
}
}
}

void corporal()
{
setup_timer_2(t2_div_by_1,249,1);           // configuracion pwm para una frecuencia de 1khz
setup_ccp1(ccp_pwm);                      // configura el modo de del registro pwm

while(true){
lcd_gotoxy(8,1);
printf(lcd_putc,"*** MENU RUN ***");
lcd_gotoxy(1,2);
printf(lcd_putc,"Ap. CORPORAL");
delay_ms(100);
set_pwm1_duty(b);                         // configura la resolucion del pwm

if(input(pin_a0)==1){                     // aumenta el ancho de pulso
a=a+50;
}

if(input(pin_a1)==1){                     // disminuye el ancho de pulso
a=a-50;
}

if(input(pin_a4)==1){
lcd_putc('\f');
set_pwm1_duty(0);//se apaga el pwm
a=1;
return;
}
}
}

void run_func(int numfunc){

switch (numfunc){

case fac:
lcd_putc('\f');
facial();
break;

case corp:
lcd_putc('\f');
corporal();
break;
}
}

void main()
{
char item=0;
char n_menus=2;
lcd_init();

      lcd_putc('\f');
      lcd_gotoxy(9,1);
      printf(lcd_putc,"***BIENVENIDO***\n");
      lcd_gotoxy(9,2);
      lcd_putc("RADIO FRECUENCIA");
      delay_ms(300);
      lcd_gotoxy(11,1);
      printf(lcd_putc,"***MARCA***\n");
      lcd_gotoxy(8,2);
      lcd_putc("******RENNAR******");
      delay_ms(300);
      

while(true){
if(input(pin_a1)==1){
item++;
delay_ms(100);
lcd_putc('\f');
}

if(item>(n_menus-1)){
item=0;
}

switch (item){

case 0:
do{
 if(input(pin_a3)==1){
delay_ms(80);

run_func(item);
      }
 
 if(input(pin_a1)==1){
      a=1;
   }
      lcd_gotoxy(9,1);
      printf(lcd_putc,"**MENU PRINCIPAL**\n");
      lcd_gotoxy(4,2);
      printf(lcd_putc,"*FACIAL*        *CORPORAL*\n");
      delay_ms(50);
      lcd_gotoxy(4,2);
      printf(lcd_putc,"                *CORPORAL*\n");
      delay_ms(50);
 }
 while(a==0);
 item++;
 a=0;
break;

case 1:

do{
   if(input(pin_a3)==1){
delay_ms(80);
run_func(item);
}
 
  if(input(pin_a1)==1){
      a=1;
   }
   lcd_gotoxy(9,1);
    printf(lcd_putc,"**MENU PRINCIPAL**\n");
    lcd_gotoxy(4,2);
    printf(lcd_putc,"*FACIAL*        *CORPORAL*\n");
   delay_ms(50);
    lcd_gotoxy(4,2);
    printf(lcd_putc,"*FACIAL*                  \n");
    delay_ms(50);
  }
   while(a==0);
   item++;
   a=0;
   break;
}
}
}


prototipo.JPG

Para el mismo proyecto de radio frecuencia tengo un programa prototipo, tiene un menú de bienvenida, selección de modo de trabajo (menú principal) y run, en el menú principal, el diseño que quiero es que titile ítem que voy a seleccionar, si lo hace, pero si conoces una manera mas eficiente para el pic 18f2550 para comparar te lo agradezco, ya te paso el código.

CSS:
#include <18f2550.h>
#fuses NOFCMEN, NOIESO, NOVREGEN
#use delay (CRYSTAL = 4 MHz, CLOCK = 4 MHz) 
#define LCD_DATA_PORT getenv("SFR:PORTB")
#define lcd_enable_pin pin_c5
#define lcd_rs_pin pin_c6
#define lcd_rw_pin pin_c7
#include <lcd.c>
#use standard_io(c)
#use standard_io(a)
int a=0;
int b=150;
enum funciones{fac,corp}; // asigno variables a la funcion

void facial()
{
output_high(pin_c1); //activa rele
setup_timer_2(t2_div_by_1,249,1);           // configuracion pwm para una frecuencia de 1khz
setup_ccp1(ccp_pwm);                      // configura el modo de del registro pwm

while(true){

lcd_gotoxy(8,1);
printf(lcd_putc,"*** MENU RUN ***");
lcd_gotoxy(1,2);
printf(lcd_putc,"Ap. FACIAL");
delay_ms(100);
set_pwm1_duty(b);                         // configura la resolucion del pwm

if(input(pin_a0)==1){                     // aumenta el ancho de pulso
a=a+50;
}

if(input(pin_a1)==1){                     // disminuye el ancho de pulso
a=a-50;
}

if(input(pin_a4)==1){
output_low(pin_c1);              //desactivar rele
lcd_putc('\f');
set_pwm1_duty(0);                         //se apaga el pwm
return;
}
}
}

void corporal()
{
setup_timer_2(t2_div_by_1,249,1);           // configuracion pwm para una frecuencia de 1khz
setup_ccp1(ccp_pwm);                      // configura el modo de del registro pwm

while(true){
lcd_gotoxy(8,1);
printf(lcd_putc,"*** MENU RUN ***");
lcd_gotoxy(1,2);
printf(lcd_putc,"Ap. CORPORAL");
delay_ms(100);
set_pwm1_duty(b);                         // configura la resolucion del pwm

if(input(pin_a0)==1){                     // aumenta el ancho de pulso
a=a+50;
}

if(input(pin_a1)==1){                     // disminuye el ancho de pulso
a=a-50;
}

if(input(pin_a4)==1){
lcd_putc('\f');
set_pwm1_duty(0);//se apaga el pwm
a=1;
return;
}
}
}

void run_func(int numfunc){

switch (numfunc){

case fac:
lcd_putc('\f');
facial();
break;

case corp:
lcd_putc('\f');
corporal();
break;
}
}

void main()
{
char item=0;
char n_menus=2;
lcd_init();

      lcd_putc('\f');
      lcd_gotoxy(9,1);
      printf(lcd_putc,"***BIENVENIDO***\n");
      lcd_gotoxy(9,2);
      lcd_putc("RADIO FRECUENCIA");
      delay_ms(300);
      lcd_gotoxy(11,1);
      printf(lcd_putc,"***MARCA***\n");
      lcd_gotoxy(8,2);
      lcd_putc("******RENNAR******");
      delay_ms(300);
      

while(true){
if(input(pin_a1)==1){
item++;
delay_ms(100);
lcd_putc('\f');
}

if(item>(n_menus-1)){
item=0;
}

switch (item){

case 0:
do{
 if(input(pin_a3)==1){
delay_ms(80);

run_func(item);
      }
 
 if(input(pin_a1)==1){
      a=1;
   }
      lcd_gotoxy(9,1);
      printf(lcd_putc,"**MENU PRINCIPAL**\n");
      lcd_gotoxy(4,2);
      printf(lcd_putc,"*FACIAL*        *CORPORAL*\n");
      delay_ms(50);
      lcd_gotoxy(4,2);
      printf(lcd_putc,"                *CORPORAL*\n");
      delay_ms(50);
 }
 while(a==0);
 item++;
 a=0;
break;

case 1:

do{
   if(input(pin_a3)==1){
delay_ms(80);
run_func(item);
}
 
  if(input(pin_a1)==1){
      a=1;
   }
   lcd_gotoxy(9,1);
    printf(lcd_putc,"**MENU PRINCIPAL**\n");
    lcd_gotoxy(4,2);
    printf(lcd_putc,"*FACIAL*        *CORPORAL*\n");
   delay_ms(50);
    lcd_gotoxy(4,2);
    printf(lcd_putc,"*FACIAL*                  \n");
    delay_ms(50);
  }
   while(a==0);
   item++;
   a=0;
   break;
}
}
}


prototipo.JPG
Buenas tardes [FONT=arial]D@rkbytes[/FONT] tendrás documentación de como programar este pic 18f2550 con el ccs compiler preferiblemente o con algún otro compilador? y gracias de antemano, feliz terde
 
Última edición:
Los métodos que existen para comparar, ya los estás empleando.
Lo que te recomiendo es lo siguiente:
Declara nombres para los pines.
Usa el tabulador para indentar el código y hacerlo más comprensible.
No uses printf si no vas a mostrar datos, si únicamente vas a escribir, con lcd_putc basta.
En tu caso es mejor usar input_state(PIN) que input(PIN)
Esto no lo estás usando:
#use standard_io(c)
#use standard_io(a)
Esta comparación:
if(input(pin_a1)==1)
{
a=1;
}
Se puede usar así nada más porque solo hay una instrucción a ejecutar:
if(input_state(PIN_A1)) a = 1;

Tienes 4 bits de sobra en el puerto B que puedes usar para otras cosas, porque la librería lcd.c es para 4 bits.

En fin, hay mucho por mejorar en ese código.
Por cierto, es un gran desperdicio usar un PIC18F2550 para ese proyecto.
 
Atrás
Arriba