Ayuda con código para PWM en PIC, lenguaje C

Hola!

Tengo un proyecto en el que tengo que usar un PWM para controlar la intensidad de brillo de un LED. He encontrado el siguiente ejemplo, pero me gustaría que alguien me explicara su funcionamiento, porque tengo ciertas dudas al respecto del código. El código es el siguiente:

Código:
 #include <p18F4520.h>
 #include <timers.h>
 
 long int count;
 long int i;
 int signal_high;
 int signal_low;
 
 void main()
 {
        
        TRISD = 0x00;
        
 while(1)
        {       //following loop increases the pwm duty cycle from 0% to 100% on portD
                        for(signal_high=1; signal_high<100; signal_high++)
                        {
 
                                for(count=0; count<signal_high; count++)
                                {
                                        PORTD = 0x01;
                                        
                                }
                                signal_low=100-signal_high;
                                for(count=0; count<signal_low; count++)
                                {
                                        PORTD = 0x00;
                                }
                        }
        //following loop decreases the pwm duty cycle from 100% to 0% on portD
                        for(signal_high=1; signal_high<100; signal_high++)
                        {
 
                                for(count=0; count<signal_high; count++)
                                {
                                        PORTD = 0x00;
                                }
                                signal_low=100-signal_high;
                                for(count=0; count<signal_low; count++)
                                {
                                        PORTD = 0x01;
                                }
                        }
 
        }
        
 }

Mis dudas son las siguientes: Dentro de los ciclos de incremento y decremento del brillo del led, nada más veo que asignan PORTD = 0x00 o PORTD = 0x01, pero ¿cómo es que varía la intensidad con esto? (Perdónenme si suena una pregunta demasiado tonta, pero la verdad tiene muy poco tiempo que empecé a usar los PICs).
Lo que pretendo hacer es mediante un ADC modificar el valor con un potenciómetro, esta parte ya esta lista y la tengo codificada para que el valor lo almacene en una variable que se llama potADC, pero quisiera saber cómo es que cambia el valor en este código para poder cambiarlo y poner el valor que obtengo del potenciómetro. Aparte que pretendo hacerlo con interrupciones y no dentro del ciclo infinito en el main.
El PIC que estoy utilizando no tiene CCP, así que hay que construir el PWM a manita.

Saludos,
 
Hola!

Tengo un proyecto en el que tengo que usar un PWM para controlar la intensidad de brillo de un LED. He encontrado el siguiente ejemplo, pero me gustaría que alguien me explicara su funcionamiento, porque tengo ciertas dudas al respecto del código. El código es el siguiente:

Código:
 #include <p18F4520.h>
 #include <timers.h>
 
 long int count;
 long int i;
 int signal_high;
 int signal_low;
 
 void main()
 {
        
        TRISD = 0x00;
        
 while(1)
        {       //following loop increases the pwm duty cycle from 0% to 100% on portD
                        for(signal_high=1; signal_high<100; signal_high++)
                        {
 
                                for(count=0; count<signal_high; count++)
                                {
                                        PORTD = 0x01;
                                        
                                }
                                signal_low=100-signal_high;
                                for(count=0; count<signal_low; count++)
                                {
                                        PORTD = 0x00;
                                }
                        }
        //following loop decreases the pwm duty cycle from 100% to 0% on portD
                        for(signal_high=1; signal_high<100; signal_high++)
                        {
 
                                for(count=0; count<signal_high; count++)
                                {
                                        PORTD = 0x00;
                                }
                                signal_low=100-signal_high;
                                for(count=0; count<signal_low; count++)
                                {
                                        PORTD = 0x01;
                                }
                        }
 
        }
        
 }
Mis dudas son las siguientes: Dentro de los ciclos de incremento y decremento del brillo del led, nada más veo que asignan PORTD = 0x00 o PORTD = 0x01, pero ¿cómo es que varía la intensidad con esto? (Perdónenme si suena una pregunta demasiado tonta, pero la verdad tiene muy poco tiempo que empecé a usar los PICs).
Lo que pretendo hacer es mediante un ADC modificar el valor con un potenciómetro, esta parte ya esta lista y la tengo codificada para que el valor lo almacene en una variable que se llama potADC, pero quisiera saber cómo es que cambia el valor en este código para poder cambiarlo y poner el valor que obtengo del potenciómetro. Aparte que pretendo hacerlo con interrupciones y no dentro del ciclo infinito en el main.
El PIC que estoy utilizando no tiene CCP, así que hay que construir el PWM a manita.

Saludos,

El puerto D es digital, cuando pone 0x01 lo que hace es encender el primer pin del puerto ya que en binario es "00000001".

El programa que muestras utiliza una variable como contador(count) que va sumando uno, manteniendo el pin encendido "0x01" o apagado "0x00". Utiliza tambien signal_high y signal_low para que se puede modifical el tiempo que esta a uno la señal en cada ciclo.
 
Ok, entonces si yo quisiera asignar el valor del potADC como duty cycle, lo tengo que asignar a signal_low o signal_high dependiendo de si el valor es menor o mayor, verdad?
 
Ok, entonces si yo quisiera asignar el valor del potADC como duty cycle, lo tengo que asignar a signal_low o signal_high dependiendo de si el valor es menor o mayor, verdad?

Si pero siempre respecto 100 que es el valor máximo de cont, para un ciclo del 100%. Por ejemplo si el potenciometro al máximo te devuelve 1.023, porque tu ADC es de 10 bits. Tienes que hacer.

signal_high=(potenciometro*100)/1023
signal_low=100-signal_high

También de deberías de poner un delay dentro del for, ya que si el tiempo es muy corto al pin no le da tiempo a cambiar de estado, ya que se ejecuta cada instrucción cada 1 us (con un reloj de 4 Mhz). El ancho de pulso de tu señal es de 100uS (aprox 10 Khz), me parece muy corto.
 
Última edición:
hola como estan..? tengo un problema estoy haciendo un sigue lineas y necesito recibir una señal analogica de un sensor infrarrojo con un pic y de acuerdo a esa señal enviarla a una salida PWM para que me controle la velocidad del motor de acuerdo a la lectura del sensor como aria eso si tienen un codigo o algo asi donde lo pueda ver, no tengo mucho tiempo programando pic ademas no se que pic seria el mar recomendable para eso necesito controlar dos motores, ademas por lo que he investigado el PWM y el convertidor analogico digital me podrian hacer el proceso muy lento necesito un pic que trabaje muy rapido o no se si lo podria hacer con dos pic...ya que es para una competencia de velocidad cualquier ayuda gracias de antemano cualquier idea bienvenida sea... DIOS LES BENDIGA
 
Atrás
Arriba