Krimskrams: STM32G431 and DAC

What are you developing?
Post Reply
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Krimskrams: STM32G431 and DAC

Post by STM32ardui »

Odds & Ends: various things of different types, usually small and not important, or of little value.
In german language "Krimskrams".


With 128 kB Flash and 32 RAM STM32G431 is not a memory-monster. But it has DACs and more important, I have a board at home. ;) I was curious, if sending signals by DAC can be done with STM32duino.

On an Arduino UNO analogWrite() will generate a PWM-signal or simply LOW/HIGH, if pin has no PWM-capability. Arduino Due, Zero and MKR-boards have a DAC and can generate a real analog signal.

So you can do with a STM32 MCUs:

Code: Select all

//--------------------------------------------------------
// Board: STM32G431CBU6 (WeactStudio "long type")
//
// https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32G4xx/G431C(6-8-B)U_G441CBU/PeripheralPins.c
// https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32G4xx/G431C(6-8-B)U_G441CBU/variant_generic.h
// DAC:  PA4, PA5
// UART1: PA3 (RX), PA2 (TX)  
//--------------------------------------------------------

#define LED_BUILTIN  PC6   // LED is connceted to GND, so it glows with HIGH-level
#define DAC1_1     PA4
#define DAC1_2     PA5

uint16_t x = 0;

void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 digitalWrite(LED_BUILTIN, HIGH);
 Serial.begin(19200);
 delay(2000);
 Serial.printf("\n\n ----- DAC-Test on STM32G431CBU6 ----- \n");

 analogWriteResolution(12);   // set resolution to 12 bits

 pinMode(LED_BUILTIN, OUTPUT);
 digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
 analogWrite(DAC1_1, 2048 + 2047*sin(x));
 x += 0.2;
 if (x > 6.28)		// sin-function takes parameter as radian
  x = 0;
}
As info: Sketch uses 32460 bytes (24%) of program storage space. Maximum is 131072 bytes.
Global variables use 1496 bytes (4%) of dynamic memory, leaving 31272 bytes for
local variables. Maximum is 32768 bytes.


You don’t need to define DAC-pin as output, simply analogWrite() is enough.

Sinus.jpg
Sinus.jpg (49.35 KiB) Viewed 5540 times

But frequency is really low - only 15,8 Hz!
You can find function inside wiring_analog.c

I expected commands for port-manipulations inside, but there are only several checks / function calls, if pin number is inside list, if pin is cofigured correctly and if value is inside range, before a function dac_write_value() is called.

Another try with a sawtooth signal:

Code: Select all

void loop() {
 analogWrite(DAC1_1, x);
 x += 100;
 if (x > 4050)
  x = 0;
}
Sawtooth.jpg
Sawtooth.jpg (49.23 KiB) Viewed 5540 times

Frequency is still low, so it is not the sinus-function slowing down.
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Krimskrams: STM32G431 and DAC

Post by STM32ardui »

I also want to use HAL for DAC. There are internet pages using STM32CubeIDE and it seems to me, that a lot of things are done in the background after user made settings in menus. So examples look unfinished or contain functions, I don’t know.

By searching for dac_write_value() I found https://github.com/stm32duino/Arduino_C ... analog.cpp and add some functions to my sketch.

Code: Select all

//#define HAL_DAC_MODULE_ENABLED   
uint16_t x = 0;
uint16_t e;
DAC_HandleTypeDef     hdac1;
DAC_ChannelConfTypeDef  Channel_Config;

void setup() {
 Serial.begin(19200);
 delay(2000);
 Serial.printf("\n\n ----- DAC-Test on STM32G431CBU6 with HAL ----- \n");

 //Channel_Config.DAC_Trigger = DAC_TRIGGER_NONE;
 hdac1.Instance = DAC1;
 HAL_DAC_MspInit(&hdac1);
 HAL_DAC_Init(&hdac1);
 HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
}

void loop() {
 HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, x);
 //e = HAL_DAC_GetError(&hdac1);
 //if (e != HAL_DAC_ERROR_NONE) Serial.printf("error = %d \n",e);
 x += 100;
 if (x > 4050)
  x = 0;
}
Again info: Sketch uses 18664 bytes (14%) of program storage space. Maximum is 131072 bytes.
Global variables use 1448 bytes (4%) of dynamic memory, leaving 31320 bytes for local variables. Maximum is 32768 bytes.

10% less.

Some remarks:
1. I wasn’t sure, if HAL_DAC_MODULE_ENABLED would be set automaticly or not. Sketch works without it.

2. I read somewhere, that DAC waits for a trigger signal to put signal to output. I commented Channel_Config.DAC_Trigger = DAC_TRIGGER_NONE;   out, because I see it inside HAL_DAC_Init().

3. The line hdac1.Instance = DAC1; is the one, I inserted at last and then I get a signal. I tried it, because inside HAL_DAC_MspInit() are if-conditions to check for „DAC1“. Also dac_write_value() uses it.

4. HAL_DAC_MspInit() is for clock enabling and GPIO setting (from comment). It was my second last adding to sketch.

5. I found HAL_DAC_Init() in analog.cpp - buit it looks, that HAL_DAC_Start() is enough.

So I’m happy that sketch is working, but it is like poking around in the dark. :roll:

Sawtooth(HAL).jpg
Sawtooth(HAL).jpg (50.13 KiB) Viewed 5538 times

As you can see is, that frequency is now much higher - 46 kHz! 46 kHz comparing to 12 Hz with analogWrite(). What you can’t see from picture: frequency is not stable. Signal is moving left and right on oscilloscope.

In sketch you can see an outcommented funktion for checking error code. If this function is active, frequency is going down to 39,9 kHz.


What’s next?
1. If should be possible to set registers directly. I see an example at microcontroller.net - but author told, that GPIO settings were not working for him. My attempt to copy it already fails at clock settings.

2. May be DAC with DMA would allow much faster action and higher frequncies, but I’m not familiar with DMA.
ag123
Posts: 1898
Joined: Thu Dec 19, 2019 5:30 am
Answers: 30

Re: Krimskrams: STM32G431 and DAC

Post by ag123 »

I need to play with this soon, I've not yet tried out the DAC which is a pretty important feature.
The other stuffs on this soc are the op amps and the comparators, which I've yet to play with as well ;)
this chip is practically a lab in a chip, e.g. this with some 'buffers' (e.g. transistors / op amps) can probably plot those transistor characteristic curves e.g. for BJT transistors !
Composite
Posts: 12
Joined: Fri Feb 16, 2024 11:09 pm

Re: Krimskrams: STM32G431 and DAC

Post by Composite »

2. May be DAC with DMA would allow much faster action and higher frequncies, but I’m not familiar with DMA.
I have G474re running 4-DAC configuration with DMA., Arduino IDE. "Typical" dma's throughput on F4-G4-F7 about CPU clock/ 12,
so G474re at 168 MHz updates DAC's at 14 MSPS.
Generate code on Cube MX and copy paste, HAL driver is the same.
User avatar
Bakisha
Posts: 150
Joined: Fri Dec 20, 2019 6:50 pm
Answers: 6
Contact:

Re: Krimskrams: STM32G431 and DAC

Post by Bakisha »

In my experiments with STM32G431 board, output of a DAC is depending on the load. Without load (just probe), it was around 2V/µS, so basicly around 1.5µS to swing from 0V to full 3.3V . When loaded with some cheap speakers with 10K input potentiometer and probably 10µF cap, it needed 50µS to go from 0V to 3.3V.
Tested with sketch:

Code: Select all

void setup() {
  pinMode(PA4, OUTPUT);
  analogWrite(PA4, 0);
}
void loop() {


  DAC1->DHR12R1 = 0;
  delayMicroseconds(50);
  DAC1->DHR12R1 = 4095;
  delayMicroseconds(50);
}

Code: Select all

DHR12R1 
could be replaced with

Code: Select all

DHR8R1
for 8bit resolution.
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: Krimskrams: STM32G431 and DAC

Post by STM32ardui »

Bakisha wrote: Thu Jul 04, 2024 2:22 pm In my experiments with STM32G431 board, output of a DAC is depending on the load. Without load (just probe), it was around 2V/µS, so basicly around 1.5µS to swing from 0V to full 3.3V . When loaded with some cheap speakers with 10K input potentiometer and probably 10µF cap, it needed 50µS to go from 0V to 3.3V.
I only used a probe to connect oscilloscope.
So thanks for this info.
Yes, you already can see in screenshot Sawtooth(HAL).jpg, that from value 4050 to 0 signal is not going down vertically. With a finer timebase (below) I can estimate that time is 1,8 * 2µs = 1,6 µs.


Sawtooth(HAL-2).jpg
Sawtooth(HAL-2).jpg (47.14 KiB) Viewed 5480 times

Your sketch looks similar to what I've seen at Microcontroller.net. There someone also uses analogWrite() in setup() for initialisation (because trouble with GPIO init) and then something like DAC1->DHR12R1 inside loop().
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: Krimskrams: STM32G431 and DAC

Post by STM32ardui »

Composite wrote: Thu Jul 04, 2024 2:51 am I have G474re running 4-DAC configuration with DMA., Arduino IDE. "Typical" dma's throughput on F4-G4-F7 about CPU clock/ 12,
so G474re at 168 MHz updates DAC's at 14 MSPS.
Generate code on Cube MX and copy paste, HAL driver is the same.
Do you like to share your code with us?
ag123
Posts: 1898
Joined: Thu Dec 19, 2019 5:30 am
Answers: 30

Re: Krimskrams: STM32G431 and DAC

Post by ag123 »

my guess is for some light loads it may take an Op Amp as the output 'driver'
https://www.allaboutcircuits.com/video- ... -follower/
I think LMV358 (note not LM358, rather LM(V)358 rail-to-rail) is adequate for that
https://www.ti.com/product/LMV358
lm358 would need a higher voltage headroom to see that it doesn't get clipped at the top.
they are there in the 'online flea markets'
https://www.aliexpress.com/w/wholesale-lmv358.html

I'm not too sure if LM386 could be a better choice
https://www.ti.com/product/LM386
but that this one has gain, and I think there is a head room on top as well. e.g. needs a higher VCC

alternatively, I'd guess even a simple transistor e.g. 2n2222 (or some generic ones) could do
https://en.wikipedia.org/wiki/Common_collector
just that Vout is likely always Vin - Vbe (base emitter voltage, about 0.7v)
Last edited by ag123 on Thu Jul 04, 2024 5:23 pm, edited 2 times in total.
Composite
Posts: 12
Joined: Fri Feb 16, 2024 11:09 pm

Re: Krimskrams: STM32G431 and DAC

Post by Composite »

Attached. Sketch includes serial debug CLI interface, to read-write internal registers.
Attachments
dac_12bits-g474_4dxx.zip
(8.19 KiB) Downloaded 355 times
Post Reply

Return to “Projects”