Salu2 fans del lenguaje C
Ahora les comparto un programa que trabaja las 2 terminales PWM del PIC16F877A.
Lo utilicé para controlar 2 servos PWM que dependiendo el ancho del pulso, toman una posición en grados con un rango de 0° a 180°.
Este programa empieza enviando un ancho de pulso (ambos canales) y mediante Push buttons uno incremente o decrementa ese ancho de pulso.
Me sirvió mucho para checar los rangos de trabajo de los servos y saber con que cantidad de milisegundos a qué posición se iba el servo.
Usa LCD y 4 push buttons, 2 para cada servo, uno incremente el ancho de pulso y el otro lo decrementa.
La desventaja de mi programa es que usa cristal de 1.25MHz... algo difícil de conseguir
//Este programa da un periodo PWM de 13.1ms
//Santiago Villafuerte
//migsantiago
//Sirve para encontrar el rango de trabajo del DUTY time
//inicia en 2.5ms y el usuario sube o baja bit a bit ese rango
//Puede operar 2 señales PWM al mismo tiempo CCP1 y CCP2
//El DUTY actual saldrá en la LCD en hexadecimal
// Conexiones de la LCD:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
//Los resultados que obtuve son:
//Servo KRAFT KPS-21K
//Periodo=13.1ms
//DUTY para 0° = 0.6784ms (0x35)
//DUTY para 90° = 1.408ms (0x6e)
//DUTY para 180° = 2.112ms (0xa5)
//Resolución
//0xa5-0x35=0x70=112
// 180°/112=1.6071°
#include "16f877.h"
#use delay(clock=1250000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#include "lcd.c"
#use standard_io (D)
#use fast_io (c)
#use fast_io (b) //PB para subir o bajar DUTY time
//B7 sube PWM1
//B6 baja PWM1
//B5 sube PWM2
//B4 baja PWM2
void main (void)
{
long duty_pwm1; //duty pwm1
long duty_pwm2; //duty pwm2
set_tris_c (0x00); //Todo salida
set_tris_b (0xff); //todo entrada
//Duty inicial
duty_pwm1=0xc8; //200d
duty_pwm2=0xc8; //200d
//D=(0xc8)(1/1.25MHz)(16)=2.5ms
//Rutina LCD
lcd_init(); //Inicia LCD
lcd_putc("f"); //Limpia LCD
lcd_putc("Presione PB
+ o -"); //rtc
delay_ms(3000);
lcd_putc("f");
setup_timer_2(T2_DIV_BY_16,255,1); //PR2 = 255
//T=(PR2+1)4.Tosc.PRStm2
//T=(255+1)4.(1/1.25MHz)(16)=13.1ms
setup_ccp1(CCP_PWM); //PWM
setup_ccp2(CCP_PWM); //PWM
while(1)
{
if( input(PIN_B7) )
{
duty_pwm1++; //incrementa duty time PWM1
delay_ms(100); //espera se suelte PB
}
if( input(PIN_B6) )
{
duty_pwm1--; //decrementa duty time PWM1
delay_ms(100); //espera se suelte PB
}
if( input(PIN_B5) )
{
duty_pwm2++; //incrementa duty time PWM2
delay_ms(100); //espera se suelte PB
}
if( input(PIN_B4) )
{
duty_pwm2--; //decrementa duty time PWM2
delay_ms(100); //espera se suelte PB
}
lcd_putc("f"); //Limpia LCD
lcd_putc("PWM1 = ");
printf(lcd_putc,"%x",duty_pwm1); //escribe DUTY1 en hexadecimal
lcd_putc("
");
lcd_putc("PWM2 = ");
printf(lcd_putc,"%x",duty_pwm2); //escribe DUTY2 en hexadecimal
delay_ms(200); //Usuario lee
set_pwm1_duty(duty_pwm1); //saca duty actual
set_pwm2_duty(duty_pwm2); //saca duty actual
}
}