2
votes

I'm not new to programming or C, but I am very new to chip programming in particular and I'm having a lot of trouble finding and deciphering documentation.

To be specific, I am using MPLab X IDE in conjunction with the XC8 compiler. My chip is a PIC12F1501. My intent (for now) is to gently pulse an LED, but eventually it will be adapted to drive a speaker with a sine wave. Pretty sure my circuit is good as I can make an LED blink on and off with a digital output.

Now, I understand how to set the TRIS register so that the right legs are output or input as required. I know how to use ANSEL to set these pins into analog mode. What I cannot seem to fathom is what command or combination of commands I need to use to actually write an analog value to a pin. I've used the latch (LAT) to set a digital output, but I can't see how to do the same thing with an analog value.

From the data sheet for the chip I get the vague idea that I'm supposed to set the value of some other register representing the DAC to determine the level of voltage output, and then latch to 1 just as you would for digital output, but I'm not used to reading these things. I've tried a number of register names that are hinted in the documentation for the DAC but none of them compile.

I've tried snippets of code for other chips in the same approximate family and none of them compile either.

Can someone share a brief snippet demonstrating how analog output works in the PIC12F1501?

3

3 Answers

0
votes

In the specification sheet for the PIC12(L)F1501, you will find the required registers described in chapter 16 (pages 124 - 126). In short summary they are DAC1CON0 and DAC1CON1. You set your desired value with the DAC1CON1 register and enable/configure with the DAC1CON0 register.

One thing to note is that the DAC is not meant to drive an external load and probably wont work with your LED attached unless you have an external buffer.

// With 5V and 0V Positive/Negative references, outputs 3.125V 
// (See manual equation 16-1).
DAC1CON1 = 20;

// Enable the DAC and output to both DACOUT pins using VDD as positive
// reference (see manual register 16-1).
DAC1CON0 = 0b10110000;

// Note that most chips also have utility structs in the MC8 headers so 
// you can also set the bits individually as follows:
DAC1CON0bits.DACOE1 = 1;
DAC1CON0bits.DACOE2 = 1;
DAC1CON0bits.DACEN = 1;
0
votes

The Microchip supplied header file does not define DAC1CON0 or DAC1CON1 only DACCON0 and DACCON1.

This code may build for you:

/*
 * File:        main.c
 * Target:      PIC12F1501
 * Compiler:    XC8 v1.45
 * IDE:         MPLABX v4.05
 * Author:      dan1138
 *
 *
 *                          PIC12F1501
 *              +---------------:_:---------------+
 *       PWR -> : 1 VDD                     VSS 8 : <- GND
 *           <> : 2 RA5         DACOUT1/PGD/RA0 7 : <> ICD_PGD 
 *           <> : 3 RA4                 PGC/RA1 6 : <> ICD_PGC
 *  ICD_MCLR -> : 4 RA3/MCLR    DACOUT2/INT/RA2 5 : <> DAC-OUTPUT
 *              +---------------------------------+
 *                             DIP-8
 *
* Created on July 25, 2018, 7:20 PM
 */
#pragma config FOSC = INTOSC    /* Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin) */
#pragma config WDTE = OFF       /* Watchdog Timer Enable (WDT disabled) */
#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 disabled) */
#pragma config CLKOUTEN = OFF   /* Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) */
#pragma config WRT = OFF        /* Flash Memory Self-Write Protection (Write protection off) */
#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 LPBOR = OFF      /* Low-Power Brown Out Reset (Low-Power BOR is disabled) */
#pragma config LVP = OFF        /* Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) */

#include <xc.h>

void main(void) 
{
    DACCON0 = 0x90;     /* DAC drives DACOUT2 */
    for(;;)
    {
        /* generate a 5-bit sawtooth outout */
        DACCON1 = (DACCON1 + 1u) & 0x1Fu;
    }
}
0
votes

Your PIC12F1501 also has got 4 PWM channels. You can very easily use these PWMs as analog output when you put a RC-Filter behind the pin. That will give you a resolution of up to 10 Bit.