This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DAC161S997: Issues with DAC output

Part Number: DAC161S997
Other Parts Discussed in Thread: MSP430FR2355, TIDA-00648, TIDM-01000

Good morning,

I have some issues with the communication between the MCU MSP430FR2355 and the DAC161S997.

My goal is to simply program the current that I want on the DAC output.

For now, I get 2.119 mA on LOOP- (although I asked in the code for 5mA). Pin ERRB is low, so there is an error somewhere...

For testing I use 2 interrupts for reading the registers 0x09 and 0x05 (so I sent commands 0x89 and 0x85).

I tried to send

0x89 0x5555   0x02 0xDEAD   (read status and NOP)

and I get on MISO 0x20 0xDEAD 0x89 0x00E1 (that "1" indicates a loop error)

When I send 0x85 0x5555 0xDEAD (read error config and NOP) and

I get on MISO : 0x20 0xDEAD 0x85 0x00F1 (that's OK)

   The SPI timings seem correct.


I program the MCU with the "MSP430FR2355 LaunchPad". When the system is only powered up with the launchpad (only the 3V3) , ERRB gets high (so, no error). But when I power the entire system (by LOOP+ / LOOP-) ERRH gets down.


Is there anything I missed or something I can test ?

If it can help, I enclosed below the programs and the schematic. I used the TIDA-00648 and TIDM-01000 as references.

Can anybody help me find the problem ?

I'm a beginner with microcontrollers, it might be a stupid mistake.

Best regards,

Christophe FELDER


#include <stdio.h>

#include <msp430.h>

#include <intrinsics.h>

#include "DAC161.h"


volatile int flag_4ma = 0;

volatile int flag_20ma = 0;

unsigned char DAC_Error_Processing;

unsigned char dacStatus = 0;


void USCIA1_Init(void);

unsigned char USCIA1_SPI_WriteByte (unsigned char data);

unsigned char DAC161_Read_Status (void);

void DAC161_Write_Regs (unsigned short *writeValues, unsigned char startReg, unsigned char lengthBytes);

void Setup_DAC161 (unsigned short errConfig, unsigned short errLow_uA, unsigned short errHigh_uA);



void main(void) {

   volatile int i=0;

   WDTCTL = WDTPW | WDTHOLD;       // Stop watchdog timer

   PM5CTL0 &= ~LOCKLPM5;


   P4DIR &= ~BIT0;                   // Input Pins

   P4IES |= BIT0;                    // High to Low Edge

   P4IFG &= ~0xFF;                   // Clear any pending interrupts

   P4IE |= BIT0;                   // Enable Interrupts

   P3OUT &= ~BIT7;                 // Clear P3.7 output latch for a defined power-on state

   P3DIR |= BIT7;                   // Set P3.7 to output direction

   P1DIR &= ~BIT0;                   // Set P1.0 as input

   P1IE |= BIT0;

   P1IES |= BIT0;

   P1IFG &= ~BIT0;                  // P1.0 IFG cleared

   P1DIR &= ~BIT1;                   // Set P1.1 as input

   P1IE |= BIT1;

   P1IES |= BIT1;

   P1IFG &= ~BIT1;                   // P1.1 IFG cleared

   __bis_SR_register(GIE);           // Enter LPM0 w/ interrupt



 Setup_DAC161(DAC161_STD_ERR_CONFIG_MASKED, 3000, 22000);     // Configure the DAC161

   DAC_Error_Processing = 0;

   DAC161_Set_Out_Value (5000); //does not work




   while (1)   {

       if (DAC_Error_Processing) {             // Perform DAC ERROR Processing Here

           DAC_Error_Processing = 0;

           dacStatus = DAC161_Read_Status();         // Read Status to clear error




#pragma vector=PORT1_VECTOR

__interrupt void Port_1(void)




   case 0: break; // No Interrupt

   case 2:

       flag_20ma = 1;                     //interrupt on P1.0

       P2OUT &= ~BIT1;                 //CS DAC = 0

       USCIA1_SPI_WriteByte(0x89);       //READ STATUS



       P2OUT |= BIT1;                 //CS DAC = 1

       DAC161_Nop();                     // to read status

       P1IFG &= ~BIT0;                   // clear flag

       break; // P1.0

   case 4: // interrupt on P1.1


       P2OUT &= ~BIT1;                 //CS DAC = 0

       USCIA1_SPI_WriteByte(0x85);       //READ ERR CFG



       P2OUT |= BIT1;              


       P1IFG &= ~BIT1; //CS DAC = 1

       break; // P1.1




#pragma vector=PORT4_VECTOR

__interrupt void Port_4(void) {

   if (P4IFG & BIT0) {   // Has an error from the DAC occurred? (ERRB -> 0)

       DAC_Error_Processing = 1;


   P4IFG = 0;



void USCIA1_Init(void) {

   P4SEL0 |= BIT1 + BIT2 + BIT3;   // Configuration MOSI MISO SCK

   P2OUT &= ~BIT1;                  //CS_DAC

   P2DIR |= BIT1;

   UCA1CTL1 |= UCSWRST;                                           // Enable SW reset

   UCA1CTLW0 = UCMST + UCSSEL__SMCLK + UCMSB + UCSYNC + UCSWRST;   // SPI Master, 3 wire, synchronous mode

   UCA1BR0 = 0;                                                  // SMCLK/1 = SCLK (1MHz)

   UCA1BR1 = 0;

   UCA1CTL1 &= ~UCSWRST;                                           // Clear SW reset, resume operation



unsigned char USCIA1_SPI_WriteByte (unsigned char data) {

   while (!(UCA1IFG&UCTXIFG));     // USCI_A1 TX buffer ready?

   UCA1IFG &= ~UCRXIFG;             // Clear RX Interrupt flag

   UCA1TXBUF = data;               // Place data in TX Buffer

   while (!(UCA1IFG & UCRXIFG));   // Wait for end of data receive

   return ((unsigned char)UCA1RXBUF);           // Return the received byte from RX Buffer



unsigned char DAC161_Read_Status (void) {       // read dac status

   unsigned char returnValue[3];

   DAC161_Read_Regs (returnValue, DAC161_STATUS_REG, 2);

 return (returnValue[2]);


void DAC161_Write_Regs (unsigned short *writeValues, unsigned char startReg, unsigned char lengthBytes) {

   unsigned char outData[3];

   outData[0] = DAC161_SPI_WRITE_CMD(startReg);

   outData[1] = *writeValues >> 8;

   outData[2] = *writeValues & 0xff;

   USCIA1_SPI_write_DAC (outData, RcvData, lengthBytes+1);   // Add 1 to length for command byte



void Setup_DAC161 (unsigned short errConfig, unsigned short errLow_uA, unsigned short errHigh_uA) {

   unsigned short errValue;

   DAC161_Write_Regs (&errConfig, DAC161_ERR_CONFIG_REG, 2);

   errValue = DAC161_CONVERT_ERR_VALUE(errLow_uA) & 0x7f00;

   DAC161_Write_Regs (&errValue, DAC161_ERR_LOW_REG, 2);

   errValue = DAC161_CONVERT_ERR_VALUE(errHigh_uA) & 0xff00;

   if (errValue < 0x80)

       errValue = 0x80;

   DAC161_Write_Regs (&errValue, DAC161_ERR_HIGH_REG, 2);



  • Hi Christopher,

    I think the first thing you should check is that your supply is allowed to be floating. Note that loop- is a lower potential than ground (COMA/COMD). The voltage differential between loop minus and ground is dependent on the desired loop current. If for example your loop minus is connected to earth ground and so is your microcontroller, then the device will not be able to regulate the current.



  • Hello, thanks a lot for your answer, I will check that after the end-of-year holidays.

    Merry Christmas and Happy New Year


  • Good morning and happy new year

    I can now confirm that there is not continuity between LOOP- and GND  (150kΩ)
    The potential between GND and LOOP- is about 0.596V.

    Best regards

  • Christophe,

    I don't see any connection or code issues with the system but I had a few other follow-on questions to this problem. What is the loop supply voltage that you are using? I assume that you're using a resistor inserted into the loop to measure the current. What resistor value are you using? Is the resistor connected to LOOP- to the negative connection of the loop supply?

    I would also check to see if the current is linear with the DAC code. I would set the DAC code to several values and measure the current. Using codes like 2000, 4000, 6000, 8000, ... E000, FFFFh, record the output current and plot them to check. When you record them, you can insert them into a table into a reply post.

    Joseph Wu

  • Hello Joseph, thanks for your answer

    For the loop receiver I use a precision 100 ohm resistor, connected as in the schematic :

    The loop supply is 24VDC.

    The DAC doesn't generate any output, I keep having ERRB interrupts when I send SPI commands. I get 2.1mA for every code I try.

    Best regards,
    Christophe FELDER

  • Christophe,

    If there is a loop error (based on the ERRB indication and the reading the STATUS register), then we should try to check the actual loop to see where the current is flowing. First, we had asked about the LOOP- voltage for which you mentioned was about -0.6V. However, this voltage probably includes the zener diode in your circuit. Really, the voltage we would want to know is the voltage from GND (or COMA) to OUT, which doesn't include the forward bias zener. At OUT, this voltage across the 40Ohm internal resistor gives most of the current going to LOOP- into the receiver.

    Then, I would measure the voltage across the emitter resistor of the NPN. This will give the controlled current pulled from LOOP+.

    Record these voltages and verify that the supply and loop receiver grounds are not the same as the device ground.

    Joseph Wu

  • Good morning,

    I measure about -81mV between GND and OUT and almost nothing (-0.005mV) between the GND and the emitter

    I checked that the loop receiver ground is not the same as the GND.

    Thank you for your guidance.

    Christophe FELDER

  • Christophe,

    I'm still unsure why you're not getting a proper output. I've gone back through your schematic and it looks fine to me.

    Returning to your measurements, with GND to OUT equal to -81mV, that would be about 2.045mA in the loop. This comes from the internal 40Ω resistor in the DAC, and is close to the 2.1mV that you're measuring at LOOP-. That likely means that the NPN isn't pulling current (or very much current) from LOOP+. Your measurement of the emitter resistor of the NPN was 0.005V. With this at 20Ω, It looks like that you're pulling 250uA from LOOP+ this isn't much current. I was thinking that you would have a little more, given that the loop current is about 2mA. Is there anything else powered off of the 3.3V supply not shown in the schematic?

    With the ERRB indication, and the STATUS read showing a loop error, that still seems like the likely problem. As I mentioned earlier though, the schematic looks ok to me. Below are things that I'd like you to check.

    Because the device is giving the loop error, I would check to see that the LDO is properly giving the output voltage. Check to see that the LDO output is 3.3V and then make sure that the VIN to VOUT voltage is the correct voltage. If you have a 24V supply for the loop, the VIN to VOUT voltage should be about 20V. The remaining 4V comes from the LDO output voltage, the voltage drop to OUT, the forward biased zener diode, and then the receiver voltage.

    For the loop, I would check to make sure the loop supply and the loop receiver are both on the same ground. I would also make sure they are independent from the uC/DAC ground. I know you measured this before, but I just wanted to check that the supply isn't on earth ground and while the uC is also on earth ground through a computer connection. Also check that the grounds for the uC, LDO, and the emitter of the NPN (through the resistor are also connected to the same ground as the DAC. The schematic looks like they are, but just verify the connection.

    I would also check the BASE voltage to make sure that it is pulling up to turn on the NPN. This voltage should be a diode voltage above ground, so that it can turn on the NPN. Again, you can use the voltage across that 20Ω resistor to verify that there is current being pulled through the NPN.

    For the loop supply, what power supply are you using and are you sure that it can supply 25mA? It's not directly shown on the schematic, Do you have it connected directly to LOOP+, or do you have any other diodes or other protection circuitry?

    Joseph Wu

  • Christophe,

    I haven't heard back from you for a while, so I wanted to check back with you on your loop setup. Have you been able to get the device to output the proper loop current? In my last post, I made a few debugging suggestions using measurements around the loop. By making the measurements, I had hoped this would lead to how the DAC output was off from what was expected.

    For now, I'll close this thread. Hopefully, you have solved this loop problem. If you haven't, post back and we'll continue working on this thread.

    Joseph Wu