En el analisis vamos a ir por parte
#define _XTAL_FREQ 1000000
Tenes puesto un cristal de 1Mhz ? O tenes uno de 4Mhz y pensaste que debes poner alli 1Mhz ?
-------------------------------------------------
ADC:void config_ADC(){
TRISAbits.TRISA0 = 1; // setear A0 como entrada
TRISAbits.TRISA3 = 1;
ADCON1 = 0b00000101; // voltaje de referncia Vdd
ADCON0 = 0x00;
PIE1bits.ADIE = 1;
PIR1bits.ADIF = 0;
}
Segun tu codigo estas usando lo siguiente:
- Fosc/2
- RA3 es VREF ( el cual lo mas simple es conectarlo a VDD a ese pin)
- RA0 que es tu entrada y que es la seleccionada.
Para evitar la conexion de RA3 a VCC, total si o si pones 3 pines ( RA0,1 y 3 ) como analogicos, mejor elegir la opcion que pone internamente VREF a VDD.
Tambien para evitar problemas, en ves de hacerlo dependiente del oscilador que pongas, vamos a usar el oscilador RC que posee el ADC
void config_ADC(){
TRISAbits.TRISA0 = 1; // setear A0 como entrada
TRISAbits.TRISA3 = 1;
ADCON1 = 0b00000100; // RA0, RA1 y RA3 analogicos, VREF = VDD
ADCON0 = 0xC1; //FRC y ADC ON
PIR1bits.ADIF = 0; //Limpias flag
PIE1bits.ADIE = 1; // Activas interrupcion
}
Podriamos omitir los TRIS, ya que en el reset todos estan como entradas.
-----------------------------
PWMAca voy a suponer que tus valores son correctos. ( Periodo/Duty )
No parece haber nada malo, y corresponden con tus comentarios si es que realmente esta ingresando 1Mhz.
Lo que si tenes que saber que lo maximo a cargar en el duty es (PR2 * 4) es decir 996, usando los 10 bits. O maximo de 249 usando 8 bits (solo el registro CCPR1L )
-----------------------------------
Funcion mainHicimos un par de cambios aca.
El INTCON.GIE lo pasamos a la funcion "interrupciones"
El ADCON0.ADON lo pasamos al "config_ADC"
Y finalmente necesitamos saber cuando es que le vamos a dar marcha al ADC
void main(void) {
config_pwm();
config_ADC();
interrupciones();
ADCON0bits.GO = 1;
while(1);
}
No recuerdo bien el nombre del bit, porque tiene varios (es el bit GO_DONE ), vos pones a 1 ese bit y solo resta esperar que termine la conversion, a la cual va a salir la interrupcion.
---------------------------------
InterrupcionUn pequeño cambio, si observas no posee sentido alguno que tengas una variable ahi.
Asi que la vamos a eliminar, y el error es que para que inicie de nuevo la conversion es que debemos activar el bit GO_DONE de nuevo
quedando:
void interrupt ADC_vector(){
PIR1bits.ADIF = 0; // Limpio flag
CCPR1L = ADRES; // Actualizo PWM
ADCON0bits.GO = 1; // Inicio de nuevo la conversion
}