# PWM PIC 16F877x programacion en assembler



## toloteo (Sep 3, 2010)

En primer lugar quiero agradecer a este tipo de foros en los cuales nos permite aprender y salvar de dudas que son de gran importancia para la vida profesional del electronico.

Hola amigos mi duda esta en la programacion del pwm del pic 16f877x, quiero mover un servomotor, el servo es de la marca TowerPro y el modelo es SG90, es uno pequeño con capacidad de carga de 1.6 kg. hasta donde tengo entendido, un servomotor funciona a base de modulacion por anchos de pulso (PWM) pero al momento de programarlo no obtengo las posiciones que quiero, lo que no tengo bien en claro es de cuanto debe ser el periodo de mi pwm, pues se que si quiero que mi servo se mueva a la posicion 0º mi duty cycle de ser de 1 ms, posicion 90º, duty cycle=1.5 ms, posicion 180º, duty cycle=2 ms. Lo que no se es de cuanto debe ser el periodo del pwm. Espero respuestas y les estare muy agradecido por ellas. Saludos.


----------



## Pablet (Sep 3, 2010)

la mayoria de los servos funcionan a 50Hz.
Un saludo


----------



## nietzche (Sep 3, 2010)

lo malo es que el pic no genera señales de 50 hz, son me parece a partir de 300 hz, ademas no es tan preciso en cuanto a la generacion de el duty cicle porque solo tiene 10 bits de resolucion, recomiendo ampliamente usar un AVR que tiene 16 bits de resolucion


----------



## Pablet (Sep 3, 2010)

nietzche lo de la frecuencia minima dependera de la frecuencia de oscilacion que tu le pongas no? de todas formas siempre existe el modulo de comparacion para hacer el pwm o incluso se puede hacer con un timer.
Un saludo


----------



## nietzche (Sep 6, 2010)

OK, sabemos que en el registro PR2 sirve para indicar el periodo de la señal PWM ok?, este registro es solo de 10 bits, asi que el valor maximo que puede alcanzar en decimal es de: 1024

Pero en el manual dice que la formula para el periodo es:

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

Como queremos saber que valor hay que agregar al registro PR2 despejando queda:
PR2 = PWM Period

___________________________________ - 14 • TOSC •(TMR2 Prescale Value)


Ahora bien, la frecuencia es el inverso del periodo

PR2 = 1/Frecuencia

___________________________________ - 1

4 • TOSC •(TMR2 Prescale Value)

y queda :


PR2 = 1

______________________________________ - 1

Frecuencia • Tosc • (TMR2 Prescale Value)


Teniendo en cuenta que Tosc es = 4/frecuencia del reloj , y suponiendo que tenemos un cristal de reloj de 4 Mhz entonces 4/Tosc = .000001

Los servos trabajan a digamos 50 Hz, entonces poniendo datos y usando un prescaler a 16

PR2 = 1

______________________________________ - 1

50 • .000001 • (16)

Nos queda = 1249 y esto convertido a binario es = 10011100001 que son 11 bits de resolucion, como el PIC solo tiene 10 bits de resolucion no alcanza a generar esa frecuencia, es mas ni se puede escribir eso en el registro PR2. Una posible solucion es usar un cristal de 500 Khz, peroq quien diablos usa un cristal de ese tamaño, reduce la velocidad de todo el controlador.

Queda demostrado que no se pueden alcanzar frecuencias mas bajas, o bien tenemos que buscar un registro PR2 de mas bits como los que tienen los AVR que son de 16 bits.En esta pagina queda demostrado que no trabajan a esas frecuencias


PIC PWM Calculator & Code Generator

En donde dice: My PIC is clocked at : ponganle 4 Mhz

En donde dice: My PWM frequency must be : dejen en blanco para que genere todas las combinaciones posibles

En donde dice: My PWM duty cycle must be : pongan cualquier cosa, expresado en fracciones, es el % del duty cicle


Vean lo que les genera, y cual es la frecuencia minima, vallanle bajando el valor del cristal hasta que genera la frecuencia de 50 Hz.

Se puede generar 2 ms, con frecuencias altas pero el servo se hace inestable a frecuencias arriba de 250 Hz, empieza a vibrar.Si que se puede hacer con timer e interrupciones pero para que complicarnos la vida con eso si tenemos el modulo PWM.Por eso prefiero usar AVR`s para servos.

Gracias


----------



## Pablet (Sep 6, 2010)

nietzche te equivocas en un par de cosas, el registro PR2 no es de 10 bits, sino de 8, y tosc no es el tiempo de instruccion, sino el tiempo de oscilacion, osea la inversa la frecuencia de oscilacion. esta claro que con 4mhz no se puede, y la pregunta es si el pic puede generar frecuencias de 50Hz la respuesta es si, quiza no con el modulo ccp, pero si con los timers como has dicho. en mi opinion es mas la complicacion que tiene pasarse a un avr, sabiendo programar pic, que hacerlo con los timers. . .
un saludo


----------



## nietzche (Sep 6, 2010)

Lo siento, me equivoque, el CCP es el de 10 bits, pero aun asi trabajar con interrupciones me da mucha pereza. Tosc es el inverso dela frecuencia del cristal, la pagina lo demuestra


----------



## JJames (Mar 19, 2012)

Buenas tardes aqui desde Perú les mando un aporte sobre el tema pic16f877a+xtal=2Mhz+PR2=255

Como sería para un xtal =4Mhz


----------



## dmadrid2010 (Mar 25, 2012)

Hola compañeros, estoy tambien interesado en el tema ya que estoy trabajando en el control de un servo para un brazo robotico, inicialmente me encontre con el mismo problema sobre el valor de PR2 ya que éste es de 8 bits por tanto solo puede ser cargado con un maximo de 255. debido a que lo quiero hacer con el pwm del pic, utilicé el oscilador interno del pic 16f883 a 500khz y el TMR2 de 16, con eso el valor de PR2 es aprox 155. Simulo en proteus y efectivamente me aparece que trabaja a 50 hz. El problema es en el montaje ya que el servo no me funciona como deberia, se queda como atrancado. En fin continuaré trabajando para ver  que puedo  diagnosticar del problema y les estare comentando.


Adios


----------



## Galder02 (Jun 22, 2012)

y por que mejor no usas la instruccion pulsout del compilador pic basic pro?? asi te evitas de andar utilizando los modulos ccp y pwm del pic, yo con esa funcion e estado trabajando, tmb quiero hacer un brazo robotico pero controlado desde la pc, y ya logre hacer el codigo, mi unico problema es a la hora de seleccionar motores para mover cada uno, el que estaba energizado previamente, perdera la fuerza por que se energiza otro, aun no e podido aclarar ese problema, pero sigo intentando. saludos


----------



## thenoi (Oct 26, 2012)

Al anterior: eso te pasa por irte por lo mas simple si usaras los timers y las interrupciones podrias controlar sin problemas muchos servos


----------



## periklo10 (Mar 28, 2013)

Hola colegas electrónicos 

Mi pregunta es acerca del pwm, como se fija el periodo?

se que existe la formula:

PWMperiodo=[(PR2)+1]*4*Tosc*(TMR2preescala)

Pero sinceramente no se que significa TMR2preescala ni PR2

El oscilador que ocupo es de 4MHZ, necesito un periodo de 20ms y el pic es el 16f877a, es para un servomotor.

Tengo un código en ASM de PWM de la escuela, pero sinceramente no recuerdo como se fijaba el periodo, se los adjunto para ver si me pueden ayudar, SaLudos

Gracias de antemano.


----------



## Nuyel (Mar 29, 2013)

TMR2preescala es un divisor que se aplica a la fuente de reloj (posibles valores 1, 4, 16) PR2 es el "Registro de Periodo del Timer2", el numero hasta el que cuenta y luego reinicia, el problema igual será que no se puede generar ese periodo, la frecuencia del reloj es muy alta y el tiempo demasiado largo, para generar este periodo con ese oscilador se puede lograr por software usando la interrupción del Timer2 y contando los pasos, esto permite usar un mayor tiempo e incluso para mejorar la resolución ayuda emplear un oscilador de mayor frecuencia.


----------

