"Not practical examples"!? I'm trying to make heads or tails of how to use the ADC to read data from a microphone and then store enough data to process it with DFT. There are very few accessible, useful tutorials for the STM32 family out there. This is MOST practical for me! Thank you, Shawn! Keep it up!
Hi Christopher, I am also trying to capture microphone recordings for DFT processing. Could you share your GitHub page so that I could replicate your step? Thank you
I'm trying to work out how to control a BLDC motor. I find HEAPS of stuff telling me about the capabilities of the chip - the timers and how they are tailored for what I want to do - but nothing to tell me how to implement these capabilities. We could really do with an online course of tutorials. Shawn Hymel has some excellent ones, but I guess it takes him time to learn enough to present a new tutorial, and time to produce it, so they don't come out very often.
Hi Christopher, hope you read this, I am in the same situation, I need to use the microphone, store data and process it with FFT. I am a bit stuck, could yo share your GitHub? If not, at least I am glad I am not alone in this struggle
chk out Nizar Mohideen's channel too for some practical examples. lots of little bite size applications there to try. May not be exactly what you need but they helped me learn alot
Terrific video. One of the clearest explanations of this challenging topic so far. I really hope you will make a comprehensive series on stm32 because this is simply great! Thank you very much for sharing.
This was a perfect video. I loved the quick-forward thing while listening to your comments. I loved the comments that you wrote in the code, the fact that you explained well every action that you took within the IDE wizard. It was just brilliant! Thank you soooo much.
Huge help, thanks Shawn. Nice early 60s retro motif, I should watch "catch me if you can" again. My problem is reading multiple ADCs (four, so for the STM32F446 means reading three and one in scan mode) performing some arithmatic on the values and pushing them back out through the DAC.
While DMA is a sounding approach for moving data between the ADC and memory, there are cases where writing optimized ARM assembly code could be faster and more performant. For example, if you need to perform data processing operations on the data coming from the ADC before storing it in memory or if you have specific timing or performance requirements that cannot be met using DMA, writing optimized ARM assembly code it could be feasible and simple, something like this that could be further boosted by added some SIMD-like in Cortex-M7 like: ; ARM assembly for copying bytes from source to destination, similar to x86 rep movsb ; Registers: ; r0: source address (ds:si equivalent) ; r1: destination address (es:di equivalent) ; r2: count of bytes to copy (cx equivalent) copy_loop: ldrb r3, [r0], #1 ; Load byte from source address and post-increment strb r3, [r1], #1 ; Store byte to destination address and post-increment subs r2, r2, #1 ; Decrement the count bne copy_loop ; Branch if count is not zero, i.e., continue the loop
This is a super great series. I would love to see a video on how to do this with multiple channels though. As an embedded beginner (well, a beginner at anything beyond an arduino), the thing I struggled with the most was figuring out how to read multiple ADC channels. There are a few ways to do this, like manually starting a conversion, changing channels, then doing it again, or using DMA, however many of the settings you don't have to worry about with single conversion become super important (and difficult to understand) when multiple channels are involved so I'd love to see a tutorial explaining how to do this with many channels (I learned the hard way that the settings need to be quite different for 2-3 channels vs 6-8), and what considerations and settings are involved.
Great tutorial. But the current STM32CubeIde (v1.7.0) puts MX_DMA_Init(); below of MX_ADC_Init(); and that's not working in that order. After any changes in the ioc file, I have to put back the MX_DMA_Init(); line in front of the MX_ADC_Init(); line to keep the AD working. This took some hours to figure out when none of these DMA tutorials worked on my board. Than I find a forum post about this issue... It was a mirracle.
I consider this the best video series to start with STM32 Cube and the presentation is very efficient. A disadvantage of STM32 is documentation (like so many other companies ST suffers from complexity build up along the way). For instance: The channels used in Timers and ADC are linked to some I/O pin. Nowhere I can find the correlation channel - I/O pin except by assigning the channel in Cube and see what I/O pin gets affected. That's not optimum to determine best PCB layout. In DM0038 (about STM32L152), the DMA register set doesn't list the 2nd addressing register for half transfers as claimed elsewhere in the same document. Some examples are even potentially dangerous, since one should start by disabling DMA and test if the enable bit reads zero before starting to modify DMA registers. The documentation also has examples using DMA registers that match the DMA description related to STM32F746, but not the DMA in STM32L152 (that chip has several DMA configurations possible and I fear some mixups happened there). If HAL doesn't support what one needs, such errors in data sheet / reference manual are really killing. According to some documentation, STM32L412KB should be able to measure duty cycle & period or generate PWM signals both DMA based. I measure DC using input capture on both edges by DMA, but didn't find if (a) measuring DC & period on the same pin is possible and (b) how to do that with HAL (even no idea if really possible both by device or HAL)? So I hope Shawn doesn't stop with this series yet but adds more.
Hmm I must have done something wrong on the first attempt. I tried adding the DMA UART communication to the first ADC example directly without making a new project first.. But it looks like I wasn't receiving data on my laptop using cat /dev/ttyACM0 even though the LED is blinking and setting a breakpoint on the callback function also works. The HAL_DMA_Start_IT function returns an OK status. At first I thought it might be due to the difference in chip, because I'm using the Nucleo-F446RE, which has some differences in the DMA setup. But anyway when I just tried to do it again using a clean project, sending data over USART2_TX using DMA worked just fine.. So far the only code difference I've found is a missing at the end of my sample text but I have a hard time imagining that to be the cause. And it's not just a hickup or an anomaly or something because when I switch back, it still doesn't work. Anyway too late now. I'll look at it again later.. Thanks for showing these great examples! I like the pace as well: challenging, no need to skip ahead all the time and with the right amount of detail and explanation of the basics. I'm hoping there's much more STM32 content coming. Perhaps a demo using some DSP instructions could be interesting. And of course I don't suggest that at all because that's what interests me the most ;)
Interesting...I would have thought that all of the CMSIS libraries would have been accessible but perhaps not integrated with the Cube software. DSP stuff isn't on my list of things to show, but good to know there's interest! I'll have to keep that in mind :)
@@ShawnHymel When DMA take control of peripheral BUS then how Microcontroller will communicate with other peripheral ? Which type of other thing it do?? Many articles says that at that time CPU BUS is in tri-state Buffer.... what it mean?? If CPU cant do more task then what is meaning of DMA????
@@radhey04ec if a particular bus is being used by DMA, then the CPU should not be able to access to it. However, the CPU can do other things, like crunch numbers and read/write to and from other peripherals not on that same bus.
@@ShawnHymel Thanks dear for quick reply, Is that mean there are different bus for each peripheral ?? Block flow represents there is common BUS known as APB and all peripheral use same that BUS to push or pull data from CPU. Some How can we check this procedure during debugging time??? Because if program is step by step execution of instructions then if suppose CPU want to use some peripheral which is connected with APB, and DMA already occupied that BUS then which type of process can CPU do???
@@radhey04ec You'll have to look at the datasheet for your particular MCU. The STM32L476RG has two different buses, each with its own set of connected peripherals (APB1 and APB2). I have not explored this yet, but apparently there's a FIFO mode for DMA that will let you queue up bus requests for when the CPU is not using that bus (here is a good discussion on it: stackoverflow.com/questions/24051720/stm32-dmaconcurrent-stream-fifo-burst-mode-double-buffer). As for step-through debugging, it's not really possible (at least, I have not found a way yet). Whenever you pause the CPU with the debugger, DMA will continue running in the background. This makes it really hard to debug when you're trying to see what DMA has put in memory (or has put out on a peripheral).
Great series, Shawn, so this isn't a criticism, but a plea for help. At 3:21, I can't see how you opened a serial monitor. I slowed the video to 0.25 speed, but was unable to see where your mouse went to open the serial console. Then I captured that section of video with OBS Studio, then edited it with Movie Maker so I could single-step the video frame by frame, but I still can't see how you did it. I've tried googling for it and searching the ST website, but I can't figure it out - and so far, I can't open a serial console. Somebody asked 8 months ago, and the answer was that there isn't one. I'm using STM32CubeIDE Version: 1.3.1 Build: 6291_20200406_0752 (UTC) (C) 2019
I was also confused at this point. I wish STM32CUBEIDE had some sort of display console, but i don't think they do. You need to get ST-Link Drivers and PuTTY, or some sort of serial/COM console. Configure them to communicate and they should display the message. For me so far, is it not so easy. This link is helping me get along: stackoverflow.com/questions/52385728/using-putty-to-print-from-stm32. Good Luck!
@@faaizsiddiqui7906 Thanks for that, Faaiz. I'll look into it tomorrow. Because I was making such slow progress, I put it to one side, and haven't been working on it much, but with your comment, I'll have another go and at least try to get through this video. Who knows - I may even complete my project one day.
Hello! Thanks for the series. I have a question. I want to use a DMA in normal mode to store to a buffer, and then switch to use the same DMA in circular mode to fill a second buffer. What's the best way to go about this? i tried changing the "Init.mode" to DMA_CIRCULAR after I've filled the first buffer however that does not seem to switch it to circular mode..
8:09 - Enabling the Interrupt. Why was it disabled to start with? Is that really necessary? What would be "other purposes" usages of USART? 9:29 - This is where the interrupt is disabled. I still don't understand the reason for doing this.
Great videos, thank you! I got UART example working by swapping MX_DMA_Init and MX_USART3_UART_Init. But the ADC one is still not. I think the callback functions in ADC example are not registered correctly.
I'd love to see a tutorial about receiving data to a nuclro board and sending them to an arduino to save them in an sd card. Greetings from Greece, thanks for the help
When DMA take control of peripheral BUS then how Microcontroller will communicate with other peripheral ? Which type of other thing it do?? Many articles says that at that time CPU BUS is in tri-state Buffer.... what it mean?? If CPU cant do more task then what is meaning of DMA????
I have the ADC set to continuous conversion mode, and added a DMA Channel (circular mode) for it, and execute HAL_ADC_Start_DMA (&hadc, pBuffer, Len); however, I don't ever get the ADC_DMAHalfConvCplt or ADC_DMAConvCplt callbacks. What could be the problem? Could it be the ADC 'Conversion Trigger' setting in the ADC Mode and Configuration window?
hey im dealing with the same problem. Did u find a fix? Im on the STM32H743ZI nucleo board. m actually not even getting any values stored in my adc_buf array in the first place. Thanks
Damn! A lot of that went straight over my head! At least now I know what the purpose of a DMA is. But I feel that I have a major lack of understanding of how the basic processes in a MCU work. Like, I don't even know what a callback is or how to effectively make sense of the documentation. Can someone point me to good resources that explain these basic processes to beginners? I mean, not how you do an analog read on an arduino, but stuff like using the DMA-controller. But this video here is almost too detailed for me. While I understand some things, 70% are lost because I don't know the other concepts. I think I need an overview about all these concepts and then I can look at implementations like this. Any advice where I should start?
A Callback function isn't specifically for a microcontroller, but a term used in software in general. A callback function is like any other function that is passed as an argument to other function; that other function is then "call back" that function somewhere in his code. In this video's context, the DMA HAL allows you to pass any function (that you are going to write, and you can write whatever you want in that function) that the DMA HAL will call after the transfer is complete. There are four events to choose from, Shawn choose "Transfer Complete", so your callback function will be called after the transfer is complete. Just google callback function.
I Know it several years after this video but i tested your solution to do the msg dma (Memory to UART) with an NucleoL053R8 and it compile well and debug well but i receive nothing in the com port on my computer and the led is not blinking. I don't know where the problem is. The code is running and the HAL_DMA_START_IT func get no problem but it seems that the HAL_DMA_RegisterCallBack function is not used, I don't really know when exactly this function is supposed to be call because it is not in the while loop. Is copying the msg to TDR register is the only thing to do for send a message in uart ? Is anyone read this message a little help will be very appreciate. Thank you for the video btw
Hi, I was also having this problem. I had to make two changes to get it running: Change the destination register to huart2.Instance->DR (instead of TDR) Move the auto generated MX_DMA_Init(); above the MX_USART2_UART_Init(); so that the DMA initializes first. Hope this helps!
@@billblakely9092 Hi! It'm seems that move the auto generated MX_DMA_Init() is working. TDR is the right Register, I just move the DMA Init and it's working well. Thanks!
when I set the potentiometer in the middle and measure the voltage, I get the 1,6v. After I connect the ADC the voltage drops to 0,1V. Do you know what the problem might be?
@@babotvoj maybe your "original" ADC pin is internally damaged, or has some other stuff hooked on the same physical pin. I may be wrong, but I know that the voltage drops only if something drains more current than the source can give.
A question not related to the video. I want to add an TFT-Display library, but when I include it on main.c it doesn't find the directory... Can someone help me ?
It actually worked when I declared the full path #include "C:\mBed Development\429I-TFT-Display\Drivers\BSP\STM32F429I-Discovery\stm32f429i_discovery_lcd.h" But that way will only work if it's compiled from that specific folder, and I don't want that...
Hello! If you’d like you could try posting this question on our TechForum. We have a team of technicians and engineers that monitor that page and I’m confident one of them can help you find the answer.
nice video but it's somehow accelerated and you need to stop it hundreds of times to get the details. Strongly suggest that you can slow down a bit and allow students to have time to absorb and understand the subject. For someone new to the cubeMX environment it's necessary to slow down the pace.
@@marshallstone731 yes use putty, under the UART config, you can read the baud rate and settings, put the same on putty, and in device manager find the COM port that st-link is working on
Hi., I have completed demo, how to print the registry values stored in dma to uart port. I want 50kSPS from 6 ports, any coding help or guidance??? SHukesh BTech FInal Year ., In need of help to complete final year project. Thanks in advance.