#include <p18f4550.h>
#include <delays.h>
//////////////////Configuaracion de bits//////////////////////////
#pragma config PLLDIV = 4
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 1 /////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config FOSC = INTOSC_EC //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
void main (){
TRISBbits.RB1=0; //Definimos el pin 5 del PuertoB como salida.
//Configuracion del timer0
T0CONbits.T08BIT=0; //Configurado a 16bits el Timer0
T0CONbits.T0CS=0; //Internal Fos/4 (8Mhz/4)
T0CONbits.PSA=1; //No prescaler.
//Cargando los registros TMR0H
TMR0H=0XFF;
TMR0L=0X38;
INTCONbits.TMR0IF=0;
T0CONbits.TMR0ON=1; //Iniciamos el timer0
while(1){
if(INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF=0;
TMR0H=0XFF;
TMR0L=0X38;
LATBbits.LATB1=!LATBbits.LATB1;
}
}
}Hola alvaro2043 debes configurar el registro TRISB como salida, por defecto esta como entrada, y tambien con ADCON1 las entradas y salidas analogicas que por defecto son analogicas.
Saludos!
//Configuaracion de bits//////////////////////////
#pragma config PLLDIV = 2 //Cristal de 8Mhz lo dividimos entre 2 para tener los 4Mhz
#pragma config CPUDIV = OSC1_PLL2 //Los 96Mhz de PLL lo dividimos entre 2 para tener los 48Mhz con lo que vamos a trabajar
#pragma config USBDIV = 2 /////Tomar el reloj para USB desde el PLL- 48Mhz
#pragma config FOSC = HSPLL_HS //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
///Include////
#include <p18f4550.h>
#include <delays.h>
//Variables globales
int estado=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(void);
void Change_Estado(void);
///////////////////////////////////////////////
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
////////////////////////////////////////////
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
if(INTCONbits.TMR0IF ==1 ){ //Si el timer0 se desbordo 0xFFFF a 0x0000
INTCONbits.TMR0IF =0; //Borramos la bandera
Change_Estado(); //Llamamos la funcion que se realiza cuando esto ocurre.
TMR0H=0XFB;
TMR0L=0X50;
}
}
void main(){
OSCCONbits.SCS1=0; //Configurando como Oscilador primario
OSCCONbits.SCS0=0;
TRISBbits.RB1=0; //Configurando como salida el PinRB1 del puerto B
LATBbits.LATB1=0; //Estableciendo a un nivel bajo el PinRB1
ADCON1=0x0F; //Configurando todos los puerto como Digitales.
T0CONbits.TMR0ON=0; //Timer 0 off
T0CONbits.T08BIT=0; //Configurado a 16bits
T0CONbits.T0CS=0; //Internal
T0CONbits.T0SE=0;
T0CONbits.PSA=1; //Prescaler no asignado
TMR0H=0XFB;
TMR0L=0X50;
RCONbits.IPEN=1; //Enable priority levels on Interrupts
INTCONbits.TMR0IF=0; //Clear TF0
INTCONbits.GIE_GIEH=1; //Enable Global interrupt
INTCONbits.TMR0IE=1; //Enable TMR0 overflow
INTCON2bits.TMR0IP=1; //High priority
T0CONbits.TMR0ON=1; //on Timer 0
while(1){}
}
void Change_Estado(void){
if(estado==0){
LATBbits.LATB1=1;
estado=!estado;
} else if (estado==1){
LATBbits.LATB1=0;
estado=!estado;
}
}
Bueno sigo con otras preguntas que me surgen con respecto a la frecuencia maxima que puedo obtener con una interrupcion, estaba probando y se me dio por cargar los registros
TMR0H y TMR0L con FFFE eso quiere decir que apenas se van a realizar 2 tick.. ya que el Timer se desborda cuando llega a FFFF (Configurado a 16bits) en teoria la frecuencia debieria de ser de:
2*(1/(48Mhz/4))=166.66ns este es el ancho del pulso osea que la frecuencia seria de (1/(2*166.66ns))=3000Khz pues ese es el calculo que saco apartir de los calculos que hice para obtener los 5khz... y la frecuencia que obtengo en mi osciloscopio es de 312Khz aprox... Que es lo que esta pasadan???' alguien me puede decir?
Nota: Solo son inquietudes que se me generan, no utilizo prescale.
Eso quiere decir que no es posible obtener una frecuencia mayor a 312Khz en C, debido a que se usan 20 ciclos de reloj (en este caso).
Osea que en .ASM se puede llegar a una frecuencia superior o no?. Me nace esa inquietud porq se gasta menos ciclo de reloj en Assembler.
Otra preguntica, con un solo timer y su interrupcion es posible generar las 4 señales que publique en la parte superior http://www.emeraldinsight.com/content_images/fig/1740250405013.png o necesitaria de otro timer? la frecuencia que tengo pensado manejar para esas señales es de 25 a 40Khz
Si tengo en mente hacer una fuente de corriente constante para ser aplicada a un calentador por inducción...
cuento con 8 modulos de este tipo y quiero ponerlo a trabajar en ese proyecto que tengo en mente..
http://www.ineltron.de/english/mitsubishi-data/IGBT/CM200DU-12F.pdf
Que Uc me puede recomendar para esa aplicacion?
//Configuaracion de bits//////////////////////////
#pragma config PLLDIV = 2 //Cristal de 8Mhz lo dividimos entre 2 para tener los 4Mhz
#pragma config CPUDIV = OSC1_PLL2 //Los 96Mhz de PLL lo dividimos entre 2 para tener los 48Mhz con lo que vamos a trabajar
#pragma config USBDIV = 2 /////Tomar el reloj para USB desde el PLL- 48Mhz
#pragma config FOSC = HSPLL_HS //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
///Include////
#include <p18f4550.h>
#include <delays.h>
//Variables globales
const char num_int=30;
unsigned int contador=0;
//Banderas
char flag1=0,flag2=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(void);
///////////////////////////////////////////////
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
////////////////////////////////////////////
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
//if(INTCONbits.TMR0IF==1){ //Si se produce la interrupcion
INTCONbits.TMR0IF==0; //Borramos la bandera
if(contador>num_int){ //Si es mayor a num_int
if(flag1==0){ //Bandera que hace un cambio cada 30 interrupciones
flag1=1;
} else{
flag1=0;
}
contador=0;
}
contador++;
//}
TMR0H=0X00;
TMR0L=0X00;
}
void main(){
OSCCONbits.SCS1=0; //Configurando como Oscilador primario
OSCCONbits.SCS0=0;
TRISBbits.RB1=0; //Configurando como salida el PinRB1 del puerto B
LATBbits.LATB1=0; //Estableciendo a un nivel bajo el PinRB1
ADCON1=0x0F; //Configurando todos los puerto como Digitales.
T0CONbits.TMR0ON=0; //Timer 0 off
T0CONbits.T08BIT=0; //Configurado a 16bits
T0CONbits.T0CS=0; //Internal
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler asignado
T0CONbits.T0PS2=0; //Prescaler de 16
T0CONbits.T0PS1=1;
T0CONbits.T0PS0=1;
//TMR0H=0X00;
//TMR0L=0X00;
RCONbits.IPEN=1; //Enable priority levels on Interrupts
INTCONbits.TMR0IF=0; //Clear TF0
INTCONbits.GIE_GIEH=1; //Enable Global interrupt
INTCONbits.TMR0IE=1; //Enable TMR0 overflow
INTCON2bits.TMR0IP=1; //High priority
T0CONbits.TMR0ON=1; //on Timer 0
do{
if(flag1=flag2){}
else{
LATBbits.LATB1=!LATBbits.LATB1;
flag2=flag1;
}
}
while(1);
}
if(flag1==flag2)
INTCONbits.TMR0IF==0; el error era ese y el de flag1==flag2ejejej ya encontré el error cuando estoy borrando la bandera de desbordamiento esto haciendo.Código: [Seleccionar]INTCONbits.TMR0IF==0;el error era ese y el de flag1==flag2
const int num_int=15;
unsigned int contador=0;
//Banderas
char flag1=0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(void);
///////////////////////////////////////////////
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
////////////////////////////////////////////
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
if(contador==num_int){
contador=0;
flag1=1;
}
++contador;
INTCONbits.TMR0IF=0; //Borramos la bandera
TMR0H=0X00;
TMR0L=0X00;
}
void main(){
OSCCONbits.SCS1=0; //Configurando como Oscilador primario
OSCCONbits.SCS0=0;
TRISBbits.RB1=0; //Configurando como salida el PinRB1 del puerto B
LATBbits.LATB1=0; //Estableciendo a un nivel bajo el PinRB1
ADCON1=0x0F; //Configurando todos los puerto como Digitales.
T0CONbits.TMR0ON=0; //Timer 0 off
T0CONbits.T08BIT=0; //Configurado a 16bits
T0CONbits.T0CS=0; //Internal
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler asignado
T0CONbits.T0PS2=0; //Prescaler de 16
T0CONbits.T0PS1=1;
T0CONbits.T0PS0=1;
RCONbits.IPEN=1; //Enable priority levels on Interrupts
INTCONbits.TMR0IF=0; //Clear TF0
INTCONbits.GIE_GIEH=1; //Enable Global interrupt
INTCONbits.TMR0IE=1; //Enable TMR0 overflow
INTCON2bits.TMR0IP=1; //High priority
T0CONbits.TMR0ON=1; //on Timer 0
while(1){
if(flag1){
flag1=0;
LATBbits.LATB1=!LATBbits.LATB1;
}
}
}una preguntilla... como puedo leer el valor del timer0. en ccs se hace con leer_timer=get_timer0();
Como lo puedo hacer en c18 sin utilizar la libreria <timer.h> leer_timer=readtimer0();
Según lo que he leído, para escribir en el Timer0 primero se carga el TMR0H y despues el TMR0L, eso es lo que vengo haciendo. Ahora para leer los valores del timer se hace el proceso contrario.. Primero se lee TMR0L y despues TMR0H.. He encontrado un ejemplo pero no entiendo la parte del 256U
Nota: No entiendo el 256U que función cumple..
valTimer0=TMR0L;
valTimer0|=TMR0H*256U;
El C30 no me sirve? estoy confundido
C18-------------------------> para los PIC18
C30-----------------------> Para elo PIC24-y dspic
XC8---------------------->?
XC16-------------------->?
XC32---------------------?
#include <p18f4550.h>
#include <delays.h>
#define PWM1 LATBbits.LATB1
//Variables globales
//const int periodo = 240; //240 tick en donde un tick=0.166uS (240x0.166us)=39.84us aprox 25.10Khz
const int duty_50 = 120;
const int duty_30 = 72;
const int duty_20 = 48;
unsigned int flag_t =0; //Bandera que me indica cuando se genera una interrupcion
unsigned int flag_d =0; //Bandera para el ciclo de trabajo
unsigned int contador=0;
unsigned int valTimer0;
/*Prototipos de funciones*/
void Interrupt_ISR_TMR0(void);
///////////////////////////////////////////////
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
////////////////////////////////////////////
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
if(INTCONbits.TMR0IF==1){
INTCONbits.TMR0IF=0; //Borramos bandera
++contador; //Cada vez que se presente una interrupcion aumentamos la variable contador
LATBbits.LATB2=!LATBbits.LATB2;
if(contador==1){
flag_t=1;
contador=0;
}
TMR0H=0XFF; //El timer 0 arranca desde 65311. 65536-65311=235tick*0.166uS=39.01us
TMR0L=0X1F;
}
}
void main(){
OSCCONbits.SCS1=0; //Configurando como Oscilador primario
OSCCONbits.SCS0=0;
TRISBbits.RB1=0; //Configurando como salida el PinRB1 del puerto B
LATBbits.LATB1=0; //Estableciendo a un nivel bajo el PinRB1
TRISBbits.RB2=0;
LATBbits.LATB2=0;
ADCON1=0x0F; //Configurando todos los puerto como Digitales.
T0CONbits.TMR0ON=0; //Timer 0 off
T0CONbits.T08BIT=0; //Configurado a 16bits
T0CONbits.T0CS=0; //Internal
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler asignado
T0CONbits.T0PS2=0; //Prescaler de 2
T0CONbits.T0PS1=0;
T0CONbits.T0PS0=0;
RCONbits.IPEN=1; //Enable priority levels on Interrupts
INTCONbits.TMR0IF=0; //Clear TF0
INTCONbits.GIE_GIEH=1; //Enable Global interrupt
INTCONbits.TMR0IE=1; //Enable TMR0 overflow
INTCON2bits.TMR0IP=1; //High priority
T0CONbits.TMR0ON=1; //on Timer 0
while(1){
//Pulso del pwm
if(flag_t==1){ //Si se desbordo el timer activamos una bandera
flag_t=0; //Limpiamos la bandera
PWM1=1; //Activamos el pin del PWM
flag_d=1;
}
//cuadrar ciclo de trabajo
if(flag_d==1){
valTimer0=TMR0L; //Leemos el valor del timer0 y lo almacenamos en la variable valtimer0
valTimer0|=TMR0H<<8;
if(valTimer0>duty_50){
flag_d=0;
PWM1=0;
}
}
}
}void set_pwm_shift(uint8_t phase2Shift, uint8_t phase3Shift)
{
uint8_t tmp;
tmp = (counter1+ phase2Shift) % 11;
if(!tmp) tmp++; //no dejar que valga nunca 0
counter2 = tmp;
tmp = (counter1+ phase3Shift) % 11;
if(!tmp) tmp++; //no dejar que valga nunca 0
counter3 = tmp;
}BrunoF gracias por esas explicaciones he mirado tu codigo muy detallado y lo he analizado, primero que todo he visto que utiliza declaraciones de variables con terminos que desconocia, como: uint8_t inline bueno he buscado sobre ellos y he visto que se trabaja orientado a la parte de c/c++. Mire en el manual de C18 y he reemplazado el Uint8_t por unsigned char "Creo que es lo mismo" el inline si no lo he utilizado por que en el manual de c18 es como una instruccion en .asm y en c/c++ creo que se utiliza cuando se hace el llamado de la funcion se reemplace todo por el cuerpo de la funcion. NOTA: si esto diciendo cosas que nada tienen que ver me perdonan eso fue lo que he entendio.
Ahora con respecto algunas cosas del codigo tengo ciertas cosas que no entiendo.Código: [Seleccionar]void set_pwm_shift(uint8_t phase2Shift, uint8_t phase3Shift)
{
uint8_t tmp;
tmp = (counter1+ phase2Shift) % 11;
if(!tmp) tmp++; //no dejar que valga nunca 0
counter2 = tmp;
tmp = (counter1+ phase3Shift) % 11;
if(!tmp) tmp++; //no dejar que valga nunca 0
counter3 = tmp;
}
no entiendo la parte del %11 el modulo ese no me queda muy claro.. si me puede explicar esa funcion te lo agradezco
[i]An implementation that accepts any stricly conforming program that does not use complex
types and in which the use of the features specified in the library clause (ANSI '89 Standard clause 7)
is confined to the contents of the stadard headers <float.h> <iso646.h>.......<stdint.h>[/i]
#pragma config PLLDIV = 2 //Cristal de 8Mhz lo dividimos entre 2 para tener los 4Mhz
#pragma config CPUDIV = OSC1_PLL2 //Los 96Mhz de PLL lo dividimos entre 2 para tener los 48Mhz con lo que vamos a trabajar
#pragma config USBDIV = 2 /////Tomar el reloj para USB desde el PLL- 48Mhz
#pragma config FOSC = HSPLL_HS //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
#include <p18f4550.h>
#include <delays.h>
#define PWM1 LATBbits.LATB1
#define PWM2 LATBbits.LATB2
#define PWM3 LATBbits.LATB0
//Tres contadores uno por cada PWM
unsigned char contador1,contador2,contador3;
//Variables que llevan el valor actual del pwm
unsigned char PWM1value,PWM2value,PWM3value;
//Prototipos de Funciones
void set_pwm_duty(unsigned char phase1Value, unsigned char phase2Value, unsigned char phase3Value );
void set_pwm_shift(unsigned char phase2shift,unsigned char phase3shift);
/*-------Interrupción de Alta_Prioridad---------*/
void Interrupt_ISR_TMR0(void);
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
TMR0L=238; //Ajustado para que se genere un Interrup cada 4us
INTCONbits.TMR0IF=0;
if(++contador1>10) contador1=1;
if(++contador2>10) contador2=1;
if(++contador3>10) contador3=1;
if(PWM1value >= contador1) PWM1=1; else PWM1=0;
if(PWM2value >= contador2) PWM2=1; else PWM2=0;
if(PWM3value >= contador3) PWM3=1; else PWM3=0;
}
void main(){
/*---------Configuracion Oscilador--------*/
OSCCONbits.SCS1=0; //Oscilador primario
OSCCONbits.SCS0=0;
/*-------Configuracion de pines---------*/
TRISBbits.RB1=0;
LATBbits.LATB1=0;
TRISBbits.RB2=0;
LATBbits.LATB2=0;
ADCON1=0x0F; //Todos los pines como digitales
T0CONbits.TMR0ON=0; //Timero Off
T0CONbits.T08BIT=1; //Configuracion a 8bits
T0CONbits.T0CS=0; //Internal Instruccion
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler On
T0CONbits.T0PS2=0; //Prescaler 1:2
T0CONbits.T0PS1=0;
T0CONbits.T0PS0=0;
RCONbits.IPEN=1; //Habilitamos la prioridad
INTCONbits.TMR0IF=0; //Interrupcion por desbordamiento
INTCONbits.GIE_GIEH=1;
INTCONbits.GIEH=1; //Activamos alta_Prioridad
INTCONbits.TMR0IE=1;
INTCON2bits.TMR0IP=1; //TMR0 Alta prioridad.
T0CONbits.TMR0ON=1; //On Timer0
//Inicio de contadores de PWM
contador1=1;
contador2=1;
contador3=1;
set_pwm_duty(1,4,9);
set_pwm_shift(0,0);
while(1){
Delay10KTCYx(10);
set_pwm_duty(5,5,5);
set_pwm_shift(3,7);
Delay10KTCYx(10);
set_pwm_duty(1,4,9);
set_pwm_shift(0,0);
}
}
void set_pwm_duty(unsigned char phase1Value, unsigned char phase2Value, unsigned char phase3Value ){
PWM1value=phase1Value;
PWM2value=phase2Value;
PWM3value=phase3Value;
}
void set_pwm_shift(unsigned char phase2shift,unsigned char phase3shift){
unsigned char tmp;
tmp=(contador1+phase2shift)%11;
if(!tmp) tmp++;
contador2=tmp;
tmp=(contador1+phase3shift);
if(!tmp) tmp++;
contador3=tmp;
}Hola Álvaro! Me alegro que funcione. Fíjate que no configuraste como salida el pin b0.
#include <p18f4550.h>
#include <delays.h>
#define PWM1 LATBbits.LATB1
#define PWM2 LATBbits.LATB2
#define sw1 LATAbits.LATA0
//Tres contadores uno por cada PWM
unsigned char contador1,contador2,contador;
//Variables que llevan el valor actual del pwm
unsigned char PWM1value,PWM2value=1;
//Prototipos de Funciones
void set_duty(void);
/*-------Interrupción de Alta_Prioridad---------*/
void Interrupt_ISR_TMR0(void);
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
TMR0L=254;
LATBbits.LATB0=!LATBbits.LATB0;
INTCONbits.TMR0IF=0;
if(++contador1>10) contador1=1;
if(++contador2>10) contador2=1;
if(PWM1value >= contador1) PWM1=1; else PWM1=0;
if(PWM2value >= contador2) PWM2=1; else PWM2=0;
}
void main(){
/*---------Configuracion Oscilador--------*/
OSCCONbits.SCS1=0; //Oscilador primario
OSCCONbits.SCS0=0;
/*-------Configuracion de pines---------*/
/*----Salidas---*/
TRISBbits.RB1=0;
LATBbits.LATB1=0;
TRISBbits.RB2=0;
LATBbits.LATB2=0;
TRISBbits.RB0=0;
LATBbits.LATB0=0;
TRISBbits.RB3=0;
LATBbits.LATB3=0;
//-----Entradas--------//
TRISAbits.RA0=1; //Definido como entrada
TRISAbits.RA1=1; //Definido como entrada
LATAbits.LATA1=0;
//----------------------//
ADCON1=0x0F; //Todos los pines como digitales
T0CONbits.TMR0ON=0; //Timero Off
T0CONbits.T08BIT=1; //Configuracion a 8bits
T0CONbits.T0CS=0; //Internal Instruccion
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler On
T0CONbits.T0PS2=0; //Prescaler 1:2
T0CONbits.T0PS1=0;
T0CONbits.T0PS0=0;
RCONbits.IPEN=1; //Habilitamos la prioridad
INTCONbits.TMR0IF=0; //Interrupcion por desbordamiento
INTCONbits.GIE_GIEH=1;
INTCONbits.GIEH=1; //Activamos alta_Prioridad
INTCONbits.TMR0IE=1;
INTCON2bits.TMR0IP=1; //TMR0 Alta prioridad.
T0CONbits.TMR0ON=1; //On Timer0
//Inicio de contadores de PWM
contador1=1;
contador2=1;
while(1){
set_duty();
}
}
void set_duty(void){
unsigned char cntduty;
while(!sw1);
Delay10KTCYx(10); //Retardor de 8.33ms
cntduty++;
switch (cntduty){
case 1: PWM1value=1; break; //Ciclo de trabajo del 10%
case 2: PWM1value=2; break; //Ciclo de trabajo del 20%
case 3: PWM1value=3; break; //Ciclo de trabajo del 30%
case 4: PWM1value=4; break; //ciclo de trabajo del 40%
case 5: PWM1value=5; break; //Cilco de trabajo del 50%
default : cntduty=0;
}
}
Gracias Bruno osea que no es recomendable precargar el registro TMR0L a un valor cercano del desborde? si es asi aprox cual es el valor máximo que uno puede cargar el timer de tal forma que no se genere ese problema. En los anteriores codigo habiamos cargado el Timer a 238, he decido cambiar ese valor ya que quería aumentar un poco mas la frecuencia de los 25Khz a 32Khz que es lo maximo que se puede generar con esa resolucion.
He visto algo curioso cuando lo simulo en proteus sucede que cuando pulso (SW1) el cual esta conectado a GND y cuando se pulsa ve VCC se queda en VCC por un tiempo considerable y demora en retornar de nuevo a GND no se si es el simulador ya que no lo he probado en lo fisico.
Gracias.
#include <p18f4550.h>
#include <delays.h>
/*-----Definicion de estados--------*/
#define ciclo_10 1 //Ciclo del 10%
#define ciclo_20 2 //Ciclo del 20%
#define ciclo_30 3 //Ciclo del 30%
#define ciclo_40 4 //Ciclo del 40%
#define ciclo_50 5 //Ciclo del 50%
/*-----Definicion de pines-----------*/
#define PWM1 LATBbits.LATB0
#define button1 LATAbits.LATA0
/*-------------------------------------*/
unsigned char contador, PwmValue, estado;
/*----Prototipos de funciones----------*/
void set_pwm(unsigned char PwmValue1);
/*-------Interrupción de Alta_Prioridad---------*/
void Interrupt_ISR_TMR0(void);
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
INTCONbits.TMR0IF=0; /*Borramos bandera*/
TMR0L=238;
if(++contador>10) contador=1;
if(PwmValue>=contador) PWM1=1; else PWM1=0;
}
void main(){
estado=ciclo_10;
TRISB=0x00;
LATB=0x00;
TRISAbits.RA0=1; //Como entradas
//LATAbits.LATA0=0;
/*---------Configuracion Oscilador--------*/
OSCCONbits.SCS1=0; //Oscilador primario
OSCCONbits.SCS0=0;
ADCON1=0x0F; //Todos los pines como digitales
T0CONbits.TMR0ON=0; //Timero Off
T0CONbits.T08BIT=1; //Configuracion a 8bits
T0CONbits.T0CS=0; //Internal Instruccion
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler On
T0CONbits.T0PS2=0; //Prescaler 1:2
T0CONbits.T0PS1=0;
T0CONbits.T0PS0=0;
RCONbits.IPEN=1; //Habilitamos la prioridad
INTCONbits.TMR0IF=0; //Interrupcion por desbordamiento
INTCONbits.GIE_GIEH=1;
INTCONbits.GIEH=1; //Activamos alta_Prioridad
INTCONbits.TMR0IE=1;
INTCON2bits.TMR0IP=1; //TMR0 Alta prioridad.
T0CONbits.TMR0ON=1; //On Timer0
while(1){
switch(estado){
case ciclo_10 :
PwmValue=1;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_20;
break;
case ciclo_20 :
PwmValue=2;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_30;
break;
case ciclo_30 :
PwmValue=3;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_40;
break;
case ciclo_40 :
PwmValue=4;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_50;
case ciclo_50:
PwmValue=5;
while(button1);
Delay1KTCYx(50);
while(!button1);
Delay1KTCYx(50);
estado=ciclo_10;
break;
}
}
}
#include <p18f4550.h>
#include <delays.h>
/*-----Definicion de estados--------*/
#define ciclo_10 1 //Ciclo del 10%
#define ciclo_20 2 //Ciclo del 20%
#define ciclo_30 3 //Ciclo del 30%
#define ciclo_40 4 //Ciclo del 40%
#define ciclo_50 5 //Ciclo del 50%
/*-----Definicion de pines-----------*/
#define PWM1 LATBbits.LATB0
#define PWM2 LATBbits.LATB2
#define button1 PORTAbits.RA0
/*-------------------------------------*/
unsigned char contador1,contador2,PwmValue,PwmValue2,estado;
/*----Prototipos de funciones----------*/
void phase_shift(void);
/*-------Interrupción de Alta_Prioridad---------*/
void Interrupt_ISR_TMR0(void);
#pragma code High_vector_Interrupt = 0x08
void High_vector(void){
_asm goto Interrupt_ISR_TMR0 _endasm
}
#pragma code
#pragma interrupt Interrupt_ISR_TMR0
void Interrupt_ISR_TMR0 (void)
{
INTCONbits.TMR0IF=0; /*Borramos bandera*/
TMR0L=243;
if(++contador1>10) contador1=1;
if(++contador2>10) contador2=1;
if(PwmValue>=contador1) PWM1=1; else PWM1=0;
if(PwmValue2>=contador2) PWM2=1; else PWM2=0;
}
void main(){
estado=ciclo_10;
TRISB=0x00;
LATB=0x00;
TRISAbits.RA0=1; //Como entradas
//LATAbits.LATA0=0;
/*---------Configuracion Oscilador--------*/
OSCCONbits.SCS1=0; //Oscilador primario
OSCCONbits.SCS0=0;
ADCON1=0x0F; //Todos los pines como digitales
T0CONbits.TMR0ON=0; //Timero Off
T0CONbits.T08BIT=1; //Configuracion a 8bits
T0CONbits.T0CS=0; //Internal Instruccion
T0CONbits.T0SE=0;
T0CONbits.PSA=0; //Prescaler On
T0CONbits.T0PS2=0; //Prescaler 1:2
T0CONbits.T0PS1=0;
T0CONbits.T0PS0=0;
RCONbits.IPEN=1; //Habilitamos la prioridad
INTCONbits.TMR0IF=0; //Interrupcion por desbordamiento
INTCONbits.GIE_GIEH=1;
INTCONbits.GIEH=1; //Activamos alta_Prioridad
INTCONbits.TMR0IE=1;
INTCON2bits.TMR0IP=1; //TMR0 Alta prioridad.
T0CONbits.TMR0ON=1; //On Timer0
while(1){
switch(estado){
case ciclo_10 :
PwmValue=1;
PwmValue2=1;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_20;
break;
case ciclo_20 :
PwmValue=2;
PwmValue2=2;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_30;
break;
case ciclo_30 :
PwmValue=3;
PwmValue2=3;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_40;
break;
case ciclo_40 :
PwmValue=4;
PwmValue2=4;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_50;
case ciclo_50:
PwmValue=5;
PwmValue2=5;
while(button1);
Delay1KTCYx(10);
while(!button1);
Delay1KTCYx(10);
estado=ciclo_10;
break;
}
phase_shift();
}
}
void phase_shift(void){
unsigned char tmp;
tmp=(contador1+6)%11;
if(!tmp) tmp++;
contador2=tmp;
}