I'm trying to get the DAC of the PIC16F1704 to work, specifically I want it to output on pin RA2/DAC1OUT2. There's nothing connected to that pin, and I've reduced the test code to this:

#define _XTAL_FREQ 4000000
#define FCY 4000000ULL
#include <htc.h>

void main(void)
    WPUA = WPUC = 0;       // disable weak pull-ups
    nWPUEN = 1;
    ZCD1CON = 0;           // disable Zero-cross detect module

    SLRCONA = SLRCONC = 0; // disable slew-rate limiting
    ANSELA = 0xff;         // all analog
    TRISA  = 0b00111111;   // all inputs

    OSCCON = 0b01101011;   // 4 MHz internal oscillator, no PLL

    DAC1CON0 = 0b10010000; // DAC on, Vref+ = Vdd, Vref- = Vss, output on DAC1OUT2
    DAC1CON1 = 0;          // Tap #0: output 0.0V on DAC1OUT2
    while (1) {

This should output a ramp 0..Vdd in about 2.56 seconds, but instead what I see is this:


My Vdd is 3.3V. The skewed and inverted ramp is from 1.0 down to 0.4 V, with a plateau around 0.8V.

The problem seems to be with that particular pin, not the DAC itself. If I change the DAC config to

DAC1CON0 = 0b10100000;

I.e., output on DAC1OUT1 instead (RA0), I can read the ramp on that pin, it is perfectly linear, and not inverted.

It seems there is some peripheral that tries to keep pin RA2 on 0.8 volts, and does it in a weird non-linear fashion.

Any ideas what might this be? For completeness, here's what this pin is multiplexed with:

Pin summary - RA2

The Zero-cross detect circuitry fits the bill quite well, but as you can see, I've explicitly disabled it (btw changing the ZCDDIS_ON to ZCDDIS_OFF doesn't change anything).

The compiler is XC8 (1.31 I think) and I'm programming the chip with PicKit2.

  • \$\begingroup\$ ZCD does seem disabled - datasheet p52 says "... ZCD can be enabled by setting the ZCDSEN bit of ZCDCON ..." - I don't know how/if that relates BUT whatyou are seeing does look like it could be ZCD constant source/sink action. \$\endgroup\$
    – Russell McMahon
    Commented Dec 21, 2016 at 12:53
  • \$\begingroup\$ Yes, I feel it must be the ZCD module as well. I have some suspicion on the PicKit2 now, since it doesn't support the '1704 out of the box - I had to tweak the device list file to enable that. So maybe my tweaking is incorrect and it doesn't write the config words right, and I'm stuck at ZCDDIS_OFF. Anyway, this seems like a remote possibility, since the similar approach with the device file editor worked before for other parts, but I'll borrow a PicKit3 to verify. \$\endgroup\$
    – anrieff
    Commented Dec 22, 2016 at 22:20
  • \$\begingroup\$ WHen I'm using output peripherals, I generally change TRISx to outputs (TRISA &= 0x04;) Worth a shot if you haven't tried it. \$\endgroup\$ Commented Feb 17, 2017 at 19:24
  • \$\begingroup\$ Please follow up when you solve this one. You might want to consider asking in the Microchip forums. \$\endgroup\$ Commented Jun 7, 2017 at 15:02
  • \$\begingroup\$ Yep, I'm just about to try my PicKit2/PicKit3 suspicion tomorrow and will keep you all posted. \$\endgroup\$
    – anrieff
    Commented Jun 9, 2017 at 16:45

1 Answer 1


As discussed in the comments, I suspected my PicKit2 not programming the part correctly, leaving Config Word 2's ZCDDIS bit not set to the correct value of '1' (ZCD controllable by the ZCDCON register), but left as '0' (ZCD always enabled). This matched what we saw on the 'scope. After using a friend's computer and PicKit3 programmer we verified that the same chip, as programmed with PicKit3, does not exhibit the issue.

Therefore it's an problem in my machine's toolchain, most likely the PicKit2 programmer, which doesn't support PIC16F1704 out of the box and I had to hack the device file to support it, so I most likely messed up that part.


If anyone is curious, this is what I actually messed up when hacking up the device data file:

PICKit2 Device Data File Editor - correct settings for PIC16F1704

I was using the PICKit2 Device Data File Editor to add support for the PIC16F1704 device. The usual way to do that is to copy the parameters from a similar device and then change the expected device IDs and memory sizes. What I didn't pay attention then were the fields ConfigMasks - these have to be set to whatever bits in the config words are implemented (and '0's for bits that aren't). It seems that the part I copied my data from didn't have bit #7 of CONFIG2 implemented, so its respective bit #7 in ConfigMasks[1] was 0, so pk2cmd later on didn't try to program this bit to '1', even if it was specified as '1' in the HEX file. This meant that the ZCD was always enabled and wasn't controllable through the peripheral registers.

What you see on this screenshot are the correct values after a recent intervention. As you can see, ConfigMasks[1] = 0x3F83 - my bit #7 is '1' now. With these changes, the PIC also programs successfully and works as expected even if programmed with PicKit2.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.