la otra prueba es usar un cristal de 20MHz y ver si el timer -previamente configurado para el cristal- funciona correctamente.
PRUEBAS CRISTAL DE 12MHz
Acabo de probar el siguiente código con un cristal de 12MHz
#include <18F13K50.h>
#rom int8 0x300000 = {0x00}//Cambia los fuses del USB,
#rom int8 0x300001 = {0x32}//Cambia los fuses del cristal que es equivalente a poner #fuses HS, PLLEN, PCLKEN
#use delay(clock=12000000)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5, stream=PC)
#define UNO PIN_C4
const long desbordamiento = 50536;//5ms
long t = desbordamiento+4500;//1500us de ton
int1 flag_1 = 0;
int1 flagRTCC_1 = 0;
long valTIMER=0; //Tiene que ser un long debido a que el timer1 es un long, timer0 es un int
#int_timer1 //Subrutina de interrupción por TIMER1
void isr_timer1(void)
{
flagRTCC_1=1;
set_timer1(desbordamiento);
}
//PROGRAMA PRINCIPAL
void main(void) {
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
set_timer1(desbordamiento); //Vtmr1 = 65536 - (1s * ( 12000000Hz / 4 ) / prescaler ) 200us -> Vtmr1=5536 set_timer1(0x15A0);
setup_ccp1(CCP_PWM); //ccp1 modo PWM //Si lo ponemos arriba me da que no funciona, siempre va primero la declaración de variables
enable_interrupts(global);// Habilita interrupciones
while (TRUE)
{
if(flagRTCC_1==1)
{
flagRTCC_1=0;
output_high(UNO);
flag_1=1;
}
if(flag_1==1)
{
valTIMER=get_TIMER1();
if(valTIMER>t)//1,5ms->10036 0.5ms->7036 0.1ms->5836 2.3ms->12436 set_timer1(0x15A0); MAX->33500 MIN->10500
{
output_low(UNO);
flag_1=0;
}
}
//Fin Para el servo1
}//Fin while(TRUE)
}//Fin main(void)
Dándome como resultado un ton de 370us y un periodo de 1250us. Lógicamente lo vuelvo a poner en el proteus pero esta vez con un cristal de 12MHz y funciona perfectamente...
Ahora probando el siguiente código, que es idéntico al anterior sólo que cambiando los fuses:
#include <18F13K50.h>
#fuses HS, NOWDT, NOPROTECT, NOLVP
#fuses USBDIV1 //USB clock source comes from PLL no divide
#fuses CPUDIV1 //No System Clock Postscaler
//Estos fuses son equivalentes a #rom int8 0x300000 = {0x00} y #rom int8 0x300001 = {0xC2}
#use delay(clock=12000000)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5, stream=PC)
#define UNO PIN_C4
const long desbordamiento = 50536;//5ms
long t = desbordamiento+4500;//1500us de ton
int1 flag_1 = 0;
int1 flagRTCC_1 = 0;
long valTIMER=0; //Tiene que ser un long debido a que el timer1 es un long, timer0 es un int
#int_timer1 //Subrutina de interrupción por TIMER1
void isr_timer1(void)
{
flagRTCC_1=1;
set_timer1(desbordamiento);
}
//PROGRAMA PRINCIPAL
void main(void) {
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
set_timer1(desbordamiento); //Vtmr1 = 65536 - (1s * ( 12000000Hz / 4 ) / prescaler ) 200us -> Vtmr1=5536 set_timer1(0x15A0);
setup_ccp1(CCP_PWM); //ccp1 modo PWM //Si lo ponemos arriba me da que no funciona, siempre va primero la declaración de variables
enable_interrupts(global);// Habilita interrupciones
while (TRUE)
{
if(flagRTCC_1==1)
{
flagRTCC_1=0;
output_high(UNO);
flag_1=1;
}
if(flag_1==1)
{
valTIMER=get_TIMER1();
if(valTIMER>t)//1,5ms->10036 0.5ms->7036 0.1ms->5836 2.3ms->12436 set_timer1(0x15A0); MAX->33500 MIN->10500
{
output_low(UNO);
flag_1=0;
}
}
//Fin Para el servo1
}//Fin while(TRUE)
}//Fin main(void)
Funciona perfectamente con un cristal de 12MHz, es decir un ton=1500us y periodo=5000us
PRUEBAS CRISTAL DE 40MHz
#include <18F13K50.h>
#rom int8 0x300000 = {0x00}//Cambia los fuses del USB,
#rom int8 0x300001 = {0x32}//Cambia los fuses del cristal que es equivalente a poner #fuses HS, PLLEN, PCLKEN
#use delay(clock=40000000)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5, stream=PC)
#define UNO PIN_C4
const long desbordamiento = 15536;//5ms
long t = desbordamiento+15000;//1500us de ton
int1 flag_1 = 0;
int1 flagRTCC_1 = 0;
long valTIMER=0; //Tiene que ser un long debido a que el timer1 es un long, timer0 es un int
#int_timer1 //Subrutina de interrupción por TIMER1
void isr_timer1(void)
{
flagRTCC_1=1;
set_timer1(desbordamiento);
}
//PROGRAMA PRINCIPAL
void main(void) {
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
set_timer1(desbordamiento); //Vtmr1 = 65536 - (1s * ( 12000000Hz / 4 ) / prescaler ) 200us -> Vtmr1=5536 set_timer1(0x15A0);
setup_ccp1(CCP_PWM); //ccp1 modo PWM //Si lo ponemos arriba me da que no funciona, siempre va primero la declaración de variables
enable_interrupts(global);// Habilita interrupciones
while (TRUE)
{
if(flagRTCC_1==1)
{
flagRTCC_1=0;
output_high(UNO);
flag_1=1;
}
if(flag_1==1)
{
valTIMER=get_TIMER1();
if(valTIMER>t)//1,5ms->10036 0.5ms->7036 0.1ms->5836 2.3ms->12436 set_timer1(0x15A0); MAX->33500 MIN->10500
{
output_low(UNO);
flag_1=0;
}
}
//Fin Para el servo1
}//Fin while(TRUE)
}//Fin main(void)
Dando como resultado un periodo de 3750us y un ton de 1125us
Con el siguiente código
#include <18F13K50.h>
#fuses NOWDT, NOPROTECT, NOLVP
#fuses HS
#fuses USBDIV1 //USB clock source comes from PLL no divide
#fuses CPUDIV1 //No System Clock Postscaler
#use delay(clock=40000000)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5, stream=PC)
#define UNO PIN_C4
const long desbordamiento = 15536;//5ms
long t = desbordamiento+15000;//1500us de ton
int1 flag_1 = 0;
int1 flagRTCC_1 = 0;
long valTIMER=0; //Tiene que ser un long debido a que el timer1 es un long, timer0 es un int
#int_timer1 //Subrutina de interrupción por TIMER1
void isr_timer1(void)
{
flagRTCC_1=1;
set_timer1(desbordamiento);
}
//PROGRAMA PRINCIPAL
void main(void) {
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
set_timer1(desbordamiento); //Vtmr1 = 65536 - (1s * ( 12000000Hz / 4 ) / prescaler ) 200us -> Vtmr1=5536 set_timer1(0x15A0);
setup_ccp1(CCP_PWM); //ccp1 modo PWM //Si lo ponemos arriba me da que no funciona, siempre va primero la declaración de variables
enable_interrupts(global);// Habilita interrupciones
while (TRUE)
{
if(flagRTCC_1==1)
{
flagRTCC_1=0;
output_high(UNO);
flag_1=1;
}
if(flag_1==1)
{
valTIMER=get_TIMER1();
if(valTIMER>t)//1,5ms->10036 0.5ms->7036 0.1ms->5836 2.3ms->12436 set_timer1(0x15A0); MAX->33500 MIN->10500
{
output_low(UNO);
flag_1=0;
}
}
//Fin Para el servo1
}//Fin while(TRUE)
}//Fin main(void)
Dando como resultado un periodo de 15.000us y un ton de 4500us
Haciendo un resumen rápido de las pruebas realizadas:
12 MHz 40MHz
#rom int8 0x300000 = {0x00} ton=370us Periodo=1250us ton=1125us Periodo=3750us
#rom int8 0x300001 = {0x32}
#rom int8 0x300000 = {0x00} ton=1500us Periodo=5000us ton=4500us Periodo=15000us
#rom int8 0x300001 = {0xC2}
A este paso voy a tener que llamar a Fox Malder y a Dana Scully
, no tengo ni idea de lo que puede estar pasando con el cristal de 40Mhz...
Cualquier sugerencia me vendría bien, lo malo es que me hace falta usar el de 40MHz para que el timer sea lo más preciso posible
Muchas gracias compañeros.