# Cuantos PWM en un Pic16Fxx puedo implementar?



## SCR13PT (Jun 9, 2006)

Buenas a todos...

Continuo desarrollando mi proyecto (Proyector RGB con leds alta potencia)...

Despues de haber estado buscando alternativas, en un principio, me decante por utilizar 3 conversores ADC via Bus I2C para manejar cada color, pero despues de haber estado consultando he allado la conclusion de que con 3 PWM (uno para cada color) podria aprovechar mas la potencia, asi como economizar en costes de montaje del circuito. 
Pero surge una serie de dudas... ¿Puedo implementar 3 PWM en un mismo Pic? ¿Que pic seria el mas adecuado si de cara a un futuro se va a aumentar la complejidad del dispositivo? ¿Cual creeis que seria el procedimiento para implementar los 3 PWM en un mismo pic?

Un Saludo


----------



## maunix (Jun 9, 2006)

SCR13PT dijo:
			
		

> Buenas a todos...
> 
> Continuo desarrollando mi proyecto (Proyector RGB con leds alta potencia)...
> 
> ...



Todo depende de los requerimientos técnicos que necesite tu PWM pero por software podrías hacer un PWM por cada pin que tenga tu PIC valiéndote del algún timer interno.  

La diferencia radica en que la máxima frecuencia posible sería cada vez más baja además que irías perdiendo precisión.

Si quieres varios PWM por hardware hay un pic 18F que tiene varios PWM no me acuerdo bien cual, pero sé que los hay.

Creo que debieras definir un poco más tus requerimientos técnicos así te podemos seguir ayudando.  

Saludos


----------



## SCR13PT (Jun 9, 2006)

Ante todo gracias por la respuesta, da gusto ver como aun hay gente que esta "ahi"...

Os comento, lo que necesito es poder implementar 3 PWM con una resolucion de 8 bits, a una frecuencia de muestreo de 30Hz. La idea es, desde un mismo Pic, poder controlar la intensidad luminica de 3 Leds (Rojo, Verde y Azul) para asi poder crear una lampara capaz de mostrar *256* (8 bits Red) * *256* (8 bits Green) * *256* (8 bits Blue) = *16777216 Colores*. He elegido una frecuencia de muestreo de 30 Hz, puesto que el ojo humano no percibe la intermitencia luminica a partir de los 26 Hz.

Segun recomendaciones de posteadores de este mismo foro (y doy las gracias por la ayuda), en vez de utilizar un PIC16F84, voy a utilizar un *PIC16F876/877* para el proyecto, incluso, pensandolo bien, es mas potente, mas I/O...

Lo que quiero es que el Pic sea capaz de manejar los 3 PWM dependiendo del valor almacenado en 3 variables.

RED = Variable de 8 Bits (almacena la intensidad luminica del Rojo) = PWM1
GREEN = Variable de 8 Bits (almacena la intensidad luminica del Verde) = PWM2
BLUE = Variable de 8 Bits (almacena la intensidad luminica del Azul) = PWM3

Por lo que si yo almaceno en cada variable un valor, y este es lanzado por cada PWM podre tener en los Leds el color "que yo quiera"... 

No se si me he explicado..., en un futuro, a este mismo pic le añadire la posvilidad de poder controlar cada PWM por un canal DMX (Protocolo muy utilizado en iluminacion espectacular). Pero en un principio eso no me preocupa, lo que me interesa es, ¿Como puedo implementar esos 3 PWM en un mismo PIC y que cada PWM me proyecte el valor de cada variable?


Detalles:

Si a alguna de las variables le doy valor 00000000 el led permanece apagado.
Si a alguna de las variables le doy valor 10000000 el led permanece a media intensidad.
Si a alguna de las variables le doy valor 11111111 el led luze a su maxima intensidad.

Entonces, poseo 256 posiciones e intensidades luminicas a cada led.

Espero recibir vuestra ayuda...

Un cordial saludo


----------



## maunix (Jun 9, 2006)

*SCR13PT* te paso una respuesta que dí al mismo tema en otro foro.  De todas formas, la posteo y te paso el link del tema.  http://www.demo-1.com.ar/foros/index.php?topic=12136.0


No importa si es C o ensamblador, se puede hacer con ambos solo que en ensamlador (sobre todo en los 16F) como se es más directo uno aprovecha mucho mas los ciclos de reloj y puede obtener mas frecuencia de PWM funcionando a menos MHz.

Ejemplo

Cada PWM tendrá 3 variables.
PWMxCiclos --> contador de la cantidad de ciclos que pasaron desde que comenzó de nuevo el PWM
PWMxPreriodo --> cantidad de ciclos que dura el PWM
PWMxCicloActivo --> cantidad de ciclos que dura el PWM en alto.

Donde periodo y ciclo activo sean por ejemplo variables de 8 bits y donde CicloActivo sea <= a Periodo (porque cicloactivo no está expresado en procentaje sino en ciclos de instrucción).

Luego

1) Usar una interrupción con un timer, fijado por ejemplo en 500us
2) Al llegar ese tiempo se enciende un flag de otra variable
3) Ese flag de la variable es el encargado de incrementar todos los contadores PWMxCiclos de los PWM.
4) Se verifica si PWMxCiclos >= PWMxPeriodo en cuyo caso se pondra en 0 el contador y en Activo la SALIDA y sigue con el PWM siguiente,  sino va a 5)
5) Se verifica si PWMxCiclos es > PWMxCicloActivo si es así lo pone en BAJO la salida por terminar el duty cycle

De esa forma se pueden tener un PWM por cada pin que se tenga en el PIC, pero por supuesto como dije antes a mas PWM menor será la frecuencia final que se podrá obtener y además la aplicación está prácticamente dedicada a esto.   


Respecto a la elección del PIC, eso lo dejo a tu criterio.  Más pines no significa más potencia si solo usaras o necesitas 3 pines para tu aplicación. 

Más memoria, bueno la puedes lograr con un pic de menos pines pero más memoria de programa.   

Ya te irás acostumbrando a eso, además depende de cuan exigente sea tu aplicación en cuanto a limitaciones de costos.

Saludos


----------



## SCR13PT (Jun 9, 2006)

Buenas a todos...

Se agradece la respuesta... incluso leyendola dos veces, aclara mucho parte de las dudas que habian surgido. Respecto a la frecuencia del PWM, creo que por software no debo tener ningun problema puesto que como comentais y si no he leido mal, con un micro funcionando a 4 Mhz y con 9 PWM implementados mediante software, trabajaria cada uno a unos 100Mhz. Por un lado tema resuelto, puesto que yo necesito 3 PWM y a una frecuencia de 30 Mhz, por lo que el micro ha de ir "sobrado". Pero ahi la gran incognita:

¿Existe alguna libreria en la que yo le diga por que PIN quiero el PWM, la frecuencia y el valor y este me lo muestre a la salida...?

Realmente creo haberme metido en un proyecto algo ambicioso para mis conocimientos de asm... pero bueno, todo es empezar... 


Un saludo y mil gracias de antemano


----------



## maunix (Jun 9, 2006)

SCR13PT dijo:
			
		

> Buenas a todos...
> 
> Se agradece la respuesta... incluso leyendola dos veces, aclara mucho parte de las dudas que habian surgido. Respecto a la frecuencia del PWM, creo que por software no debo tener ningun problema puesto que como comentais y si no he leido mal, con un micro funcionando a 4 Mhz y con 9 PWM implementados mediante software, trabajaria cada uno a unos 100Mhz. Por un lado tema resuelto, puesto que yo necesito 3 PWM y a una frecuencia de 30 Mhz, por lo que el micro ha de ir "sobrado".


Yo no he dicho tal cosa!  100Mhz ? Si el pic anda a 4Mhz como haces para generar un PWM de 100Mhz solo con el firmware.  

Antes mencionaste 30Hz y ahora 30Mhz ? Hay una sensible diferencia de 29,99997 millones de ciclos...

Por favor haz bien tus cálculos o estaras partiendo mal de entrada.




			
				SCR13PT dijo:
			
		

> ¿Existe alguna libreria en la que yo le diga por que PIN quiero el PWM, la frecuencia y el valor y este me lo muestre a la salida...?
> 
> Realmente creo haberme metido en un proyecto algo ambicioso para mis conocimientos de asm... pero bueno, todo es empezar...



No conozco, de hecho ese pequeño detalle que puse fue algo que se me ocurrió en el momento pero nunca tuve la necesidad de tantos PWM.

Saludos


----------



## SCR13PT (Jun 9, 2006)

Mil perdones.... Cuando me referia a 100Mhz, era a 100Hz y cuando dije a 30Mhz, quise decir a 30Hz... Es de enteder que no es lo mismo 100 ciclos por segundo que 100 millones de ciclos por segundo... jejeje 

Respecto a la posibilidad de implementar 3 PWM en un PIC... Continuo invesigando... Porque..

Si no he leido mal el PIC16F777 posee 3 PWM por hardware, ¿Eso quiere decir que podria usar a la vez los 3 PWM del PIC16F777? Seria una alternativa, y en caso afirmativo, ¿Como?


Me abordan las dudas

Un Saludo


----------



## maunix (Jun 9, 2006)

SCR13PT dijo:
			
		

> Si no he leido mal el PIC16F777 posee 3 PWM por hardware, ¿Eso quiere decir que podria usar a la vez los 3 PWM del PIC16F777? Seria una alternativa, y en caso afirmativo, ¿Como?



Asi es, acabo de leer las especificaciones y tiene 3PWM.  

Si, podrías utilizar los 3 a la vez, programarlos y dejar que funcionen solos mientras tu software se dedica a otras cosas.

¿Cómo? Bueno, leyendo el datasheet de cómo se configuran.  No es algo difícil, requiere que pongas esfuerzo de tu parte y te puedo ayudar a que lo saques andando pero no haré la tarea por tí.  Ojo, no de mala voluntad simplemente me gusta ayudar a quienes ponen empeño en algo pero dar 'servidas las cosas' no es mi estilo.

Saludos


----------



## SCR13PT (Jun 11, 2006)

Buenas a todos:

Continuo trabajando en el tema de los PWM para hacer el poyector RGB. Gracias a *magio* he conseguido ver como hacer funcionar el PWM en un PIC16F877 que es el que estoy usando de pruebas, este solo tiene 2 PWM por Hardware, pero para hacer las pruebas me biene muy bien, luego ya se implementará el 3er PWM del PIC16f777. Como Comento e hecho funcionar los PWM pero hay algo que no me ha quedado muy claro. Expongo el codigo:
*
Codigo asm:*


```
periodo equ .255 ; PWM periodo, lo que ocupa un flanco de subida y uno de bajada (un 1 y un 0)
duty equ .200 ; PWM duty del ciclo, el tiempo que está en 1



;------------------------------------

	bsf	     status,5

	clrf	      trisc

	bcf	     status,5

;------------------------------------
;------------- PWM 1 ----------------
;------------------------------------

	[b]movlw	     04h[/b]

	movwf	     t2con

	bsf	        status,rp0

	movlw	     periodo		;Determina la duracion del Ciclo Completo

	movwf	     pr2

	bcf	        status,5

	[b]movlw	.63[/b]

	movwf	     ccp1con

	movlw	     duty		;Determina la Duración del Ciclo de Duty

	movwf	     ccpr1l

;------------------------------------
;------------- PWM 2 ----------------
;------------------------------------

	[b]movlw	     04h[/b]

	movwf	     t2con

	bsf	        status,rp0

	movlw	     periodo		;Determina la duracion del Ciclo Completo

	movwf	     pr2

	bcf	        status,5

	[b]movlw	.63[/b]

	movwf	    ccp2con

	movlw	    duty		;Determina la Duración del Ciclo de Duty

	movwf	    ccpr2l

;------------------------------------
;------------- PROGRAM --------------
;------------------------------------



fin	nop

	goto	fin







	end
```
Ok, mas o menos ya tengo pillao el tema, en el fracmento aterior pongo a funcionar los dos PWM del pic. Pero cosas que no me han quedado claras:

¿Como determino la frecuencia de trabajo del PWM? ¿Que queire decir el codigo que he resaltado en negrita?¿Cuales serian lo valores para obtener un PWM con 8 bits de resolucion?

Gracias de antemano


----------



## SCR13PT (Jun 13, 2006)

Ok... no recibi respuesta en el foro, pero ya empiezo a allarlas, aunque un poquito de alluda no vendria mal 

Respecto al fracmento del codigo anterior

*movlw .63 

movwf ccp1con *

He averiguado que determina la resolucion del PWM en este caso esta configurado para funcionar a 8 bits.

¿Pero como determino el periodo? ¿Como hago para darle el valor (de 0 a 255) y me lo saque el PWM? Un saludo


----------



## maunix (Jun 18, 2006)

SCR13PT dijo:
			
		

> Ok... no recibi respuesta en el foro, pero ya empiezo a allarlas, aunque un poquito de alluda no vendria mal


No he estado conectado. Lo siento. 



			
				SCR13PT dijo:
			
		

> Respecto al fracmento del codigo anterior
> 
> *movlw .63
> 
> ...


tienes a mano un datasheet? ahí esta bien explicado que significa cada bit del registro CCP1CON.




			
				SCR13PT dijo:
			
		

> ¿Pero como determino el periodo? ¿Como hago para darle el valor (de 0 a 255) y me lo saque el PWM? Un saludo




La frecuencia, se define como la inversa del período.  Frec = 1/T 

El período se calcula asi.

*PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)*

De acuerdo al valor del registro PR2 ,  al clock de tu pic y al valor del prescaler del timer2,  te dará la frecuencia del PWM.


Saludos


----------



## VOLVOX (Oct 9, 2006)

Disculpen los pics de picaxe tienen PWM


----------



## maunix (Oct 9, 2006)

VOLVOX dijo:
			
		

> Disculpen los pics de picaxe tienen PWM



¿Es una pregunta o una afirmación?


----------



## VOLVOX (Oct 10, 2006)

Es una pregunta -sorry


----------



## maunix (Oct 10, 2006)

VOLVOX dijo:
			
		

> Es una pregunta -sorry



Si, algunos sí, te recomiendo leas este link http://www.rev-ed.co.uk/docs/axe001_techfaq.pdf


----------



## Aristides (Oct 24, 2006)

Creo que el microcontrolador que tiene más posibilidades de generar varios PWM simultáneos, es el Propeller de Parallax, ya que tiene multifunción en lugar de multitarea, si alguno viaja a MDQ se lo puedo mostrar andando:
http://www.parallax.com/propeller/index.asp


----------



## Luis Quintero (Ene 23, 2007)

hola,yo hice lo mismo de controlar un led rgb por medio de pwm y lo hice con un pic 16f84a a 4 Mhz, de hecho hice una lampara para controlar la intensidad de 4 leds rgb usando 12 salidas de pwm,el hecho es que cada led lo controlo por el mismo ciclo y periodo,pero haciendo modificaciones se pueden manejar independientemente las 12 salidas,les pego el programa por si a alguien le sirve.


```
//proyec
#include <16f84a.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#define periodo 125      //125 * 80microS =~10mS
#define duty    125      //parte del periodo que encenderan las lamparas
#define Tiempo_int   30 //50 * 125 * 80microS =~500mS entre cambio y cambio de intensidad


int  c1=0;        //rojo
int  c2=0;        //azul
int  c3=0;        //verde
int i2;          //variable control de ciclo de retardo en intensidades
int i;           //variable que controla el ciclo del periodo del pwm  
int d = 0;   //control porta
int z = 0;   //control portb

                     





            




//////////////////////////////////////////////////////////////////////////////////////////////////
void tiempo()
              {
              delay_ms(4000);
              }
              //led1_portb_0
             
          
void  ciclo_PWM_10mS(){


                                  for (i=1;i<periodo; i++)   //control periodo
                                    {                                                
                                      
                                    if (i<=c1)           //control intensidad  rojo 
                                    {                    
                                     bit_set(z,0);       //led1_portb_0   //Led2=port_b_bits_543(var) 
                                     bit_set(z,3);       //led2_portb_3  //Led3=port_a&portb_bits_a&1_(v)b&76(ar)
                                     bit_set(z,6);       //led3_portb_6    //Led4=port_a_bits_320(var)
                                     bit_set(d,0);       //led4_porta_0
                                    }
                                    else
                                    {
                                    bit_clear(z,0);      //led1_portb_0
                                    bit_clear(z,3);      //led2_portb_3  
                                    bit_clear(z,6);      //led3_portb_6
                                    bit_clear(d,0);      //led4_porta_0
                                    }
                                 
                                    if (i<=c2)           //control intensidad azul
                                    {
                                    bit_set(z,1);       //led1_portb_1     
                                    bit_set(z,4);       //led2_portb_4 
                                    bit_set(z,7);       //led3_portb_7       
                                    bit_set(d,2);       //led4_porta_2
                                    }
                                    else
                                    {
                                    bit_clear(z,1);    //led1_portb_1 
                                    bit_clear(z,4);   //led2_portb_4
                                    bit_clear(z,7);   //led3_portb_7
                                    bit_clear(d,2);   //led4_porta_2
                                    }
                                 
                                    if (i<=c3)           //control intensidad verde
                                    {
                                    bit_set(z,2);        //led1_portb_2    
                                    bit_set(z,5);        //led2_portb_5
                                    bit_set(d,1);        //led3_porta_1 
                                    bit_set(d,3);        //led4_porta_3
                                    }
                                    else
                                    {
                                    bit_clear(z,2);     //led1_portb_2  
                                    bit_clear(z,5);     //led2_portb_5 
                                    bit_clear(d,1);     //led3_porta_1 
                                    bit_clear(d,3);     //led4_porta_3
                                    }
                                    output_b(z);
                                    output_a(d);
                                 
                                   }
                                    delay_us(40);                                  
                                                              
                                                       
                                 }

/////////////////////////////////////////////////////////////////////////////////////////////////////

void  tonos_mas(){                                  
                 
                         
                           for (c1=1,c2=1,c3=0; c1<duty ; c1++,c2++) //;control de tono magenta
                           {
                              
                               for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad                              
                              ciclo_PWM_10mS()  ;                                                
                              
                       }
               }
                  
            


void  tonos_2_mas(){
                                          

                 for (c3=1,c1=1,c2=0; c3<duty; c3++,c1++)         //;control de tono amarillo
                 {       
                 
                           for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad
                              
                              ciclo_PWM_10mS()  ;                                                        
                              
                          
                  }
                  
               }   



void  tonos_3_mas(){
                                          

                 for (c3=1,c1=0,c2=1; c3<duty; c3++,c2++)         //;control de tono cyan
                 {       
                 
                           for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad
                              
                              ciclo_PWM_10mS()  ;                                                        
                              
                          
                  }
                  
               }   



void  tonos_menos(){                                  
                 
                         
                           for (c1=duty,c2=duty,c3=0; c1>1 ; c1--,c2--) //;control de tono magenta
                           {
                              
                               for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad
                              
                              ciclo_PWM_10mS()  ;                                                
                              
                       }
               }




void  tonos_2_menos(){                                  
                 
                         
                           for (c1=duty,c2=0,c3=duty; c1>1 ; c1--,c3--) //;control de tono amarillo
                           {
                              
                               for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad
                              
                              ciclo_PWM_10mS()  ;                                                
                              
                       }
               } 
                                   
            
void  tonos_3_menos(){
                                          

                 for (c3=duty,c1=0,c2=duty; c3>1; c3--,c2--)         //;control de tono cyan
                 {       
                 
                           for (i2=1; i2<Tiempo_int; i2++)      //;espera entre incrementos de intensidad
                              
                              ciclo_PWM_10mS()  ;                                                        
                              
                          
                  }
                  
               }          
            
            




void negro()                //color negro                                      
               {
                z=0;
                d=0;
                output_b(z);
                output_a(d);
                tiempo();
                }


void blanco()             //color blanco
                {
                     
                           
                     z=d=255;
                     output_b(z);
                     output_a(d);
                     tiempo();
                     z=d=0;
                     output_b(z);
                     output_a(d);
                     
                        
                }
                
                
                                                            
                                                            
                
                                                         //b%76543210  //b%76543210
                                                         //B%arvarvar  //A%xxxxvavr                
  void rojo()                     //color rojo           //b%01001001  //a%xxxx0001
                {
                 
                   
                  output_b(0x49);         
                  output_a(0x01);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
                                              
                }              
                
 void   verde()        //color verde                           
                                                         //b%76543210  //b%76543210
                                                         //B%arvarvar  //A%xxxxvavr    
                                                         //B%00100100  //A%xxxx1010
               {
                  output_b(0x24);        
                  output_a(0x0a);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
               }
                
void   azul()             //color azul


                                                            
                                                         //b%76543210  //b%76543210
                                                         //B%arvarvar  //A%xxxxvavr    
                                                         //B%10010010  //A%xxxx0100               
                {
                  output_b(0x92);         
                  output_a(0x04);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
               }


void  amarillo()         //color amarillo

                                                         //b%76543210  //b%76543210
                                                         //B%arvarvar  //A%xxxxvavr    
                                                         //B%01101101  //A%xxxx1011     


                  {
                  output_b(0x6d);         
                  output_a(0x0b);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
                  }
                  
void  cyan()         //color cyan
                                              //b%76543210  //b%76543210
                                              //B%arvarvar  //A%xxxxvavr    
                                              //B%10110110  //A%xxxx1110     



                  {
                  output_b(0xb6);         
                  output_a(0x0e);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
                  }              
                  
 void  magenta()         //color magenta
 
                                  
                                              //b%76543210  //b%76543210
                                              //B%arvarvar  //A%xxxxvavr    
                                              //B%11011011  //A%xxxx0101     
                  {
                  output_b(0xdb);         
                  output_a(0x05);
                  tiempo();
                  z=d=0;
                  output_b(z);
                  output_a(d);
                  }                               
                  
///////////////////////////////////////////////////////////////////////////////////////////////////////////






 int  main ()
           
                    {                          //salida al puerto b=0
         
                  while (true)
                           {
                           
                           
                         //   negro();                 //(0, 0, 0) es negro
                            blanco();                //(255, 255, 255) es blanco  
                            rojo();                  //(255, 0, 0) es rojo
                            tonos_mas();
                            tonos_menos();
                            verde();                 //(0, 255, 0) es verde
                            tonos_2_mas(); 
                            tonos_2_menos(); 
                            azul();    
                            tonos_3_mas();
                            tonos_3_menos();
                            amarillo();            //(255, 255, 0) es amarillo
                            cyan();                //(0, 255, 255) es cyan
                            magenta();             //(255, 0, 255) es magenta
                           
                            
                           
                            z=d=0;
                            output_b(z);
                            output_a(d);
                           }
                              return(0);
                           
                   }
```
 
                      saludos.


----------



## zidaemon (Ene 29, 2007)

Mejor utiliza un pic de bajo coste como un pic16f628, tengo un programa que puede manejar tres pwm, sin utilizar ninguno de los que trae por hardware. Con esto te quiero decir, que puedes tener mas de 10 PWM independientes. Todo por Software. Lo que haace este circiuto, es un juego de tres luces que encienden gradualmente una despues de otra.


```
;***********************************
;	         Hurive Sis	               
;      
;      
;	  Juego de 3 Luces por PWM       
;							
;Salida leds:Rb0,Rb1,Rb2		
;	   Oscilador Interno del Pic	
;Visitar la pagina electronica para
;lo relacionado con este circuito	                
;									                                                
;	Compilado en MPLAB IDE v7.31	
;	Mexico DF. Octubre del 2006	
;***********************************  
LIST P=16C628A
#INCLUDE <P16F628A.INC>	

PH0		EQU		0X20 ;aqui va el numero de intensidad del PWM1
PH1		EQU		0X21 ;aqui va el numero de intensidad del PWM2
PH2		EQU		0X22 ;aqui va el numero de intensidad del PWM3

CONT		EQU		0X23
CONT2		EQU		0X24

C21		EQU		0X25 ;registros para retardos
C22		EQU		0X26
C23		EQU		0X27


#DEFINE		TIEMPO2A 	0XFF ;TIEMPOS PARA RETARDO 2
#DEFINE		TIEMPO2B	0XFF
#DEFINE		TIEMPO2C	0X7F

#DEFINE		PMW0	PORTB,0
#DEFINE		PMW1	PORTB,1
#DEFINE		PMW2	PORTB,2

		ORG	0X00

		MOVLW	0X00
		MOVLW	0X07
		MOVWF	CMCON
		BSF	STATUS,5
		CLRF	TRISA
		CLRF	TRISB
		BCF	STATUS,5
		CLRF	CONT2
		CLRF	PORTB

;*****	PROGRAMA MAIN	********
MAIN		CALL	RETARDO
		MOVLW	0XFF
		MOVWF	PH2
		CLRF	PH0
		CLRF	PH1

MAIN1		CALL	F13  ;Prende gradualmente PWM1, almismo tiempo
		INCF	PH0  ; que apaga PWM3
		BSF	PMW0
		DECFSZ	PH2
		GOTO 	MAIN1
		CALL 	RETARDO

MAIN2		CALL	F12
		INCF	PH1
		BSF	PMW1
		DECFSZ	PH0
		GOTO	MAIN2
		CALL	 RETARDO

MAIN3		CALL	F23
		INCF	PH2
		BSF	PMW2
		DECFSZ	PH1
		GOTO	MAIN3
		CALL	MAIN

;*****	RETARDO	******

RETARDO		MOVLW	TIEMPO2A
			MOVWF	C23
CICLO23		MOVLW 	TIEMPO2B
			MOVWF	C22
CICLO22		MOVLW	TIEMPO2C
			MOVWF	C21
CICLO21		DECFSZ	C21
			GOTO	CICLO21
			DECFSZ	C22
			GOTO	CICLO22
			DECFSZ	C23
			GOTO 	CICLO23
			RETLW	0

;*****	SUBRUTINAS	******
F13		MOVLW	0X00
		MOVWF	CONT
		BSF		PMW0
		BSF		PMW2
UNO		MOVF	CONT,W
		SUBWF	PH0,W
		BTFSS	STATUS,0
		BCF		PMW0
		MOVF	CONT,W
		SUBWF	PH2,W
		BTFSS	STATUS,0
		BCF		PMW2
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP

		INCF	CONT
		MOVF	CONT,W
		XORLW	0XFF
		BTFSS	STATUS,2
		GOTO	UNO
		RETLW	0

F12		MOVLW	0X00
		MOVWF	CONT
		BSF		PMW0
		BSF		PMW1
DOS		MOVF	CONT,W
		SUBWF	PH0,W
		BTFSS	STATUS,0
		BCF		PMW0
		MOVF	CONT,W
		SUBWF	PH1,W
		BTFSS	STATUS,0
		BCF		PMW1
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP

		INCF	CONT
		MOVF	CONT,W
		XORLW	0XFF
		BTFSS	STATUS,2
		GOTO	DOS
		RETLW	0

F23		MOVLW	0X00
		MOVWF	CONT
		BSF		PMW1
		BSF		PMW2
TRES	MOVF	CONT,W
		SUBWF	PH1,W
		BTFSS	STATUS,0
		BCF		PMW1
		MOVF	CONT,W
		SUBWF	PH2,W
		BTFSS	STATUS,0
		BCF		PMW2
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP

		INCF	CONT
		MOVF	CONT,W
		XORLW	0XFF
		BTFSS	STATUS,2
		GOTO	TRES
		RETLW	0

		END
```

Saludos de Hurive Radik Zidaemon Uribe


----------



## Raúl Galván (Abr 27, 2007)

La frecuencia, se define como la inversa del período.  Frec = 1/T 

El período se calcula asi.

*PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)*

_______________________________________________________

  Disculpa quisiera un poco de ayuda para programar el PIC16F873A, Tengo problemas a la hora de calcular la frecuencai del PWM que biene integrado en el chip, lo necesito que funcione a 60 *Hz *(si solo utilizo el predivisor la minima frecuencia qie obtengo anda alrededor de *244 Hz*) si utilizo en posdivisor con valor de 5 obtengo la frecuencia deseada pero no se que susede con el ciclo útil (en un divisor de frecuencia con contadores TTL (digitales) el ciclo útil siempre se mantiene al 50%) y mi duda es como se comporta el posdivisor ¿mantiene la relación en %? o se comporta como un divisor común y corriente.

 Por favor si pudieras ayudarme te lo agradeceria: si tienes las respuestas enviane que valores de veben cargar en los registros PR2, TMR2 Prescaler, Poscaler y CCPRxL


----------



## Maco1717 (May 7, 2007)

Hola mira esto:

http://ww1.microchip.com/downloads/en/AppNotes/01074A.pdf

no es en esamblador, esta en c pero para mi es mejor.
suerte


----------



## Raúl Galván (May 17, 2007)

Maco1717 dijo:
			
		

> Hola mira esto:
> 
> http://ww1.microchip.com/downloads/en/AppNotes/01074A.pdf
> 
> ...



________________________________________________________
PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)

Basicamente lo que necesito es saber que valores debo cargar el los registros:
PR2=?
TMR2 Prescaler=?
TMR2 Proscaler=?
PWM Pperiodo

aunque me parese interesante como camviar de color un led.


----------



## edwin625 (Ago 13, 2008)

Hola Yo tambien hice un programa en ccs para manejar leds Rrgb con el pic 16f877 saque señales pwm por los tres puertos de este pic por el portb,portc,portd, y me funciono perfectamente, el unico punto es que mientras vallas utilizando mas pines con señales pwm pierdes precision. pero con un oscilador de 20mhz no tuve problemas


----------



## Jodorro (Jul 15, 2009)

Hola, escribo aqui por no abrir tema nuevo. A1q espero q alguien q pueda ayudarme lea esto. Estoy haciendo una lampara RGB con un programa q encontre por internet, q con algunas modificaciones conseguí hacer funcionar y la verdad q va perfectamente(los PWM son por software y sacados por el portB), solo que ahora qeria añadir un pulsador al circuito para que una vez lo pulse, se pare el color en el que este hasta nueva pulsacion. He estado probando con interrupciones, pero no consigo hacer q se pare en el color que esta, sino que me pone uno de los tres colores RGB y la verdad esq no se q hacer. Si quereis os puedo pasar el codigo para que alguien me diga como implementarlo o me aconseje un poco.

En fin, espero alguna respuesta. Muchas gracias de antemano.

Saludos a todos!


----------



## buzzzer (Jul 16, 2009)

Luis Quintero dijo:
			
		

> hola,yo hice lo mismo de controlar un led rgb por medio de pwm y lo hice con un pic 16f84a a 4 Mhz, de hecho hice una lampara para controlar la intensidad de 4 leds rgb usando 12 salidas de pwm,el hecho es que cada led lo controlo por el mismo ciclo y periodo,pero haciendo modificaciones se pueden manejar independientemente las 12 salidas,les pego el programa por si a alguien le sirve.
> 
> 
> ```
> ...



perdon por mi ignorancia, soy nuevo en esto de los pics y ando de autodidacta...   por que medio controlas los leds RGB es decir, como introduces los valores para obtener un resultado en tus leds?

muchas gracias de antemano, si alguien me contesta


----------



## Jodorro (Jul 16, 2009)

¿Alguien me puede dar una opcion para que al pulsar un boton (pulsador) el cambio de colores q estaba haciendo automatico, se pare y se quede en el color que estuviera en el momento de pulsarlo? Os puedo pasar el codifo .asm que estoy utilizando por si os sirve de referencia, pero esq como yo lo tengo ya he probado con interrupciones y no funciona, solo se me para en el verde, el rojo o el azul, no en el color del momento de pulsar. 

Saludos!


----------



## edgarios (Abr 6, 2012)

Sería bueno tener el diseño del circuito usado para el software que vemos aquí......  en un principio utilice  el PIC  en su puertoB = 0,1,2 con sus respectivas resistencias limitadoras...  la conexion a VSS &  VDD...   pero no funcionó....

En tu software seria bueno anexar (aunque no es mandatorio..) la linea correspondiente al "bit configuration"....  yo usé la siguiente configuración..:

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 



Saludos..!



zidaemon dijo:


> Mejor utiliza un pic de bajo coste como un pic16f628, tengo un programa que puede manejar tres pwm, sin utilizar ninguno de los que trae por hardware. Con esto te quiero decir, que puedes tener mas de 10 PWM independientes. Todo por Software. Lo que haace este circiuto, es un juego de tres luces que encienden gradualmente una despues de otra.
> 
> 
> ```
> ...


----------

