Problema con PWM 18f4550

#1
Hola a todos!! feliz navidad!!!!, vereis estoy usando un p18f4550 y queria hacer un control pwm con los registros que ya lleva el micro, el codigo que utilizo es el siguiente:
Código:
#include <p18f4550.h>
#pragma config FOSC=HS
#pragma config DEBUG=ON
#pragma config MCLRE=OFF

void main (void){
	unsigned char duty=100, nduty, flag=0;
	unsigned int ton;
	
	TRISC=0xFD;//RC1 como salida
	TRISA=0x00;//puerto A como entrada
	T2CON=0x07;//Se configura T2 con preescalar 1:16 y postescalar 1:1 y se pone en marcha
	CCP2CON=0x0F;// Se configura CCP como PWM
	PR2=124;// valor calculado
	ton=duty*5;//valor calculado
	//ton=800;
	CCPR2L=ton/4;
	CCP2CONbits.DC2B0=ton&0x0001;
	CCP2CONbits.DC2B1=ton&0x0002;
	nduty=duty;// se inicializa nduty al valor duty
	while(1){
//aumenta o disminuye el valor de nduty solo 1 vez por pulso
	if(PORTAbits.RA0==1 && flag==0){
	nduty=nduty+5;
	flag=1;
	}
	if(PORTAbits.RA1==1 && flag==0){
	nduty=nduty-5;
	flag=1;
	}
	if(PORTA==0x00 && flag==1)
	flag=0;
//-----------------------------
	if(nduty!=duty){ //comprueba si el valor de nduty ha cambiado y si es asi lo cambia.
	duty=nduty;
	ton=duty*5;//valor calculado
	CCPR2L=ton/4;
	CCP2CONbits.DC2B0=ton&0x0001;
	CCP2CONbits.DC2B1=ton&0x0002;
	}
	

	}
	
	}
, y tengo dos problemas, pero bueno primero os explico un poco el programa, la primera parte es solo de configuración de los registros e inicializo la variable duty que va a ser el ciclo de trabajo que quiero que tenga la señal, luego hay otra variable que es nduty, que al principio tiene el mismo valor que duty, y es la que voy a ir variando, entonces, ya dentro del while(1), lo primero que hago es si le doy un 1 a Ra0, incremento el duty en 5, y si se lo doy a Ra1, lo decremento en 5, para que solo cuente 1 vez cada vez que le doy un pulso esta la variable flag que solo deja que suba 5 por pulso, luego si nduty es diferente del duty anterior, le doy al duty el valor de nduty y actualizo el tiempo ton, si es igual, no actualiza nada.
bueno dicho esto tengo 2 problemas, primero, no consigo que el ciclo de trabajo suba del 50%, es mas, si pongo 60 me baja al 10%, 70 al 20%, es como si el 100% estuviera en el 50% y si me paso vuelve a empezar, y segundo y problema que me tiene frito. . . . nunca entra en los if de los pulsadores, si le doy a Ra0 un 1, no entra en ese if, igual con Ra1. . .
de momento no lo he implementado, solo lo estoy depurando con el proteus desde el mplab, y tambien he probado con el proteus solo y no funciona. . . , entes hice un pwm usando los temporizadores y me pasaba lo mismo!! no entraba en los ifs. . sabeis que puede pasar??
un saludooo!!!
 
#2
empieza por recordar la funcion while.- es más empieza por recordar la simulación.
¿que hace que pase el while?
¿que ocurre cuando esta siempre a 1?
Mira la do-> que va mejor.
 
#3
pero el while lo unico que hace es que el programa se repita constantemente. . . . y eso si que funciona bien. . no se lo que me quieres decir.. . .
 
#4
Creo que te puedo ayudar con de los botones: si vas a usar PORTA como entradas, tenés que configurarlas como digitales (y no análogas) a través del registro ADCON1.
 
#6
Yo creo que no es tanto así, en la datasheet página 113 dice:
On a Power-on Reset, RA5 and RA3:RA0 are configured as analog inputs and read as ‘0’. RA4 is configured as a digital input.
Y abajo de eso te sale el código en ensamblador para inicializar el PORTA, que incluye configurar ADCON1 con los bits correspondientes según tu situación.

Otra cosa que no me había fijado, es que TRISA lo estas inicializando con 0x00, como salida. En la misma página del datasheet podés ver que tenés que tenés que poner un 1 para que funcione como entrada. En tu caso tendrías que inicializar TRISA con 0x03.

Ojalá esto te sirva.
 
Última edición:
#7
cierto!!!! lo siento!!!!! pero los he puesto en el puerto D que no tiene entradas analogicas y si que entra!! gracias!! y a lo de que nunca sube del 50% de ciclo de trabajo?? utilizo las formulas del datasheet pero no consigo que pase del 50%!!, si pongo para que haya un 60% vuelve al 10%
 
#8
se que este post es antiguo pero lo he visto y ya lo solucione la duda que planteaba. El problema es que el valor de PR2 era mayor que 255, no tenia en cuenta que PR2 es un registro de 8 bits, entonces solo contaba hasta 255, y como el duty depende también de del valor de periodo no funcionaba bien. solucione eso y ahora fijándome el los valores máximos que pueden tomar las variables todo funciono perfectamente ^^
Un saludo
 
Arriba