//Este es un comentario
//Bits de configuracion o directivas de preprocesador
//#pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
//#pragma config CPUDIV = OSC2_PLL3// System Clock Postscaler Selection bits ([Primary Oscillator Src: /2][96 MHz PLL Src: /3])
#pragma config FOSC = XT_XT // Oscillator Selection bits (XT oscillator, PLL enabled (XTPLL))
#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOR = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
#pragma config CCP2MX = ON // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#include <xc.h>
#define _XTAL_FREQ 4000000UL //Frecuencia de trabajo actual
unsigned int temporal = 0;
unsigned int servo = 1; // Servos para seleccionar Servo1 = 1 / Servo2 = 0
//ANGULOS ACTUALES DE LOS SERVO 1 Y 2
unsigned int ang_servo1 = 1000;
unsigned int ang_servo2 = 1000;
unsigned int val_min = 1000;
unsigned int val_max = 2000;
void Configurar_TMR0(void){
INTCONbits.GIE = 0;
T0CON = 0x88;//1000 0100
INTCONbits.TMR0IE = 1; // Permitir el desbordamiento del Timer0
INTCONbits.GIE = 1;
}
void ingresoTmr0(unsigned int tiempo){ //1000
temporal = (65535 - tiempo);
TMR0L = temporal;
temporal = (65535 - tiempo);
TMR0H = temporal >>8;
T0CONbits.TMR0ON = 1;
}
void Configurar_Puertos(void){
ADCON1 = 0x0F;
TRISBbits.RB0 = 1; //BOTON PARA IZQUIERDA DEL SERVO 1
TRISBbits.RB1 = 1; //BOTON PARA DERECHA DEL SERVO 1
TRISBbits.RB2 = 1; //BOTON PARA IZQUIERDA DEL SERVO 2
TRISBbits.RB3 = 1; //BOTON PARA DERECHA DEL SERVO 2
TRISEbits.RE0 = 0; //SERVO 1
TRISEbits.RE1 = 0; //SERVO 2
}
void main(void){
Configurar_TMR0();
Configurar_Puertos();
T0CONbits.TMR0ON = 0;
//ESTABLECER UN VALOR INICIAL
//SERVO 1 EN BAJO
while(1){
//PARA EL SERVO 1 IZQUIERDA
if(PORTBbits.RB0 == 1){ //ANG_SERVO1 = 1000
__delay_ms(15);
if(ang_servo1 == val_min){
ang_servo1 = val_min;
servo = 1;
}
else{
ang_servo1 = ang_servo1 - 50;
servo = 1;
}
}
//PARA EL SERVO 1 DERECHA
if(PORTBbits.RB1 == 1){
__delay_ms(15);
if(ang_servo1 == val_max){
ang_servo1 = val_max;
servo = 1;
}
else{
ang_servo1 = ang_servo1 + 50;
servo = 1;
}
}
//PARA EL SERVO2 IZQUIERDA
if(PORTBbits.RB2 == 1){
__delay_ms(15);
if(ang_servo2 > val_min){
ang_servo2 = ang_servo2 - 50;
servo = 0;
}
else{
ang_servo2 = val_min;
servo = 0;
}
}
//PARA EL SERVO2 DERECHA
if(PORTBbits.RB3 == 1){
__delay_ms(15);
if(ang_servo2 < val_max){
ang_servo2 = ang_servo2 + 50;
servo = 0;
}
else{
ang_servo2 = val_max;
servo = 0;
}
}
}
}
//IMAGINANDO QUE INGRESE 1000
void __interrupt (high_priority) Tmr0ISR(void){
if(INTCONbits.TMR0IF){
switch(servo){
case 1:
if(PORTEbits.RE0){
ingresoTmr0(ang_servo1);
LATEbits.LE0 = 0;
}
else{
ingresoTmr0(20000-ang_servo1);
LATEbits.LE0 = 1;
}
INTCONbits.TMR0IF = 0;
//CONTO 2ms (ESTANDO EN BAJO) / SALTA A LA INTERRUPCION Y AHORA CUENTA
//19ms (ESTANDO EN ALTO)
break;
case 0:
if(PORTEbits.RE1){
ingresoTmr0(ang_servo2);
LATEbits.LE1 = 0;
}
else{
ingresoTmr0(20000-ang_servo2);
LATEbits.LE1 = 1;
}
INTCONbits.TMR0IF = 0;
break;
}
}
}
void Configurar_TMR0(void){esta el T0CON configurado como 10001000
Un problema que veo sin siquiera ponerme a pensar en el codigo es:
- Estas usando el Timer 0 como si fuera de 16 bits.
temporal = (65535 - tiempo);
TMR0L = temporal;
Y no lo iniciaste como 16 bits... Es decir cambiar el bit: T08BIT: Timer0 8-Bit/16-Bit Control bit
inicia en 1 lo cual lo esta como 8 bits.
Hice un codigo mas sencillo y pues da lo mismo... le di 2 ms en alto y 18ms en bajo, pero no es precisio, me da 1.88 ms en alto
Target halted. Stopwatch cycle count = 15041 (1,880125 ms)Target halted. Stopwatch cycle count = 18002 (18,002 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Target halted. Stopwatch cycle count = 18000 (18 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Target halted. Stopwatch cycle count = 18002 (18,002 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Target halted. Stopwatch cycle count = 18000 (18 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Target halted. Stopwatch cycle count = 18002 (18,002 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Target halted. Stopwatch cycle count = 18000 (18 ms)
Target halted. Stopwatch cycle count = 2001 (2,001 ms)
Por supuesto esto no tiene demasiados pasos, ya que tenemos 10 pasos para dar. Podes achicar mas la interrupcion.
OK KILLERJC, el PIC16F684 tiene 4 PWM, a ver si saco un rato y aplico el código que pusiste a los 4 PWM.
Saludos!!!
OK KILLERJC, el PIC16F684 tiene 4 PWM, a ver si saco un rato y aplico el código que pusiste a los 4 PWM.
Saludos!!!
Ojo que no estoy usando el modulo PWM (solo el PWM), estoy usando el CCP en modo Compare. Ese PIC tiene 1 solo PWM con 4 salidas, no 4 PWM independientes, Y si queres muchas salidas mas y liberar el micro, podes poner algo como el PCA9685, que tenes modulos a bajo precio "Arduino"