ST 32F417 DAC1 and DAC2 initialisation - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: January 15, 2021, 07:06:57 am
content: I wonder if anyone has usedbothDACs?There is an output buffer option. This is a voltage follower but they haven't implemented it using modern rail to rail methods so there is a big zero offset of about 35mV. There is no negative rail available but this is still a lot considering we are not loading it (it is driving the input of a TLV2333; zero load). No problem... disable the output buffer! Well, you can on DAC1 (which then goes down to 0.5 LSB which is great) but not on DAC2. Either a bug in the silicon or a bug in ST's code, in the BOFF bit staying at zero for DAC2where Channel is 0 for DAC1 or 16 for DAC2.Another weird thing is whether one needs to call HAL_DAC_Start() for each output update. It's not clear whether you need to call it once and then will get a conversion every time you write the value or if you need to call it to start the conversion after writing every value. As with all "ST" lots of people have been up this road online and opinion seems to vary! Calling after writing every value just in case which seems to work, but is daft. This is a DAC, after all... why not just write a value? Well, one can't just write a value. One has to load a value into a register and then do a "release" which in the simplest case is done by software, it appears. But it should not be more than that.

author: newbrain
author_rank: Super Contributor
timestamp: January 15, 2021, 10:13:36 am
content: The code you show from HAL_DAC_ConfigChannel() looks correct, how are you initializing thesConfigchannel configuration structure?As forHAL_DAC_Start(): the need to call it or not depends on the channel configuration.If the trigger mode is set to NONE (DAC_TRIGGER_NONEin the HAL), there's no need to call it, the value set in the holding register will be immediately loaded by the DAC and reflected to output.If the trigger mode is set to SW (DAC_TRIGGER_SOFTWARE) one needs to callHAL_DAC_Start()to trigger the trasfer from the holding register to the output.Refer to chapter 14.3.4 inthe RM:QuoteSoftware trigger falls in the HW trigger category, just to mud the waters a bit.As this DAC is quite simple I would probably eschew the HAL, especially if not using DMA.

author: peter-h
author_rank: Super Contributor
timestamp: January 15, 2021, 05:12:24 pm
content: That's very useful; would have never guessed thatThis is the init:

author: newbrain
author_rank: Super Contributor
timestamp: January 15, 2021, 06:10:20 pm
content: At a cursory glance I don't see anything strange.If I have time I might try (with an F411 or an F407 - I have no F417) with some simple code later today or during the weekend.The processor errata does not mention anything related to the DAC buffers.As a general note, please use the code tags (# button) to post code, rather than an image.

author: peter-h
author_rank: Super Contributor
timestamp: January 15, 2021, 08:19:49 pm
content: Thank you.I reckon the buffer is just a low grade op-amp with probably an NPN-NPN output stage, so the lowest it will go (even when driving an infinite load) is Vce(sat) of the bottom transistor. Both DACs went down to the same voltage, 34-36mV. It is probably linear enough, so in another application one could follow it up with an inverting stage and bias it to discard the bottom 2% or so of the DAC range. I imagine a lot of people will be doing that anyway, so they can get down to "real zero" or even below.

author: newbrain
author_rank: Super Contributor
timestamp: January 16, 2021, 03:32:57 pm
content: So, I tried on a STM32F407 DISCO board.I used the CubeMx generator, so the code matches yours.Here are my findings:On the board, the DAC outputs (PA4 and PA5) are used: PA5 is connected to a high Z CMOS input, and PA4 to chip with an internal "weak pullup" (~1 MΩ)So, take this into consideration for the following.Code 0, Buffer Off on DAC1 (PA4): ~17 mV, considering the 15 kΩ output impedance, and the ~1 MΩ pullup, I could have tolerated 3 times as much: 3 V × 15 kΩ / (1 MΩ + 15 kΩ)Code 0, Buffer On on DAC1 (PA4): ~45 mV, as the DS promisedCode 0, Buffer Off on DAC2 (PA5): ~0.3 mV, as the DS promised (0.5 mV)Code 0, Buffer On on DAC2 (PA5): ~45 mV, as the DS promised (0.2 V)I did also some tries with other codes, 0x800, 0xFFF etc, and had no surprise.Since I was using the no trigger option, there's no need for HAL_DAC_Start(), but of course remember to use __HAL_DAC_ENABLE(hdac, Channel);Moreover, I notcied that if I rewrite the buffer flag (using the debugger), I need to to also refresh the data in the DAC to have a correct output.All in all, the DS does not seem to lie (for once!) and CubeMx generates correct code.

author: peter-h
author_rank: Super Contributor
timestamp: January 17, 2021, 03:24:46 pm
content: Thank you for putting in the time to test that!Yes I can confirm _start is not needed; _enable is sufficient.On the rest, we are still working on it.Basically, it looks like that for basic operation, no output buffer, all 32 config bits are zero, except bit 1 and bit 17. I have hacked that value to 0x00020002 and it still does the same. Even if the pullup was getting enabled, that would not explain the 30-35mV, because it would be much more.

author: peter-h
author_rank: Super Contributor
timestamp: January 17, 2021, 06:28:36 pm
content: This is weird:I changed this from nopull to pullup and it makes no difference on DAC1 (it still goes right down to < 1mVdespite being unbuffered) but it makes a big difference to DAC2, whose 'zero' level goes up from 30mV to 90mV.The 90mV is way too low for what the pullup would do to anunbufferedDAC (1V or so?) so I reckon DAC2 has the bufferenabledand the 90mV is just the increase in Vce(sat) of the bottom output transistor of the buffer, due to the pullup current.

author: newbrain
author_rank: Super Contributor
timestamp: January 18, 2021, 12:53:25 am
content: Quote from: peter-h on January 17, 2021, 06:28:36 pmAs per the RM, using the pull up and pull down in analogue mode is not admissible, so I would not draw any conclusion from this kind of experiments.Use an external resistor to test.Quote

author: peter-h
author_rank: Super Contributor
timestamp: January 19, 2021, 02:56:11 pm
content: I think I found the issue. It's quite subtle.The output of the DAC is fairly high (well I knew that) and it is very sensitive to noise injection. But the effect isn't random or symmetrical. It appears to create a bias. So one has to be very careful how one is connecting a DVM to it!The DAC really needs a buffer, located pretty well right after it, and with the buffer being fed via an RC lowpass filter to get rid of RF muck from the rest of the circuit on the PCB. Of course the internal buffer provided should do this but it doesn't go anywhere near the bottom supply rail. With a TLV2333 or similar it works down to below 1LSB.

author: dmendesf
author_rank: Frequent Contributor
timestamp: January 20, 2021, 11:00:42 am
content: Have you seen this document? I've used the circuit from page 14 to get 400kHz+ from stm32f4 dac.https://www.google.com/url?sa=t&source=web&rct=j&url=https://www.st.com/resource/en/application_note/dm00129215-extending-the-dac-performance-of-stm32-microcontrollers-stmicroelectronics.pdf&ved=2ahUKEwigs9LnrKruAhX5ILkGHdSzD9AQFjAAegQIAxAC&usg=AOvVaw0lvaeGZe0ntgMOW5P-zKnq

author: peter-h
author_rank: Super Contributor
timestamp: January 20, 2021, 03:21:12 pm
content: That's very neat, using a virtual earth to eliminate the lowpass effect of a capacitive load on the output.Also interesting is that they bias the virtual earth at half rail - not what I would have expected for a unipolar DAC.There is a typo in my last post above. I meant the outputimpedanceof the DAC is fairly high, and it is, about 15k. That virtual earth will be susceptible to noise.