#include <xc.h>
#include <pic18f2550.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define _XTAL_FREQ 48000000 //para usar el Delay
unsigned int tiempo_on_us = 100;
void main(void)
{
//PORTB
TRISBbits.RB4=0;
//TIMER1
T1CON=0b10110000;//prescale 8
TMR1=0x00;
T1CONbits.TMR1ON=1; //enciendo el timer
while (1)
{
TMR1=65536 - ((tiempo_on_us*48)/(4*8));//100us
do{
PORTBbits.RB4=1;
}while(PIR1bits.TMR1IF == 0);
PIR1bits.TMR1IF = 0;
PORTBbits.RB4=0;
__delay_us(100);
}
};
#include <xc.h>
#include <pic18f2550.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define _XTAL_FREQ 48000000 //para usar el Delay
unsigned int tiempo_on_us = 100;
void main(void)
{
//PORTB
TRISBbits.RB4=0;
//TIMER1
T1CON=0b10110000;//prescale 8
TMR1=0x00;
T1CONbits.TMR1ON=1; //enciendo el timer
tiempo_on_us = 50;
while (1)
{
TMR1=65536 - ((tiempo_on_us*48)/(4*8));//100us
do{
PORTBbits.RB4=1;
}while(PIR1bits.TMR1IF == 0);
PIR1bits.TMR1IF = 0;
PORTBbits.RB4=0;
__delay_us(100);
}
};
............
pero por ejemplo cuando cambio el valor de la variable "tiempo_on_us" dentro del main. ya el flag nunca se pone en uno, El registro TMR1 se carga con el valor correcto y empieza a temporizar, llega a la cuenta maxima, desborda, pero el flag no se pone en 1, por lo que no sale del bucle . Ejemplo si simulo el siguiente codigo, que simplemente cambio el valor de la variable dentro del main.Código: [Seleccionar]#include <xc.h>
#include <pic18f2550.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define _XTAL_FREQ 48000000 //para usar el Delay
unsigned int tiempo_on_us = 100;
void main(void)
{
//PORTB
TRISBbits.RB4=0;
//TIMER1
T1CON=0b10110000;//prescale 8
TMR1=0x00;
T1CONbits.TMR1ON=1; //enciendo el timer
tiempo_on_us = 50;
while (1)
{
TMR1=65536 - ((tiempo_on_us*48)/(4*8));//100us
do{
PORTBbits.RB4=1;
}while(PIR1bits.TMR1IF == 0);
PIR1bits.TMR1IF = 0;
PORTBbits.RB4=0;
__delay_us(100);
}
};
Cargar el timer de esta manera: TMR1=65536 - ((tiempo_on_us*48)/(4*8)); no me parece un buen metodo, pero no se como hacer para variar la temporzacion al valor que yo quiera. Necesito hacer esto para otro codigo, por lo que PWM lo descarte.
....................
tiempo_on_us = 50 ;
tiempo_on_tics = 0x10000-(tiempo_on_us*48)/(4*8) ;
while (1)
{
TMR1 = tiempo_on_tics ;
PORTBbits.RB4 = 1 ;
while(PIR1bits.TMR1IF == 0);
PIR1bits.TMR1IF = 0;
PORTBbits.RB4 = 0;
__delay_us(100);
}
#define delay_for(x) for(unsigned int nnnn=x;nnnn>0;nnnn--)
void main(void)
{
unsigned int N_on,N_off ;
//PORTB
TRISBbits.RB4=0;
tiempo_on_us = 50 ;
tiempo_off_us = 100 ;
N_on = tiempo_on_us *4/3 ; // Es la variable que realmente tenés que modificar
N_off = tiempo_off_us *4/3 ; // Idem
while (1)
{
PORTBbits.RB4 = 1 ;
delay_for(N_on) ;
PORTBbits.RB4 = 0;
delay_for(N_off) ;
}
};
Por otro lado... ¿Para que usás el timer en modo bloqueante?El tema es este, el codigo que puse es un breve programa para ver porque el flag no se pone en alto cuando desborda el timer.
Para eso hacé un retardo con un bucle for. No es lo mismo que el timer, pero del modo en que lo estás usando da igual. Incluso podés hacer variable el T_off.
Es raro, yo copypego ese código y sale lo mas bien del bucle. Tal vez convendría comprobar que esté en 1 al entrar.Te muestro imagen 1, sin modificar la variable
A mi tampoco, hacer ese cálculo repetidamente no tiene sentido y te suma 6uS al Toff. Mejor cargá directamente la cuenta de TMR1Exacto, alguna idea de como hacer lo que quiero sin utilizar una formula asi?. Ejemplo, que venga un flaco, ponga con un teclado, quiero 200us, joya temporiza 200us, pero luego ponga 50us y temporice 50us. Como que me veo obligado a utilizar una variable que modifique el registro según la formula para temporizar el valor adecuado.
No querés usar PWM, OK ¿Pero por qué tampoco interrupciones?Voy a usar interrupciones, pero no del modulo Timer...No es necesario según la esencialidad del programa. Para lo unico que voy a usar las interrupciones es para modificar el registro TMR1, ejemplo con un pulsador, conectado al puerto B.
...Te muestro imagen 1, sin modificar la variable
imagen 2, modificando la variable
No me doy cuenta que xq pasa esto, yo tengo entendio que ese flag siempre se pone en uno cuando desborda el timer, es como automático, pareciera que algo lo bloquea. Yo vi la simulación haciendo un debugger con el VSM de proteus, es mas lo estoy corriendo en "tiempo real" con proteus mientras voy linea por linea moviendome en MPLABX. Veo como se van modificando los registros tanto en Proteus y Mplab x, y es exactamente lo mismo, no es que en Mplabx si se pone en alto, pero en proteus no. Estoy utilizando la herrmienta Proteus VSM viewer.
Exacto, alguna idea de como hacer lo que quiero sin utilizar una formula asi?. Ejemplo, que venga un flaco, ponga con un teclado, quiero 200us, joya temporiza 200us, pero luego ponga 50us y temporice 50us. Como que me veo obligado a utilizar una variable que modifique el registro según la formula para temporizar el valor adecuado.
void main(void)
{
//PORTB
TRISBbits.RB4=0;
//TIMER1
T1CON=0b10110000;//prescale 8
TMR1=0x00;
T1CONbits.TMR1ON=1; //enciendo el timer
tiempo_on_us = 50;
TMR1=65536 - ((tiempo_on_us*48)/(4*8)); //<<<<<<<<<<<< Línea "inútil"
while (1)
{
TMR1=65536 - ((tiempo_on_us*48)/(4*8));//100us
do{
......................Con esa línea simula correctamente, la sacás y vuelve a demorar 43.6ms en arrancar.
#define _XTAL_FREQ 48000000 //para usar el Delay
unsigned int tiempo_on_us = 100;
unsigned int CTimer;
void main(void)
{ //PORTB
TRISBbits.RB4=0;
//TIMER1
T0CON=0b00001010;//prescale 8
TMR0=0x00;
T0CONbits.TMR0ON=1; //enciendo el timer
//tiempo_on_us = 50;
//CTimer=65536 - tiempo_on_us*(3/2);//100us
//TMR0=CTimer;
while (1)
{
tiempo_on_us = 5000;
CTimer=65536 - tiempo_on_us*(3/2);//100us
TMR0=CTimer;
do{
PORTBbits.RB4=1;
}while(INTCONbits.TMR0IF == 0);
INTCONbits.TMR0IF = 0;
PORTBbits.RB4=0;
__delay_us(100);
}
};
void main(void)
{ //PORTB
TRISBbits.RB4=0;
//TIMER1
T0CON=0b00001010;//prescale 8
TMR0=0x00;
T0CONbits.TMR0ON=1; //enciendo el timer
//tiempo_on_us = 50;
//CTimer=65536 - tiempo_on_us*(3/2);//100us
//TMR0=CTimer;
while (1)
{
tiempo_on_us = tiempo_on_us + 100;
CTimer=65536 - tiempo_on_us*(3/2);//100us
TMR0=CTimer;
do{
PORTBbits.RB4=1;
}while(INTCONbits.TMR0IF == 0);
INTCONbits.TMR0IF = 0;
PORTBbits.RB4=0;
__delay_us(100);
}
Cargar el timer de esta manera: TMR1=65536 - ((tiempo_on_us*48)/(4*8)); no me parece un buen metodo, pero no se como hacer para variar la temporzacion al valor que yo quiera. Necesito hacer esto para otro codigo, por lo que PWM lo descarte.Porque descartas el PWM?? EL PIC18F2550 tiene un modulo EPWM (mejorado) que te permite hacer lo que quieres! Incluso para señales complementarias ya tiene el tiempo muerto programable. Se ajusta la frecuencia con un registro (PR2) y el ciclo de trabajo se actualiza en otro registro (CCP1L). Este modulo es utilizado para control de motores y convertidores de potencia. otros como el PIC18F4431 tiene tres modulos EPWM utilizado mucho para control de motores trifasicos.
TMR1H = 0 ;
TMR1L = 0 ; TMR1L = Nl ;
TMR1H = Nh ; WRITETIMER1(65536 - (tiempo_on_us*3/2) ) ; Porque descartas el PWM?? EL PIC18F2550 tiene un modulo EPWM (mejorado) que te permite hacer lo que quieres! Incluso para señales complementarias ya tiene el tiempo muerto programable. Se ajusta la frecuencia con un registro (PR2) y el ciclo de trabajo se actualiza en otro registro (CCP1L). Este modulo es utilizado para control de motores y convertidores de potencia. otros como el PIC18F4431 tiene tres modulos EPWM utilizado mucho para control de motores trifasicos.Simplemente no veia la utilidad para la aplicacion de establecer solo tiempos. Estoy tratando de establecer tiempos precisos para una generación de pulsos bipolares. hay dos tiempos muertos y un tiempo igual para el pulso + y -. Es necesario que los tiempos para el pulso + y - sean IGUALES, por eso que el codigo para tratar eso lo hago en ASM. El hecho de setear estos tres tiempos, me parece mas practico y preciso que utilizar un PWM. El EPWM no esta para los disp PIC18F4550/4455?.
Ahi lo probe, y en el simulador del MPLAB, me funciona correctamente, tengo XC8 1.43Yo no utilice el simulador de MPLAB, directamente uso la herramienta de VSM... Creo que deberia ser lo mismo. Te pregunto, cual es el motivo por el cual no actualizas el XC8?
Misterio resuelto (creo :) )Tiene toda la pinta que si, ahi lo probe, y en principio anda....Voy a ver que onda en la otra aplicación. Estoy seguro que nunca me hubiera dado cuenta jajaaj, ya estaba negado jajajaja
El EPWM no esta para los disp PIC18F4550/4455?.
Yo no utilice el simulador de MPLAB, directamente uso la herramienta de VSM... Creo que deberia ser lo mismo. Te pregunto, cual es el motivo por el cual no actualizas el XC8?