Tengo un PIC12F1571 (hoja de datos aquí: enlace ) que he programado para leer un entrada analógica, realice algún procesamiento en el valor leído y, a continuación, obtenga un valor relacionado en el DAC de onchip.
Para las pruebas, he conectado un potenciómetro a la entrada analógica y puedo ver en el depurador de MPLAB que el PIC está leyendo el valor correcto (ADRESH / ADRESL están configurados adecuadamente por el ADC). También he verificado que los bits DAC se configuran correctamente en los registros DACCON0 y DACCON1. En el depurador puedo ver que el DAC se configura en la salida correcta, pero no hay voltaje en el pin de salida.
He comprobado dos veces la dirección de mi registro TRISA para los pines apropiados, me he asegurado de que el registro de función de pin alternativo no tenga conflictos y que todo lo demás esté deshabilitado.
El código está debajo. He configurado el PIC para que RA4 - pin 3 (Canal analógico 3) se use como entrada ADC y RA0 - pin 7 como salida DAC.
#if defined(__XC)
#include <xc.h> /* XC8 General Include File */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <pic12f1571.h>
#define SYS_FREQ 500000L
//#define FCY SYS_FREQ/4
//Set up using the Memory View (Window -> PIC Memory Views -> Configuration Bits
// CONFIG1
#pragma config FOSC = INTOSC // (ECH, External Clock, High Power Mode (4-32 MHz); device clock supplied to CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOREN = OFF // Low Power Brown-out Reset enable bit (LPBOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (Low-voltage programming enabled)
void setup(void)
{
/* Configure Interrupts
* INTCON - Interrupt Control Register:
* Set GIE (Global Interrupt Enable)
* Set PEIE (Peripheral Interrupt Enable bit (for ADC interrupts)
* Set TMR0IE (Timer0 Overflow Interrupt Enable bit)
*
* PEI1 - Peripheral Interrupt Enable Register:
* Set ADIE (ADC Interrupt Enable bit)
*/
INTCON = 0xE0;
PIE1 = 0x40;
PIE2 = 0x00;
PIE3 = 0x00;
/* Configure PORTA for the following:
*
* Configure TRISA for Port A Direction Control
* only have 1 input pin - RA4
* 1 output pin - RA0 (for DAC1)
*
* Configure ODCONA for Open-drain Control
* PORTA configured as standard push-pull
*
* Configure SLRCONA for Slew Rate Control
* Slew rate is unlimited
*
* Configure INLVLA for Input Threshold Control
* Doesn't need to be set since all input is analog
*
* Configure ANSEL registers for ADC operation on AN3 (RA4/pin 3)
*/
TRISA = 0x10;
ODCONA = 0x00;
SLRCONA = 0x00;
INLVLA = 0x00;
ANSELA = 0x10;
/* Configure TIMER0
*
* In OPTION_REG:
* Select Internal instruction clock
* Select no prescaler on the timer
*
* */
OPTION_REG = 0x84;
/* Configure ADC
*
* Set ADCON0 to the following:
* CHS set to analog channel AN3 = 00011 (RA4/pin 3)
* ADON set to ADC enabled = 1
*
* Set ADCON1 to the following:
* ADFM set to left justified = 0 (so that we can get away with reading a
* single byte for our converted value)
* ADCS Conversion clock source set to Fosc/8 = 001
* ADPREF set to Vdd reference = 00
*
* Set ADCON2 to trigger on Timer0 overflow
* ADCON2:TRIGSEL = 0011
*/
ADCON0 = 0x0D;
ADCON1 = 0x10;
ADCON2 = 0x30;
/* Configure up DAC
* Set DACCON0 register:
* DACEN set to DAC enabled = 1
* DACOE set to voltage level output = 1
* DACPSS<1:0> is set to Vdd = 00
*
* DACCON1 register contains the DACR bits (i.e. the output value)
*
*/
DACCON0 = 0xA0;
DACCON1 = 0x00;
// Set APFCON register to
APFCON = 0xFF;
}
void interrupt isr(void)
{
if(TMR0IF)
{
TMR0IF = 0; /* Clear TIMER0 Overflow Interrupt Flag*/
//ADC will automatically start converting now
// ++counter;
}
if(ADIF)
{ /* Clear ADC Completion Interrupt Flag */
ADIF = 0;
DACCON1 = ADRESH >> 3;
}
}
int main(int argc, char** argv) {
setup();
while(1);
return (EXIT_SUCCESS);
}
¿Qué me estoy perdiendo? Esto debería ser fácil ...