STM32: waveform generation for beginners? - Page 1
Forum section: electronics / general

author: Watth
author_rank: Frequent Contributor
timestamp: January 12, 2022, 03:31:33 pm
content: Hey everybody,After playing with Arduino, I'm new to STM32, as a hobby. I'm starting with a Nucleo-L412KB and STM32CubeIDE, with witch I could blink an LED (yay!) make it throb with PWM (woohoo!) and command a LED driver with SPI.So far so good.I'd like to generate waveforms to drive a loudspeaker. In practices: beeps of different pitch and shapes for alarms and as an auditory confirmation for the user interface.ST provides anapplication note on the subjectbut doesn't goes into details about practical issues.Also, I'm still a bit lost with ST's IDE's software packages and embedded software, is there anything (library?) in there that would make things easier for such a function?Thanks for reading this message.

author: MarkF
author_rank: Super Contributor
timestamp: January 12, 2022, 04:07:24 pm
content: Here is an introduction to DDS in a PIC32 microcontroller. You should be able to adapt it for your MCU.Plus this:https://people.ece.cornell.edu/land/courses/ece4760/labs/f2021/lab1birdsong/Birdsong_keypad.html

author: wek
author_rank: Frequent Contributor
timestamp: January 13, 2022, 08:51:04 am
content: If you want to stick to Cube, there are examples e.g.https://github.com/STMicroelectronics/STM32CubeL4/tree/master/Projects/STM32L476G-EVAL/Examples/DAC/DAC_SignalsGeneration. This is not CubeMX/CubeIDE-ready and needs to be modified for your particular mcu, but the principle should be the same.Skeleton for something similar should be clickable in CubeMX and then fleshed out, but I don't know, I don't use Cubes.Otherwise, would you chose traditional register-based approach, read the first chapters of RM up to the DMA chapter plus TIM and DAC chapters, while performing experiments, writing simple test programs and experimenting with the registers in debugger.Whatever you chose, I'd recommend with stepwise approach - first learn how to use GPIO, then get DAC working, then TIM, then DMA. Debugger is your friend.JW

author: emece67
author_rank: Frequent Contributor
timestamp: January 13, 2022, 09:43:15 am
content: .

author: peter-h
author_rank: Super Contributor
timestamp: January 13, 2022, 06:57:47 pm
content: That was probably "my" threadIt is quite easy (once you have got it going) to use a timer to trigger a DAC and the DAC is fed with DMA. Zero CPU work after initialisation. The DMA buffer can be circular, and you can do any waveform, limited only by RAM (CCM is not DMA-accessible).

author: Watth
author_rank: Frequent Contributor
timestamp: January 14, 2022, 11:53:20 am
content: Quote from: wek on January 13, 2022, 08:51:04 amYes, I started with basic LED blinking, then PWM it. I played with prescalers' settings to change the output frequency (by putting a piezo LS in parralel with the LED) to change frequency.I haven't yet looked at the debugger, it's still new to me.I miss Arduino's serial monitor and the Serial library. I haven't found yet how on STM32 I can read data from the MCU te same way. In the meantime, tried STM32CubeMonitor and managed to read in real time variable values, it's close enough, but still.Next indeed is tinkering with DAC and DMA.To me, it's a bit hard to find properly summarised guides on these topics . Either these are made for people trained in this type of MCU topics, or to vague and don't explain what's at stake and the internal workings.

author: wek
author_rank: Frequent Contributor
timestamp: January 14, 2022, 12:49:24 pm
content: Quote from: Watth on January 14, 2022, 11:53:20 amIn the realm of 32-bitters this is called "semihosting" and it entails a variety of techniques how to achieve that plain printf() outputs to a window on the host machine (PC). Semihosting is usually something which comes somehow prechewed with an IDE. I am not familiar with these, I don't use IDEs and custom tailor debug-printing to whatever platform I am working at (and I refrain from using the standard printf() and kin because of their inherent bloat, but that's another issue).I see the merits of debug-printing and understand how CubeMonitor is different, but for the basic tests I wouldn't use either - IMO the plain debugger exposing direct access to registers is IMO better.Quote from: Watth on January 14, 2022, 11:53:20 amIt's hard to push knowledge. Try pulling: ask.JW

author: Watth
author_rank: Frequent Contributor
timestamp: January 14, 2022, 01:27:47 pm
content: Quote from: wek on January 14, 2022, 12:49:24 pmWell knowledge pushing exists, that's school. Now as to ask, I don't know how patient people would be, and also at what point I've search enough by myself.

author: wek
author_rank: Frequent Contributor
timestamp: January 14, 2022, 02:05:11 pm
content: Quote from: meQuote from: Watth on January 14, 2022, 01:27:47 pmI know. Teaching is hard, though, and schools too often miss the target. It's because for those, who know, it's hard to understand how does it feel like, not to know. So teaching generally is tossing some material on the pupils in the hope that some of it sticks.It was you who wrote that the available materials don't fit your needs.Quote from: Watth on January 14, 2022, 01:27:47 pmI know. It's the same problem seen from the other side: pupils reasonably but mistakenly expect the material which falls on them to be perfect. So they are usually frightened to ask for more/different, assuming reasonably but mistakenly, that it's them who are at fault when it does not stick.So I've just relegated the problem to you.JWPS. Also, I never promised I will answer...

author: wek
author_rank: Frequent Contributor
timestamp: January 22, 2022, 11:21:10 am
content: Quote from: Watth on January 14, 2022, 11:53:20 amI've just stumbled upon this "article", maybe that will be of some help in this regard.https://community.st.com/s/article/how-to-redirect-the-printf-function-to-a-uart-for-debug-messagesI can't judge its correctness/relevancy, I don't use CubeIDE.JW

author: peter-h
author_rank: Super Contributor
timestamp: January 22, 2022, 03:16:00 pm
content: I recommend the SWV ITM data console output. Much faster than a UART, which just hangs up your target during the output.Not difficult to implementCode:/*** Copied here from core_cm4.h.\brief ITM Send Character\details Transmits a character via the ITM channel 0, and\li Just returns when no debugger is connected that has booked the output.\li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.\param  ch Character to transmit.*/static void ITM_SendChar_2 (uint32_t ch){if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */{while (ITM->PORT.u32 == 0UL){__NOP();}ITM->PORT.u8 = (uint8_t)ch;}return;}// Redirect printf to the SWV ITM / SWD debug interfaceint __io_putchar(int ch) {ITM_SendChar_2(ch);return ch;}However, I find the STLINK V2 or V3 debuggers eventually crash if using this facility

author: Watth
author_rank: Frequent Contributor
timestamp: January 22, 2022, 05:25:30 pm
content: Quote from: peter-h on January 22, 2022, 03:16:00 pmI have yet to figure out how to show variables while debugging.

author: MasterT
author_rank: Frequent Contributor
timestamp: January 22, 2022, 05:31:04 pm
content: If you like arduino IDE, there is official pack from ST. I see STM32L412KB Nucleo L412KB among supported.I also prefer arduino serial for debugging, have a few H7 F7 F4 G4 boards and run them under ST add-on.https://github.com/stm32duino/Arduino_Core_STM32

author: peter-h
author_rank: Super Contributor
timestamp: January 22, 2022, 08:46:57 pm
content: You need to compile the project with F11, not the normal way which is thisThen it will stop at each breakpoint. Then, when it stops, F6 steps through C source lines, F5 stepsintoa function, etc. At each stop, you can see variables in a window (see below).I know watching YT videos is a huge waste of life (most are of poor quality in one way or another, and some of the ST ones are barely intelligible) but it is the best way to learn the Cube IDE basics.I use about 1% of Cube features, and every time I have a look around I find stuff I didn't know about. Also a lot of config is accessible in 10 different ways, and some is almost impossible to find againBut it is free and does work. Also look at thishttps://www.eevblog.com/forum/microcontrollers/is-st-cube-ide-a-piece-of-buggy-crap/msg3901742/#msg3901742

author: MasterT
author_rank: Frequent Contributor
timestamp: January 22, 2022, 10:57:53 pm
content: One reason I like arduino IDE (with STM) - simplicity, two buttons compile & loadBut there is another, arduino has enormous code support - libraries. Let say, if I need TFT LCD in my project - I don't need to spend a month writing C code to integrate specific ILI9686 or whatsever cheap market has on-line available. Just download adafruit GFX and mcufriend library- and all set in 10 minutes.

author: Watth
author_rank: Frequent Contributor
timestamp: January 23, 2022, 12:44:30 pm
content: Yup, I may go back to the 2.0 Arduino IDE, if performances are reasonable.

author: DavidAlfa
author_rank: Super Contributor
timestamp: January 23, 2022, 01:49:23 pm
content: I tested wav/mp3 playback on a STM32F411.First I made a simple WAV player, outputting the signal using filtered PWM, which gave a suprising good sound for 8-bit resolution. The quality drop was as much more noticeable when lowering sample rate.Later, I enhanced it to MP3 decoding, sending the samples to a PCM5102A I2S DAC. The sound was absolutely fantastic, without noises, very crisp.Both use a similar method, using DMA in circular buffer mode.Half transfer/full transfer DMA interrupts makes it work like double buffering, so you all you need is to keep filling the corresponding half with samples from the USB drive.PWM uses a timer to drive the DMA request at the audio the sample frequency. I2S uses its own PLL and drives DMA directly.Wav PWM player ishere.Wav/Mp3 I2S player ishere.But the basic approach is there. Make a buffer with your samples and start the DMA. If the whole wave fits into your buffer, the you don't need any cpu operation, it will keep sending the samples in a loop.

author: Watth
author_rank: Frequent Contributor
timestamp: January 26, 2022, 05:23:06 pm
content: Quote from: peter-h on January 22, 2022, 08:46:57 pmYes, I went on with this.Although I didn't use the navigation functions (F5, F6 and F7) I managed to get what I wanted by1- hovering the mouse over variables displays there values2- using the "Expressions" view in which I typed the variables' names that interest me. So yeah, that somehow gives me what I wanted.I totally agree that videos are a poor format for teaching how to use an IDE. I 'd rather have a written article with screencaps that I can read at my own speed. (note that a video can be helpful/a better media, but that's quite exceptional).

author: rstofer
author_rank: Super Contributor
timestamp: January 26, 2022, 06:58:35 pm
content: Quote from: Watth on January 23, 2022, 12:44:30 pmIf you want SERIOUS horsepower, like 600 MHz power, consider the Teensy 4.1. You wind up installing the Teensyduino toolchain under the Arduino IDE and it includes functions that work identical to the AVR version of Arduino. A lot of work has been done porting libraries and such.https://www.pjrc.com/store/teensy41.htmlhttps://www.pjrc.com/teensy/teensyduino.html