Atmega64M1 DAC not responsive

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My current development setup includes an STK600 for breakout of all the pins, an Atmel-ICE for debugwire debugging capabilities, and a cheap little oscilloscope for verifying outputs.

I am developing on the Atmega64M1-AU chip with plans to migrate to the AtmegaS64M1 radiation-tolerant version once my development is completed.

The STK600 is currently configured to provide target power and the AREF0 voltage of 1.02V (This was the closest I could get to the 1.024V that I plan on using as an external voltage reference on my final design).

I have verified that both AVCC and and VCC are at the same voltage by means of probing the MCU pins directly with the scope. I used Atmel START to get a good base configuration. Unfortunately, when trying to write ANYTHING to the DACL portion of the DAC register, it gets entirely ignored. I have tried both 

DAC = 1023;

as well as embedding this function in the dac header file and calling it in my main routine.

static inline void writeDAC(uint16_t n) {
	DACL = n & 0xFF;
	DACH = n >> 8;
}

but, when I run the program with debugwire enabled, I can see the DACH portion being updated with 0x03, but DACL never changes from 0x00. I am watching the scope with a setting of 200mV/div just to see any minor changes, but alas, nothing happens.

 

My DAC initialization routine is as follows:

int8_t DAC_0_init()
{
	PRR &= ~(1 << PRADC);
	ADMUX = (0 << REFS1) | (0 << REFS0);
	DACON = (0 << DALA)        /* Digital to Analog Left Adjust: disabled */
	        | (1 << DAEN)      /* Digital to Analog enable: enabled */
	        | (1 << DAOE)      /* Digital to Analog Output enable: enabled */
	        | (0 << DAATE)     /* DAC Auto Trigger Enable: disabled */
	        | (0x00 << DATS0); /* Analog Comparator 0 */

	return 0;
}

 

Attachment(s): 

This topic has a solution.

73 de KN4ZXN

Last Edited: Wed. Jul 29, 2020 - 06:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So after poking around a bit more, I found that clicking on those empty DACL bits in the I/O viewer would affect some values in the data 0x00AB line of memory but seemingly with random values every time. This is odd considering the memory line of interest is 0x0091 which is just above 0x00AB in the Memory 4 window. I tried switching the ADC source to AVCC and I get full scale control up to 3.3V but those DACL bits are still showing up as empty in the I/O viewer. This makes me think it's just a broken feature of AS7 and I can't rely on that to debug the DAC. When looking at the memory window, it still fails to show any updates to the DACL register, but sending a value of, say 125, which would be entirely in that lower portion successfully updates the output when using AVCC as a source. I'm wondering if I am just using this debug feature incorrectly. Either way, using an external AREF still doesn't work for some reason.

73 de KN4ZXN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just added the following line to the beginning of my DAC initialization routine. No success there.

	ADCSRB = (0 << ISRCEN) | (1 << AREFEN);	

 

73 de KN4ZXN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PlatinumLuthier wrote:

| (0x00 << DATS0); /* Analog Comparator 0 */

Although ORing zero bits does not do anything, I still don't think having an 8 bit value here is what you intended.

 

PlatinumLuthier wrote:

static inline void writeDAC(uint16_t n) {
	DACL = n & 0xFF;
	DACH = n >> 8;
}

C does not guarantee order of execution, so best to just write to DAC here, the compiler knows how to do that, this goes for any 16 bit reg.

 

Suggestion, write a small, Complete, test program that demos the problem and post that, then other freaks can load and run your program and help you with debugging, rather then post parts and pieces, in most cases, doing this exercise, you will find your answer.

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


You may need the ADC enabled so this control reg will enable an external vRef using the AREFEN bit in ADCSRB.

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I think I just found my problem. It wasn't really clear to me that the datasheet did NOT differentiate between Vref and whatever you put into the AREF pin. It states a minimum value for Vref is 2.56V. When I cranked up the reference voltage from the STK600, it started to respond at around 1.35V, but that's probably stressing the internal circuitry. I guess I'll have to rethink which external reference I should use in my final design if any at all. I may as well just use the internal 2.56V Bandgap reference at this point.

73 de KN4ZXN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I also tried that on a whim and it didn't produce any immediately noticeable results, but after increasing my external reference voltage, it came to life. Regarding the ORing of zero bits, I didn't think that would work either, but the compiler seems to recognize that (unless all bits are default zero and it truly is a waste of text). Since I'm not using any external triggering, that line is just a placeholder anyway. Also, regarding the order of operations, there's been a number of complaints about how most 16-bit write operations are done High byte first, but for some reason, Atmel has decided to go the Low-byte first route with the DAC. If I try to write DAC = 1023, it attempts to write the high byte first because that's just how avr-gcc has been hard coded. For this reason, one needs to be very specific when writing to the DACH and DACL registers in the proper order. As far as posting the whole program, there really isn't much else to post. I have a couple blinking lights and a UART. The DAC portion is nicely contained in the dac.c file which was generated from Atmel START. Here is the finalized working version of my dac.c file:

/**
 * \file
 *
 * \brief DAC related functionality implementation.
 *
 (c) 2018 Microchip Technology Inc. and its subsidiaries.

    Subject to your compliance with these terms,you may use this software and
    any derivatives exclusively with Microchip products.It is your responsibility
    to comply with third party license terms applicable to your use of third party
    software (including open source software) that may accompany Microchip software.

    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    PARTICULAR PURPOSE.

    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
 *
 */

/**
 * \addtogroup doc_driver_dac
 *
 * \section doc_driver_dac_rev Revision History
 * - v0.0.0.1 Initial Commit
 *
 *@{
 */
#include <dac.h>

/**
 * \brief Initialize dac interface
 *
 * \return Initialization status.
 */
int8_t DAC_0_init()
{
	PRR &= ~(1 << PRADC); /* Power up the ADC Module */
	ADCSRA = (1 << ADEN); /* Enable the ADC */
	ADCSRB = (0 << ISRCEN) | (1 << AREFEN);	/* Disable the current source and connect the AREF pin to the DAC */
	ADMUX = (0 << REFS1) | (0 << REFS0); /* External Vref on AREF pin, Internal Vref is switched off */

	DACON = (0 << DALA)        /* Digital to Analog Left Adjust: disabled */
	        | (1 << DAEN)      /* Digital to Analog enable: enabled */
	        | (1 << DAOE)      /* Digital to Analog Output enable: enabled */
	        | (0 << DAATE)     /* DAC Auto Trigger Enable: disabled */
	        | (0x00 << DATS0); /* Analog Comparator 0 */

	return 0;
}

And here is my finalized dac.h file:

/**
 * \file
 *
 * \brief DAC related functionality declaration.
 *
 (c) 2018 Microchip Technology Inc. and its subsidiaries.

    Subject to your compliance with these terms,you may use this software and
    any derivatives exclusively with Microchip products.It is your responsibility
    to comply with third party license terms applicable to your use of third party
    software (including open source software) that may accompany Microchip software.

    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    PARTICULAR PURPOSE.

    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
 *
 */

#ifndef DAC_H_INCLUDED
#define DAC_H_INCLUDED

#include <compiler.h>

#ifdef __cplusplus
extern "C" {
#endif

int8_t DAC_0_init();

static inline void writeDAC(uint16_t n) {
	DACL = n & 0xFF;
	DACH = n >> 8;
}

#ifdef __cplusplus
}
#endif

#endif /* DAC_H_INCLUDED */

73!

Seth KN4ZXN

73 de KN4ZXN

Last Edited: Wed. Jul 29, 2020 - 07:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
, I still don't think having an 8 bit value here is what you intended.
Where are you seeing an "8 bit value"?

 

In actual fact it's 16 bit but that's another thing, my point i that putting 0x00 does not suddenly make soething 8bit just as 0x00000007 doesn't make this 32 bit either.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

ki0bk wrote:
, I still don't think having an 8 bit value here is what you intended.
Where are you seeing an "8 bit value"?

 

In actual fact it's 16 bit but that's another thing, my point i that putting 0x00 does not suddenly make soething 8bit just as 0x00000007 doesn't make this 32 bit either.

I changed that line to just 

(0 << DATS0)

but, either way, this was an auto-generated line from Atmel START as a placeholder.

The DAC is performing beautifully now, but unfortunately, I've lost some resolution having to increase my reference voltage. My goal was to output 0-800mV to "inject" into the feedback node of a switching regulator to control its output. It seems that when I lower my reference voltage from 2.56V down to 2.048V, it still performs nicely in the required range, but loses linearity beyond that. That's something I picked up not too long ago, that using a reference voltage that aligns nicely with the resolution of the DAC will give you nice even steps between incremental changes in output voltage. 

73 de KN4ZXN