# PWM con PIC16F877A



## tatocasta (Sep 30, 2007)

Hola a todos.

Esta vez los molesto con un problemilla que tengo. 
Resulta que necesito generar una señal con un 16F877A, que tenga frecuencia variable entre 1Hz y 100Hz a la cual debo tambien poderle controlar en ancho del pulso, pero con el modulo CCP no me deja trabajar a frecuencias tan bajas!.

Si alguien tiene el codigo para generar esta señal con PWM por Software y frecuencia variable o me puede decir como lohago, le quedare inmensamente agradecido!

Adios a tod@s!


----------



## Paloky (Oct 1, 2007)

Hola. 

Para poder generar un PWM con esa frecuencia tan pequeña, tendrás que utilizar un timer.

Debes programarlo con el mayor tiempo que te permita.  Luego tienes que crearte una variable "contador"  que se incremente cada vez que entres en la interrupción.

Mejor te lo pongo con un ejemplo.  (en C para el compilador CCS)

La frecuencia del reloj es de 20MHz.


```
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                       //No Watch Dog Timer
#FUSES HS                               //Crystal osc 20MHz
#FUSES NOPUT                        //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                   //No Debug mode for ICD
#FUSES NOBROWNOUT           //No brownout reset
#FUSES NOLVP                        //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                       //No EE protection
#FUSES NOWRT                      //Program memory not write protected

#use delay(clock=20000000)


#define salida  PIN_B0;         // Pin de Salida del PWM
int16 contador=0;
int16 frec=0;                          // Variable que indica la frecuencia del PWM
int16 anchura=0;                  // Anchura del PWM


// 1Hz = 1 segundo = 1000mS
// 100 Hz = 0.01 segundos  = 10mS
// La interrupción se genera cada 1mS
#int_TIMER2
TIMER2_isr() 
{
contador++;

if (contador<=anchura)
       output_high(salida);    
else
      output_low(salida);
 
if (contador==frec)   contador==0;      // Reseteamos el contador

}




void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,19,16);    // Interrupcion cada 1 mS
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER2);         // Habilitamos la Interrupcion
   enable_interrupts(GLOBAL);

   
   while(1)
   {
   
      //Generamos un PWM de 10mS (100Hz) con una anchura del 50%
      frec=10;
      anchura=5;
   
   
      //Generamos un PWM de 1 segundo (1 Hz) con una anchura del 30%
      frec=1000;
      anchura=300;
      //
      
   }  // Fin del While(1)

}
```


Espero que te sirva.

Un Saludo.


----------



## patolofr (Dic 2, 2009)

ando haciendo un brazo robotico de 2 grados de libertad... soy nuevo con esto del pwm.. ando con ensablador o pic basic pero tmb es nuevo...  no se muy bien como funciones eso del pwm.. si em puediran ayudar.. el programa de arriba solo es para C vdd? estoy haciendo con Labview

alguien me puede ayudar??
o alguien k me explique como esta el rollo eso del pwm y si me pudieran pasar el programa y eplicado


----------



## manuel:_zazu (Feb 10, 2010)

compilo tu programa y me sale error linea 32 33 y 34 me dice q salida deberia ser un valor numerico... a ver si me dicen como lo corrijo

Lo correji, solo tuve q poner en vez de salida pin_b0 pero esto quiere decir q no funciona el define salida pin_b0 y ya varias veces me encuentro con este problema, quiero definir una variable o una salida y no me deja me sale el msn de error: Debe aparecer un valor numerico aqui alguien q me aclare las cosas, por lo menos q me confirmen si es un error del compilador ccs


----------



## spitzelf (Mar 14, 2010)

hola estaba buscando un codigo para generar el pwm por software aparte del problema que menciona manuel me di cuenta que en la linea donde resetea el contador esta asi:
contador==0;
pero debe de tener solo un signo quedando de esta manera
contador=0;

bueno solo es un comentario gracias por el codigo


----------



## ajburbano (Abr 17, 2010)

Hola mi gente......soy nuevo en el foro y estoy construyendo un robot que siga una linea y recoja pelotas, necesito configurar el pwm interno del pic 16f877a en asm.....para un servo el cual va a trabajar como pala para las pelotas.......les agradeceria mucho...........si me colaboran...


----------



## spidermanpc (Oct 27, 2010)

manuel:zazu dijo: 





> pero esto quiere decir q no funciona el define salida pin_b0 y ya varias veces me encuentro con este problema, quiero definir una variable o una salida y no me deja me sale el msn de error: Debe aparecer un valor numerico aqui alguien q me aclare las cosas, por lo menos q me confirmen si es un error del compilador ccs



Aunque quizas sea muy tarde para responderte el error que te sale en el define es porque esta instruccion no lleva ; al final, por lo tanto te quedaria asi

#define salida PIN_B0

pruebala ahi y veras que compila

Saludos


----------

