STM32 Guide #2: Registers + HAL (Blink example)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
season's greetings everyone welcome back to my second video in the stm32 series when i left off i talked about which development board i recommend getting for starters and i recommended either a nucleo board or the stm32 blue pill now let's see if we can get him to do something the way i'm approaching this series is assuming that you know nothing this video is targeted at either programmers who want to get into microcontrollers for the first time or maybe someone who already has a little bit of arduino background i've put a ton of thought into how i want to cover this do i want to do everything first and explain why later or do i want to explain everything why and wait until the very end to do it and i decided that i'm going to take an approach that falls somewhere in the middle let's take a quick moment to appreciate how clean a blank arduino program looks lucky for you stm32 is just as easy all you have to do is run through this configuration program to figure out how you want to have all your pins timers and peripherals set up and then we can tinker around with a clock configuration to get all that working properly and finally mess around with our tool chain and application structure and after you've gone through those easy steps it leaves you with this nice clean blank looking project okay i get it it's really overwhelming but i promise you all of that stuff is actually your friend you just don't know it yet a lot of those tools and settings are actually there to solve your problems but to fully understand them you might need to know how a microcontroller works at its base level i'm sure you've heard this a million times but computers are made up of ones and zeros now usually we like to group these together into more manageable chunks either 8 bit as a byte or sometimes even 16 or 32 bits a specific type of memory is called ram which is random access memory and this is really just your dumping grounds you can put information in there and recall it later so for example if i wanted to have a variable called mitch and remember that its value is 77 i can just put this into memory somewhere here the microcontroller doesn't care what this value is it's just going to remember it for us until we need it later however not all of the memory is just generic dumping grounds you have a ton of memory to work with for example the blue pill has 64 kilobytes of memory but what's this stuff up at the top that's kind of set aside these are special locations in memory called registers so what would happen if we took the number 51 for example and stored it into this memory address whoa my microcontroller lit up if you have a keen eye you might notice that the number 51 which is zero zero one one zero zero one one is the same pattern of the leds that lit up here if you have an even more keen eye you might have noticed that the pin names are a0 through a7 where we've got a0 on the right and a7 on the left so what we just accidentally discovered is some location in memory that controls the output pins this is sometimes referred to as port a which controls all of the a pins and in stm32 it's referred to as gpioa odr which stands for the output data register so in general what are registers and how do we know where they live in memory registers control everything about how the microcontroller works this ranges from gpio turning pins on and off all the way to timers or pulse width modulation and even communication such as serial or spi all of these registers are documented in the data sheet or rather the reference manual the names of these registers are often abbreviated so they might look a little intimidating or confusing the first time that you see it this is a very small list of some of the registers that are called out in the data sheet by storing specific numbers in these data registers it controls how the microcontroller works before we get any deeper into registers let's do a quick exercise going back to these leds which are hooked up to pins a7 through a0 and we're gonna label them as seven six five four three two one zero what would i have to do to light up just led three we've already come across port a also known as gpioa output data register and we learned that if we stored the value of 51 into that we get this light pattern so to light up just led 3 all we need to know is a binary number with a 1 in the 3's place and 8 translates to 0 zero zero zero one zero zero zero which will light up led three at this point we understand a little bit about one specific register however in order to control gpio pins to their full potential there's quite a long list here now nothing is stopping you from reading the data sheet and i have excellent documentation to describe what each and every one of these do but that's awfully tedious for such a simple task such as turning a pin on or off so it brings up the question do you really need to know what all of these are and the answer to that is no let's look at what a hardware abstraction layer is or hal if you're coming from a background in arduino this line of code should look very familiar to you writing digital write 3 comma high will turn pin 3 on or high even though you may never have heard of hardware abstraction layer before that's what this is now stm gives us a hardware abstraction layer as well however it doesn't quite look as graceful in essence it's doing the same thing they just took a different approach if we break this down the first thing that we need to do is tell the microcontroller what pin we care about for arduino we just say the number three but for stm32 we have to tell it a port and a pin so why can't we just tell stm32 to turn pin 3 on why do we have to specify the port that's entirely because arduino decided to sacrifice performance for code readability the actual microcontroller on the arduino uno is an atmega328p and the pinout for it is right here if we scan through this we won't see pin 3 called out anywhere and that's because arduino made it up don't get that confused with this pin right here which is physical pin 3 it has nothing to do with what the microcontroller logic thinks of it now if we look at the arduino pin out we can see that pin 3 down here actually has pd3 next to it and that means that it's port d pin 3. this just means that any time that you call digital write with an arduino we have to first look up the port and pin before we can actually turn it on or off in simple terms we can just imagine a big table like this where we've got the made up pin number and then each made up pin number such as 13 maps to a port and pin so pin 13 is really port b pin five that just means that any time that we call digital write we first have to look up the port and pin and then we have to set the value if you're interested in learning how to do bare metal programming on an arduino or avr microcontroller i'd encourage you to take a look at my bare metal mcu series of videos the stm32hal actually runs quite a bit faster than arduino's digital right and that's because it doesn't have to spend the time to look up the port and pin because you have to tell it the port and pin to turn it on the last thing that we have to say is whether or not we want the pin to be on or off in arduino we can say high or low or even one or zero and for stm we say gpio underscore pin underscore set or one or if we want to turn it off we could say gpio pin reset or zero now maybe at this point you're saying i really don't like how this works it seems overly complicated or it just doesn't feel right well lucky for you there's tons of other options out there that will hide all of the tedious register manipulation from you we're going to be using st's hardware abstraction layer but a lot of these chips also work with arduino outside of these two i don't have too much experience myself but really you can pick anything that fits your comfort level ranging from something that's very close to bare metal all the way up to an interpreted language like python using micro pi embedded operating systems such as mbed or rtos's real-time operating systems are also pretty popular because they work very similar to how you'd expect a program to run on a desktop computer rather than a microcontroller if you guys are interested you could probably easily convince me to do a series on any one of these other options so overall out of all of the hal stuff that we've talked about the main takeaway is that it saves you from working at the tedious level of register manipulation this allows you to focus on the big picture like why you're turning pins on and off rather than what bit you need to change in which register to get that pin to turn on without affecting anything else there's often a trade-off between writing fast efficient bare metal code and writing code that's easily maintainable or readable so within a project it's pretty common to see hal calls for non-critical parts and then using direct register manipulation when you really need to squeeze out every bit of performance at its heart every microcontroller is just registers how you interact with those registers is entirely up to you and that's one of the reasons why there's so many different options that you can pick from when it comes to developing for an stm32 if you go on st's website you can see this workflow of what it looks like from start to finish of an stm32 project they break it up into three steps the first step is configuration and code generation they release a tool called stm32 which should help out with this rather than reading the entire datasheet to figure out what bits you need to set on which registers this will make it more user-friendly to set those initial configuration registers you can always change this later in your program if you want but this will give you a nice strong starting point the next stage that we have is the actual development environment the purpose for this is to give you all the tools that you need to program something and then eventually compile it into some machine code st's version of a compiler is in the stm32 cube ide you might also notice arduino is up here in the top right now be warned not all of these ides are free based on what this graph is i believe all of the ones that are in this greenish box are free at this point we've taken our code and compiled it into machine code but the last step is to get the machine code from our computer to our micro controller st's program that will take the machine code on your computer and move it to your microcontroller is called the stm32 cube programmer the cube monitor is a debug tool to help you see what's going on in real time and their mcu finder program will help you find the perfect microcontroller based on whatever requirements you have such as peripherals memory clock speed power whatever else you have in mind when i was learning stm32 for the first time all these stages were separate programs cube mx would spit out a program that could be imported into your ide the ides would compile your code into machine code and then the programmer would take that machine code and push it onto the microcontroller however st has been really busy with taking all of these and moving them into one giant development package and that's what i plan on using for the foreseeable future to download this ide we can just search for stm32 cube ide first website here is what we want and then we can click get software to download it in my case i'm on a mac so i'm going to download the mac version of course there's a license agreement so make sure that you read through this and then click accept when ready and then before you can download it you either have to enter your name and email address or login if you have an account after you've downloaded and installed the program we can run it now the first thing that we're prompted for is a workspace and this is really just a folder where it's going to save all of our project info this is the default workspace that it came with when i installed mine but for right now i'm just going to say youtube this will make sure that all of my youtube projects don't get mixed in with my personal stuff and click launch we're greeted with this pretty clean welcome page and you can actually see some remnants of back when these were all three separate programs we're going to want to start a brand new project so we're going to click this the first thing that we need to do is select which micro controller we're using first of all this decides which compiler is going to be used in my previous video i talked about all the differences between the cortex m series and each one of those is compiled slightly differently also the way that each microcontroller works is slightly different different microcontrollers have different registers which control different things so by selecting a specific microcontroller it tells us what hal or firmware we need to use to work with it this also has all the information like flash memory and ram so that way we're not writing a program that won't fit on the microcontroller or maybe we're allocating too much memory and last but not least this will also help with the configuration program which we're about to see next we have two ways that we can go about selecting a microcontroller using these tabs up at the top we can either specify a specific microcontroller or if we're using a pre-built development board by st we can use the board selector the board selector works great for boards that are made by st such as the nuclio but i think the blue pill was made by some third party so it doesn't show up in this list the main thing that the board selector does that the mcu selector does not is that it pre-populates whatever pins are connected to on-board devices or sets up the clock based on however they design the board so for example the nuclio has a blue user button here which is tied to one of the pins on the micro controller if we select this from the board selector it will default that pin hooked up to a button so that way we don't have to configure it ourself but if we selected this from the mcu selector it would just treat it like a blank micro controller and we would have to say which pin is controlling that button i'm going to do a blink example with both the nucleo and blue pill boards but i really suggest that you watch the whole video regardless of what you've got i'm going to start with the blue pill but i suggest that you watch everything because i'm going to cover slightly different things when i go through it once with the blue pill and once with the nucleo since this is not a development board made by st we're going to want to go to the mcu selector and type in the part number of microcontroller which is the f103c8t6 but the t6 doesn't have to be on here because that's just the package this brings up just one option down here so everything looks good and we're going to click on that and then move my face out of the way and hit next at this point really all we have to do is give this a project name so i'm going to call this blue pill underscore blink by default it's going to save it into that workspace that we selected earlier which is the youtube folder the targeted language i'm going to leave this as c this just changes what compiler is being used it might even have some effect on which hell is used the targeted binary type will be executable meaning that we want to run this on our microcontroller if we were to select static library that's something where we would create this project and kind of package it up and then be able to use it in other projects in the future the targeted project type is stm32 cube meaning that everything should mesh well within this ide but to be fair i've never used empty myself before at this point we can click finish but i'm going to go to the next page just to show you what's in here this is where we select what firmware this chip is using if you're curious this is the f1 firmware meaning that it's used for all stm32f1 whatevers the firmware is more or less just a list of all of the registers and where they live in memory i'm happy with everything here so i'm going to click finish now we enter the configuration program the reason i went with the blue pill is because none of the pins are preconfigured for us it's also a lot less overwhelming to see stuff that we don't understand now this configuration program has no idea that we're using the blue pill it just knows that we're using the microcontroller on it if we look very closely there's a user led and it says pc13 on it so port c pin 13 is what will toggle that led and now we want to set pin pc13 right here as an output we can do that by left clicking on it and going down to gpio output now just because you selected it as an output here doesn't mean that you can't change it in the code later this configuration tool is really to take away some of the tedious work of setting up a pin for the first time but you're welcome to ignore it and do everything through code later as a matter of fact by selecting it as an output pin here it will actually generate code that we can look at later in our main program that'll lend some insight as to how to do it on our own if we want to change it later everything on the left side here are some of the other peripheral configurations that you can do such as the analog to digital converters or some of the built-in timers but that stuff is going to have to be saved for a future video the next tab at the top is what probably looks the most intimidating and that's the clock configuration you have a lot of flexibility with how the clock is configured on these microcontrollers if you don't change any of these settings it will use the built-in oscillator on the microcontroller in a future video we'll take this and bump it up to its maximum speed which is 72 megahertz the next tab is the project manager tab since we're staying within the st's ecosystem this doesn't really matter to us this would help the configuration program output something that a different ide could use but since we're doing all of this within st's ide all the default values work for us the last tab is tools which i admittedly have not used yet this allows you to do a lot of simulations or power calculations and from what i've seen it's incredibly powerful but i haven't had the time to look at it myself yet so we'll jump back to the pin out and configuration tab everything looks good so we'll save this and generate the code if we click on this little save icon up here it will save our configuration and then prompt us if we want to generate code because all this configuration tool really does is generate some basic code for us so in that case yes i want to do this now this looks spooky at first because there's quite a bit of stuff going on here and some really complicated calls but i'm going to strip out all of the comments and make this look a little more minimalistic when you hide all the comments the code looks a lot more manageable you can see that we have our main function here and inside of that is an infinite while loop that just means that anything that we execute around this area is just like the setup part of an arduino code and anything within here is like the loop part so if we're to step through this we start out by calling hal init and this just initializes whatever the hardware abstraction layer needs the next part is configuring the clock and this third line is what initializes our gpio pins now the code that this calls is a little bit lower and i haven't stripped out the comments here one cool thing about this ide is if you press control on windows or if you hit the command key on a mac and then click on one of these links it will jump you to that function so when we're calling this gpio init we can actually see what is happening behind the scenes and this is the code that was generated by that previous configuration tool at a very high level this enables the port we turn the pin off or put it into reset mode 0 and then we change the way that the pin works you could do all of this stuff directly with registers or you could be using these hal calls to use the hardware abstraction layer like they're doing here thankfully this code is generated and we can just completely ignore it now unfortunately it's not a good idea to delete all those comments because they're actually quite important so i'm going to add them back in the reason these comments are important is because it allows us to go back to this little tab here at any time and change some of our ping configurations then regenerate code without losing all the stuff that we wrote let's take a look at one of these comments right here we can see user code begin2 and it's followed by user code end to this is their way of saying that we can put anything in between these two comments and it won't get erased there's tons of user code sections everywhere so we can program in between any of them just to give you an idea of what's going on i'm going to create a variable in this user code section called int mitch is cool set that to 102 big number wow and now i'm going to create a variable outside of this user code section called int mitch isn't safe here equals 24. now at this point we have something that's in the user code section and something that's outside of the user code section i'm going to jump back to this configuration tool tab and just pick some random pin i'm just going to set pc14 as a gpio output for no reason and then save it and generate the code now if we look here we see our user code begin and i still have my variable in here but the variable called mitch isn't safe is now gone so make sure that whenever you're writing your code that you do it in between the comments otherwise it's going to disappear if you ever go back and change something in the configuration we don't need this anymore okay so the moment that you've all been waiting for let's turn an led on and off pretty much all of the hal code lives in something called hal underscore at any time you can press control and space and it will bring up an auto complete list of things that you can type in if we want to control the general purpose input output or gpio pins we can type in gpio and we can notice that this list is shrinking down here we have things like read pin toggle pin and right pin and if we double click on any of these such as right pin it will auto complete this line for us these are the three things that we need to specify the port the pin and the pin state on or off if you recall we're using pc13 which is tied to our green led that means that right here we need to specify the port which is called which is port c next is pin 13 however we do not want to type in 13 here and i'll show you why in a sec instead we want to type in gpio underscore pin and control space to auto complete and select pin 13. now using that trick i showed you earlier we can either press control on windows or command on mac and click on this and it will take us to the definition this is where this magic gpio pin 13 is declared and we can see here that it's set to 2000 in hex if we convert this from hex to binary we can see that the binary number is just a 1 followed by 13 zeros this is very similar to that little exercise we did earlier where we set the number eight to turn on led number three i'm not really sure how you do this but sometimes if you like hover over it or click on this number it also shows you where it's being defined as well if any of you guys know how to intentionally make that box show up please let me know in the comments now that we've specified port c and pin 13 the last thing that we have to do is say whether or not we want it to be on or off so we can type in one to turn it on alternatively you could type in gpio underscore pin reset to turn it on i just like to do ones and zeros now let's wait for a second we can do that by typing in hal underscore d and then control space and then find delay or keep typing delay this works the exact same way as arduino where we specify how many milliseconds we want to wait so 1000 is one second now i'm going to copy this code and paste it but this time i'm going to write a 0 to turn the pin off instead of a 1. and then i'm going to fix all of my spacing here so that's it this should toggle pin pc13 on and off so now to program one of these things it's not quite the same as arduino there is a usb port on here but that's not how we're going to program it arduinos come with a built-in boot loader which allows you to program it over usb for the blue pill someone did make a bootloader that lets you upload through the usb port however the only two hardware supported methods that work on every single chip are using the swd pins on the back here or programming it over serial which i believe uses pins a9 and 10. at this point you should also have an st-link v2 programmer this is useful for programming stm32 and also stm8 devices and it has quite a few different pins on the back let's take a closer look at these 10 pins i list them all here and some of them are duplicates for now let's ignore all of the power and ground pins that leaves us with these four pins these four pins are reset swim which is single wire interface module swdio which is serial wire data input output and swclk which is serial wire clock the only time that i ever use the reset and swim pins are when i'm programming an stm8 stm32 seems to always use the serial wire pins which are swdio and swclk this is what the pin out looks like on the back of the blue pill it's a little tough to read so i labeled them here the top and bottom pins are ground and 3.3 volts to power it and the middle pins get mapped to swclk and swdio on the st-link v2 programmer so in short to program an stm32 you just need to power it and then have two data lines let's wire this up i'm going to put the red pin to 3.3 volts for power the black pin to ground and then i'm going to use white for i o and gray for the clock and now we'll match these wires up to the four pins on the back of the blue pill after a little bit of struggling i managed to get them plugged in just be careful because the order of the pins are not the same between the programmer and blue pill at this point we can plug into a usb port on our computer or a usb extension cord like i have here if i go as well there shouldn't be any smoke and you should see a power led that comes on one interesting thing about the f1 series is that it has a boot pin now depending on whether or not that pin is high or low when the microcontroller turns on depends on whether or not it goes into program mode or run mode that would be this jumper here on my right so what we need to do is pick this up and place it into the downward position which sets us into program mode however this is only checked when the microcontroller first turns on so even though i moved it it didn't do anything yet we can either disconnect power and reconnect it or press this reset button here now it doesn't look like anything's happened but we're now in program mode and ready to upload code i personally don't like the boot jumper and there's a way to get around it that i'll show you in a future video now that we have our programmer hooked up to the microcontroller we're able to push code onto it unlike the arduino uno an stm32 you can actually run in either run mode or debug mode debug mode is pretty powerful but we're not going to look at that right now to push our code onto the microcontroller in run mode we just need to click on this green play button right here when we do this it's going to bring up the launch configuration window we don't actually need to change any of this but i do want to run you through it really quick so you know what everything means you can run through this step multiple times and create a different configuration for any type of variant that you want to have while compiling or running your code so because of that we can have a name for this particular configuration ignore the fact that i'm now on blank three because i've had to record this part a few times anytime that you click on this little hammer icon it's going to compile your code and save it into a folder called debug and then the name of your project.elf so this parameter here is just asking what compiled file do you want to push onto the microcontroller so it defaults to the spot where it auto saves the project is just the project that we're working on and these other settings are just how we want to compile our code which will leave everything as default the next tab is the debug tab if you're running in debug mode the microcontroller can actually talk back and forth between your computer it can tell you things like what the current value of a variable is in real time and it also allows you to set breakpoints which will halt your code when you hit a certain line to accomplish this your computer sets up a debug server in the background or gdb server so this first parameter is really saying do we want to create a new debug server or do we want to connect to an existing one i always leave mine as default and auto start one each time that i click play the next few settings mostly have to do with whatever programmer you're using so for example if i was using something other than the st-link v2 maybe like a j-link programmer that's where i would want to select this the next two settings are really all of the nitty-gritty details of how we're going to communicate with the microcontroller we're using the swdio and swclk pins which are the serial wire debugging pins or swd which is why swd is selected by default another option that's a little bit more universal is using something called jtag jtag deserves its own video in the future and as you can see the remaining settings are really just how the swd is going to behave our next tab is startup i've never personally changed anything in here so i'm not going to cover this the source tab is really just a hierarchy of where your code lives this more or less helps the compiler find all of your program files so that way it can compile them correctly the last tab is common and i've never used any of this at this point we can click ok and this will push the code onto the microcontroller and we can watch the output here if you see debugger connection lost shutting down at the end that means that it was successful in order to push the code it creates a debugger pushes the code on and then shuts down the debugger afterwards we can see that our led is not blinking and that's because we're still in program mode and we need to switch back into run mode we can do that by taking this jumper and switching it back to the other direction and once again this pin is only checked when it's turned on for the first time so we either need to disconnect and reconnect power or press the reset button now we have our led which is blinking every second great we did it now let's try it with the nucleo board as a reminder the nuclio has an st link v2 programmer built in that means there's no fancy wiring that we need to do we just have to plug in a usb cable let's set this aside now let's just repeat what we did for the blue pill to create a new project we just need to go to file new stm32 project wait for downloads which happens every once in a while this time we're going to go to the board selector since this is a pre-made board my nucleo board is an f446re so i'm going to select that move my face out of the way hit next and now fill out the project name which is going to be nuclio blink all the default settings are great here this is something new asking us if we want to initialize all the peripherals with their default mode that's only there because this board has some fun stuff built into it like this blue button it's also got a built-in led and i believe it's also got a few other things as well if we say yes this is automatically going to program those pins to do whatever their function is on this board so we're just going to say yes so here's the default configuration which looks a little more complicated than the blue pill because it has a bunch of pins already pre-configured and this is only because the nucleo board has a few things built in already for example we can see that pc13 over here is what's wired up to the blue push button and down here at pa5 we have the green led so at this point there's nothing that we need to change however i do want to show you one cool trick where you can name pins we're going to make the built-in green led blink and if we right-click on pa5 we can click on enter user label at this point we can name this pin and i'll show you how that affects our code later i'm going to call this mitch led then hit enter we now see that this is renamed as mitch led i'm going to click on the save icon and now generate our code here's our generated code which is pretty much the same as the blue pill i'm going to scroll down to our main loop last time we used hal gpio right to write a 1 and a 0 to turn the led on and off there's another function which is pretty cool when it comes to turning something on and off called toggle this will make our code a little bit shorter to use this we type in hal underscore gpio and then control space to auto complete and we'll go to gpio toggle pin this time we just need to specify the port and the pin we don't need to say if we want it on or off because it's just going to flip it to the opposite of whatever it's currently at now here's a question for you do you remember what port the led is on this is why it's really great that you can name pins instead of going back to that page to look up what port it was i can actually type in mitch led and then use control space and here we can see that the first recommendation is mitch led gpio port so i'm just going to double click on that to fill this out now if i hit command on my mac or control on windows and click on this we can see that this actually is gpioa so instead of typing this in i could have said gpioa but now this is a little bit more readable because i know that there is some led called mitch led on this pin the pin works the same way we just have to type in mitch led and then underscore control space and click on pin this is just a way of cleaning up your code to make it more readable it's totally optional last but not least we want to delay and we can do that using hal delay 1000 milliseconds is one second i'm going to click on the hammer to compile our code to make sure that i didn't have any bugs and it looks like we're good to go so we can click on the play button to push the code just like before we don't need to change anything in this configuration so i'm just going to hit ok and there we go it looks like the download verified successfully and then the debugger shut down let's check our microcontroller well lookie here we have a blinking led how neat is that if you ask me this was totally worth a 30 minute video alright everyone i gotta run this video took four days to film so i really hope i did a good job explaining things if anything didn't make sense let me know in the comments and i'll make sure to clarify in the next video see you next time and merry christmas
Info
Channel: Mitch Davis
Views: 186,788
Rating: undefined out of 5
Keywords:
Id: Hffw-m9fuxc
Channel Id: undefined
Length: 30min 1sec (1801 seconds)
Published: Thu Dec 24 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.