#include <p30f3013.h>
#include <uart.h>
_FOSC(CSW_FSCM_OFF & HS3_PLL16) //Fcy = 20e6*16/(3*4) = 26.6 MIPS - Tcy= 37.5 nanosegundos
_FBORPOR(MCLR_EN & PWRT_OFF)
_FWDT(WDT_OFF);
void InitADC(void);
void PortsSetup(void);
void __attribute__((__interrupt__)) _ADCInterrupt(void);
int main(void)
{
InitADC();
PortsSetup();
PORTDbits.RD9 = 1;
OpenUART2(UART_EN & UART_IDLE_CON & UART_EN_WAKE & UART_DIS_LOOPBACK & UART_NO_PAR_9BIT & UART_1STOPBIT,
UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_INT_RX_CHAR & UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR,
12); //baud = 128000
while(1)
{
asm("clrwdt"); // espera un bucle infinito
}
}
/*
Configuracion ADC:
1) 1 canal (no scan): AN2
2) Automatic Sample start
3) Automatic Stop Sampling and start converting
4) 16 muestras por interrupcion
5) Timer3 triggered
*/
void InitADC(void)
{
//Muestreo automatico.
ADCON1bits.ASAM = 1;
//Timer3 triggered
ADCON1bits.SSRC = 2;
//Formato entero con signo
ADCON1bits.FORM = 1;
//Interrupcion cada 16 muestras en buffer
ADCON2bits.SMPI = 15;
//Fs = 6400 Hz.
//Ts = 1/Fs = 1/6400 = 156us
//Siendo Tcy = 37.5ns
//Tad > 667ns
//Configuro el Timer del AD al maximo valor posible: ADCS = 63.
ADCON3bits.ADCS = 63;
//Tad = Tcy*(ADCS+1)/2 = 37.5ns *(63+1)/2 = 1.2 us
//14Tad por cada muestra (16,8us)
//Configuro el Timer3 con un tiempo de interrupción de 156us para iniciar la conversion
//Calculo el periodo de interrupcion:
//Periodo interrupcion = Tcy * prescaler * PR3 = 156us (siendo el prescaler = 1);
//por lo que PR3 = 156us/ 37.5ns = 4167, para un periodo aproximadamente de 156.2625us (6399.49 Hz)
TMR3 = 0x0000;
//Configuro prescaler
T3CONbits.TCKPS = 0;
//Configuro PR3
PR3 = 4167;
//Limpio flags
IFS0bits.T3IF = 0;
IEC0bits.T3IE = 0;
//Conecto AN2 al canal CH0
ADCHS = 0x0002;
//Escaneo deshabilitado.
ADCSSL = 0x0000;
//RB2 analogico.
ADPCFG = 0xFFFB;
//Limpio flag de interrupción
IFS0bits.ADIF = 0;
//Habilito interrupción
IEC0bits.ADIE = 1;
//Enciendo en conversor
ADCON1bits.ADON = 1;
//Enciendo en Timer3
T3CONbits.TON = 1;
}
void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt(void)
{
IFS0bits.T3IF = 0;
IFS0bits.ADIF = 0;
if(PORTDbits.RD9 == 1)
PORTDbits.RD9 = 0;
else
PORTDbits.RD9 = 1;
WriteUART2(ADCBUF0);
WriteUART2(ADCBUF1);
WriteUART2(ADCBUF2);
WriteUART2(ADCBUF3);
WriteUART2(ADCBUF4);
WriteUART2(ADCBUF5);
WriteUART2(ADCBUF6);
WriteUART2(ADCBUF7);
WriteUART2(ADCBUF8);
WriteUART2(ADCBUF9);
WriteUART2(ADCBUFA);
WriteUART2(ADCBUFB);
WriteUART2(ADCBUFC);
WriteUART2(ADCBUFD);
WriteUART2(ADCBUFE);
WriteUART2(ADCBUFF);
}
void PortsSetup(void)
{
TRISDbits.TRISD9 = 0;
PORTDbits.RD9 = 0;
}