Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

01/03/2016 #1


Controlar brillo de LED con PWM en PIC16F628A
Buenas, recurro a este foro para pedir ayuda, si es que alguien sabe como hacer para encender un led pero de a poco , cambiando su brillo, intensidad, a través del tiempo y una vez encendido apagarlo lentamente de la misma manera. Sé como hacer encender y apagar led, solo que se hagan lentamente cambiando su brillo de menos a más a traves del tiempo no se como hacerlo en software Programo en C con CCS.
y tengo esto por ahora pero no me funciona:

Código:
 #include "C:\\librerias\\16F628A.h"
#use delay(clock = 20000000)
#fuses HS, NOWDT,PUT,BROWNOUT,NOMCLR,NOLVP,PROTECT,NOCPD
#use fast_io(A) // estandar de entrada y salidas de los puertos, necesario para que funcione
#use fast_io(B)
#zero_ram
int data=0,time=0;
void main(){ 
 
set_tris_b(0b00000000);
delay_ms(50); 
setup_timer_2(T2_DIV_BY_1,254,1); 
setup_ccp1(ccp_pwm); 
 
while(1){ 
   data=data+5; 
   if(data==255){data=0;} 
   delay_ms(10+time); 
   set_pwm1_duty(data); 
  } 
}
...
01/03/2016 #2

Avatar de ruben90

Eso se realiza utilizando PWM, verifica si el PIC contiene el módulo CCP (modo PWM) ya que será más fácil programarlo. Si no, tendrás que calcular los tiempos de encendido y apagado del Puerto, esto se realiza calculando los tiempos.
************************************************** ***
Revisando el datasheet del PIC (páginas 58 y 59) si contiene el modulo.
Lo que necesitas es declarar los registros y calcular el periodo (1kHz, 2kHz,10kHz) que te funcione.
El datasheet contiene las fórmulas.

Si utilizas el CCS ahí un libro muy bueno, no me acuerdo muy bien del nombre pero en Google búscalo como "Libro CCS Proteus".
Espero haberte ayudado, Saludos.
01/03/2016 #3


Si lo tiene, si en el codigo lo estoy utilizando y nisiquiera prende RB3, no se si me falta agregar cosas al diseño de proteus... e hize todos los calculos que necesitaba 4kHZ y obtuve este codigo nuevo:

Código:
#include "C:\\librerias\\16F628A.h"
#use delay(clock = 20000000)
#fuses HS, NOWDT,PUT,BROWNOUT,NOMCLR,NOLVP,PROTECT,NOCPD
#use fast_io(A) // estandar de entrada y salidas de los puertos, necesario para que funcione
#use fast_io(B)
#zero_ram

int16 data=0;
void main(){ 
 
set_tris_b(0b00000000);
setup_timer_2(T2_DIV_BY_16,78,1); //78 por formula desbordamiento timer2
setup_ccp1(ccp_pwm); // habilita el pwm
 
while(1){    
	if (data==313){
	data=0;
	}
	data=data+2; 
	set_pwm1_duty(data);
	delay_ms(25); 

} 
   
}
y el proteus:
Imágenes Adjuntas
Tipo de Archivo: png 111.png (18,3 KB (Kilobytes), 28 visitas)
01/03/2016 #4

Avatar de ruben90

Yo utilizo mikroC, así que no puedo decirte si está bien o mal en CCS, pero como te comenté del libro es bueno, viene bien explicado, te aseguro que resuelves tus dudas.

Yo utilizo los registros del PIC, pocas veces las librerías. Primero defino los registros: PR2, T2CON y CCPR1CON.
Ya después utilizo solo el registro CCPR1L para controlar el duty cycle de la señal y me funciona de maravilla.
01/03/2016 #5
Moderador

Avatar de D@rkbytes

thekako dijo: Ver Mensaje
si es que alguien sabe cómo hacer para encender un led pero de a poco, cambiando su brillo, intensidad, a través del tiempo y una vez encendido apagarlo lentamente de la misma manera.
Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
Es muy sencillo hacerlo de esa forma y el código no es complicado.

Adjunto el ejemplo con simulación. (Oscilograma)
Físicamente se nota un efecto de variación de luminosidad en el LED, lento y estable que sube y baja.
Esto viene siendo como las lámparas de obstrucción en sistemas de seguridad y señalamiento.
Archivos Adjuntos
Tipo de Archivo: rar 16F628A LED PWM.rar (31,6 KB (Kilobytes), 212 visitas)
01/03/2016 #6

Avatar de yorsk2004

Yo también quiero hacer lo mismo pero que el ciclo de trabajo del PWM dependa de una entrada análoga. ¿Cual uC podría usar para este fin?
01/03/2016 #7
Moderador

Avatar de D@rkbytes

Uno que tenga conversor análogo a digital, y puede ser con uno pequeño como el PIC12F675.
02/03/2016 #8


D@rkbytes dijo: Ver Mensaje
Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
Es muy sencillo hacerlo de esa forma y el código no es complicado.

Adjunto el ejemplo con simulación. (Oscilograma)
Físicamente se nota un efecto de variación de luminosidad en el LED, lento y estable que sube y baja.

Hola muchas gracias por responderme , tengo algunas dudas, puedo probarlo colocando un led en el puerto del osciloscopio en la simulacion o no notaria los cambios de brillo?
Otra duda cuando copio tu codigo y lo intento compilar con MPLAB me tira el siguiente error sabes a que se debe? "Undefined Identifier T0_INTERNAL" intente googlearlo pero no encontre algo similar..

Desde ya muchas gracias por la ayuda

Reedit: cambie TO_INTERNAL por RTCC_INTERNAL y pudo compilar, afecta en algo o es cosa del compilador?
Otra cosa, cual es la formula para calcular el valor del set_timer0 dado que uso un reloj de 20Mhz y en el osciloscopio se ve rara la onda, gracias!
02/03/2016 #9
Moderador

Avatar de D@rkbytes

thekako dijo: Ver Mensaje
¿Puedo probarlo colocando un LED en el puerto del osciloscopio en la simulación o no notaría los cambios de brillo?
No se pueden ver los cambios de intensidad en el LED durante simulación con PWM.
thekako dijo: Ver Mensaje
Cuando copio tu código y lo intento compilar con MPLAB me tira el siguiente error. ¿Sabes a que se debe? "Undefined Identifier T0_INTERNAL"
Intenté googlearlo pero no encontré algo similar.
Eso se debe a que tu compilador ya es obsoleto y no contiene las nuevas constantes.
thekako dijo: Ver Mensaje
Reedit: cambie TO_INTERNAL por RTCC_INTERNAL y pudo compilar, afecta en algo o es cosa del compilador?
No afecta. Esa constante es de versiones anteriores y también está disponible en la versión actual.
thekako dijo: Ver Mensaje
¿Cuál es la fórmula para calcular el valor del set_timer0, dado que uso un reloj de 20 Mhz. y en el osciloscopio se ve rara la onda.
La fórmula viene en la hoja de datos al igual que toda la información que requieras sobre el PIC.
En el ejemplo usé un desborde cada 30 ms. teniendo 4 MHz con el oscilador interno.

Nota que si cambias la frecuencia de oscilación, también se debe cambiar la configuración del Timer 2.
Si no haces eso también se verá afectada la frecuencia del PWM.
También existe otro detalle importante cuando se aumenta la frecuencia de reloj.
Los tiempos de desborde para los Timers disminuyen, y por consecuencia se logran frecuencias más altas para el PWM.

Con 20 MHz. El desborde máximo para el Timer 0, será de 13.1072 ms. estando el prescaler a 1:256
Así que la variación en los cambios de intensidad sobre el LED serán más rápido.

Entonces es importante que tomes eso en cuenta para elegir la frecuencia de operación del microcontrolador.
02/03/2016 #10


Muchas gracias por la información amigo, me has aclarado un montón

sabes que he estado probando casi todo el día y he llegado a un codigo coherente con ccs en donde la onda debiese variar subiendo y bajando el brillo del led, pero por alguna razón el PIN no está recibiendo nada por lo que no oscila nada en ella, me podrías guiar en donde se encuentra posiblemente el error que no he logrado solucionarlo aún por favor, si Revisas la imagen te darás cuenta que por RB3 no sale nada, se encuentra en azul y no en rojo :c
:

Código:
#include "C:\librerias\16F628A.h"
#fuses intrc_io, nocpd, noprotect, nomclr
#use delay(clock = 4M)

int variable=0;

void main(){
set_tris_b(0b00000000); 
setup_timer_2(T2_DIV_BY_16,254,1);
setup_ccp1(ccp_pwm);

while(1){
	variable=variable+5;
	if(variable=255){
		for(variable=255;variable<0;variable=variable-5){
		set_pwm1_duty(variable);
		delay_ms(20);
		}
	}
	set_pwm1_duty(variable);
	delay_ms(20);
}

}
Imágenes Adjuntas
Tipo de Archivo: jpg Sin título.jpg (66,7 KB (Kilobytes), 17 visitas)
02/03/2016 #11
Moderador

Avatar de D@rkbytes

En lenguaje C debes igualar usando == y no un solo =
Esto es cuando comparas, cuando asignas si se usa un solo signo =

La variable "variable" no puede llegar a ser menor de 0 porque es una variable sin signo.

En C también es más fácil que escribas; variable += 5; y no: variable = variable + 5;
02/03/2016 #12

Avatar de ruben90

prueba con esto:
Código:
void main() {
TRISB = 0x00;
PORTB = 0x00;
    PR2 = 0xF9; //1kHz
  T2CON = 0x05;
CCP1CON = 0x0C;
while(1) {
CCPR1L = 0x7D; //50%
}
}
02/03/2016 #13
Moderador

Avatar de D@rkbytes

ruben90 dijo: Ver Mensaje
prueba con esto:
Código:
void main() {
TRISB = 0x00;
PORTB = 0x00;
    PR2 = 0xF9; //1kHz
  T2CON = 0x05;
CCP1CON = 0x0C;
while(1) {
CCPR1L = 0x7D; //50%
}
}
Ese programa únicamente genera una frecuencia de 1 KHz con ciclo activo fijo, y lo que se requiere es que aumente y disminuya el ciclo activo constantemente, así como lo expuse en el ejemplo que subí.

Aparte no tiene sentido incluir dentro del bucle el registro CCPR1L si siempre aplicas el mismo valor.
Y en PIC C Compiler no se usan esos registros porque tiene funciones predefinidas que lo hacen.
Por lo tanto ese código sin la declaración de registros, dará errores si se compila en PCWHD.
02/03/2016 #14


muchas gracias por la ayuda, les informo que modifique lo que me dijeron y aún así sigue sin salida por el pin RB3, adujunto imagen para que me crean :p no se a que se deberá :c

el código lo dejé así:
Código:
#include "C:\librerias\16F628A.h"
#fuses intrc_io, nocpd, noprotect, nomclr
#use delay(clock = 4000000)

int variable=0;

void main(){
set_tris_b(0b00000000); 
setup_timer_2(T2_DIV_BY_16,254,1);
setup_ccp1(ccp_pwm);

while(1){
	variable=variable+5;
	if(variable>=255){ //probé con == y >= y no funciona
		for(variable=255;variable<=5;variable=variable-5){
		set_pwm1_duty(variable);
		delay_ms(20);
		}
	}
	set_pwm1_duty(variable);
	delay_ms(20);
}

}
Imágenes Adjuntas
Tipo de Archivo: png 1.png (38,4 KB (Kilobytes), 17 visitas)
02/03/2016 #15
Moderador

Avatar de D@rkbytes

¿Y por qué no implementas el programa del ejemplo que subí?
Hace lo que requieres. ¿No? Eso era lo que requerías en tu primer post.
02/03/2016 #16


es que con tu código se debía de presionar un boton para que cambiara el pulso y yo necesito que siempre haga lo mismo subir de 0 a 100 y bajar de 100 a 0 infinitamente , no logre modificar tu codigo para hacer esto, por eso no lo segui ocupando jeje
02/03/2016 #17
Moderador

Avatar de D@rkbytes

Creo que estás equivocado. El programa que subí hace los cambios automáticamente.
No se tiene que presionar ningún botón para que realice la variación del ciclo activo.
De hecho el único botón que tiene es el de reset, y es opcional.

Prueba el circuito físicamente y lo podrás comprobar.
03/03/2016 #18


entonces debo probarlo fisicamente?, por que con el osciloscopio no me muestra ninguna onda si no presiono el boton :p
mira adjuntare cuando no apreto nada(sin) y cuando presiono el boton(con):
Imágenes Adjuntas
Tipo de Archivo: png sin.png (38,3 KB (Kilobytes), 19 visitas)
Tipo de Archivo: jpg conboton.jpg (84,4 KB (Kilobytes), 19 visitas)
03/03/2016 #19
Moderador

Avatar de D@rkbytes

Algo debes estar haciendo mal. No realices modificaciones al programa ni al diseño.
El circuito empieza a correr el programa desde el inicio, tanto en simulación como físicamente.
Si puedes ver en la ventana "Watch Window" que la variable "ciclo" aumenta y disminuye, quiere decir que el programa está funcionando.

Subí dos simulaciones, una en proteus 7.10 y la otra en proteus 8.3
En ambas se muestra la forma de onda como empieza el ciclo activo desde 0 % a 100 % y luego inversamente.

Físicamente también funciona y ahí si se puede ver la actividad en el brillo del LED.

También se pueden tomar los oscilogramas físicos en tiempo real.

Ciclo activo al mínimo.


Ciclo activo a la mitad. (50 %)


Y ciclo activo al máximo.


Las capturas físicas son aproximadas al ciclo, porque es algo complicado atinarle.
Imágenes Adjuntas
Tipo de Archivo: png Min_Duty.png (7,4 KB (Kilobytes), 147 visitas)
Tipo de Archivo: png Mid_Duty.png (7,9 KB (Kilobytes), 145 visitas)
Tipo de Archivo: png Max_Duty.png (7,7 KB (Kilobytes), 145 visitas)
04/03/2016 #20

Avatar de yorsk2004

D@rkbytes si solo quiero un "Duty Cycle" fijo, digamos 25%, entonces me podrías asesorar con el código en C CCS.

Otra cuestión la frecuencia del PWM se puede configurar digamos a 200 Hz.

Gracias de antemano D@rkbytes.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.