Best videos that I found until now for CMSIS programming😊😊😊👍👍👍 Very clear speaking and good explanations. You must know very much about microcontrollers.
The guide is very clear and detailed. I have got and timing error in my STM32F746ZG. When I have checked the blinking rate with the oscilloscope I observed around 1.8 second delay instead of 1 second. This was due to the reset values of the RCC's PLLCFGR register. I have added a line of code for resetting the PLLCFGR register with 0's before setting the parameters and I finally got the 1 second delay. My take from this issue is that the reset values of the registers need to be considered when we are not resetting every register manually before setting them.
@@serpico3w767 RCC peripheral’s PLLCFGR register which can be found in the Reference Manual of the related MCU was not 0x0000 0000. Its was something like 0x0000 0101. I have observed this in step by step debugging of the code with the STM32CubeIDE and also checked the default reset value of the register wirth the reference manual. So if you do not set the register to all zeros before setting the bits with OR statement you might get different value than you wanted to set. So I needed to clear the register before setting the bits.
Thanks for all the STM32 projects you have made to date as they have been very educational. Please keep the no HAL projects coming! How about converting the SSD1306 project to no HAL?
You are a very good programmer. I had to smile when you said you'd rather shift 16 bits left instead of shifting 21 bits left. But you are correct you saved the time it takes to shift 5 bits. Do you prefer using register programming or using ST's HAL API ? One last question .. will you be advancing to robotic applications in the videos at some point ?
I prefer registers but things gets very complicated specially with arm Cortex series. HAL is easier approach but not so much optimised I might include more robotic stuff but not now. I still have more basic things to cover right now..
Thanks for your video, i have to make a project were i need the timer works in nanoseconds. Using every 72mhz of bluepill, with no prescale, i should have a precision of 13.8nanoseconds, what do you think? I am scared about Crystal 8mhz because I don't know if it is a bottleneck. I will use a photodiode that is very fast (5nanoseconds) to send value to stm32. Thanks again and keep up the good work!
Thanks for your helpful videos. I just have one concern. which is to set The UG bit in TIMx_EGR registers to update the registers. otherwise, the update will not going to happen until an overflow or underflow occurs. which could take a very long time if using the 32-bit register, and this is what exactly happened with me until I noticed that in the datasheet.
hello, I am trying to do a similar program for 3 different LEDs using 3 different timers, I am using 2 16 bit timers and one 32 bit timer, the program works fine for the 16 bit timers with both LEDs blinking at different periods, but my other led which is using the 32bit timer does not blink it stays on for a long while and turns off. Could you explain the EGR register in more detail because I think this is the part I am missing in my code, thanks
@@ControllersTech If you set the prescaler and ARR such that the ARR period is the delay you want, and configure the timer’s UIF interrupt, then the interrupt handler will fire at the end of the desired delay. For longer delays, compute the multiple of the ARR period, then decrement in the interrupt handler; when it gets to 0, your time is up. For example, make the ARR period be 1ms; then you can easily do Delay_ms() without blocking. I think there may be another counter that changes on every ARR period (on advanced timers only?); if so, that would be an alternative to a software counter.
Yeah i know about that but can we call it delay ? It is more of a period update, suited for some periodic function. Maybe be good for blinking LED but certainly can not be used for delay purpose
9:44 there I've a question: when we only write "1" with the "or" operator to the register or also without the "or" then the same result should be come out in my head. Because when we write a "1" and not 0b1: is that not the same? Because in 0b1 the zeros that are before the one are thinked before, but we don't need to write it. Is that also true when we write "1" as integer / decimal number in the register?
I’m curious why TIM6Config waits for UIF to be set? That’s going to end up waiting for 65536 microseconds (when the timer’s counter reaches the ARR value and is reloaded). AFAICT, you don’t need to wait after configuring timers (like you do with the oscillators and PLLs).
Yeah even i am not sure about that. I tried simple way and it wasn't running.. after i almost gave up on it, i went through the hal initialisation and there i saw that they were looking for this bit to update. I still don't know why though.. but it works with it. I will dig deep when i have some free time for this
@@ControllersTech The problem is actually that the prescaler only starts working after the next update event. It is written in the datasheet: "The new prescaler ratio is taken into account at the next update event." So basically after you start the timer the prescaler won't work because no update event happens until it reaches the ARR value. If you wait for the UIF flag to set (like in the video) that means you wait for the counter to count until it reaches 0xffff, with lower clock speeds and higher ARR values it can take a really long time (even minutes) for your program to move forward because it is stuck in the while loop. After you enable the timer you can generate an event by software with setting the first bit of the Event Generation Register (TIMx_EGR: Update generation) and then your prescaler will work. To summerize: if you change that while loop to: TIM6 -> EGR |= 1, you don't have to wait for a UIF event, your program can instantly proceed and your timer will work corretly. I hope i was clear. Thanks for your videos they help me a lot. :)
Hi...I am using stm32f407 discovery board. @168mhz. I have done everything right but my LED blinking delay is about 5 seconds, where as it should be 1 second.
@@ControllersTech Thanks for the quick reply. After some investigation, it turns out that the Nucleo board that I have has a 25 MHz external clock as you described. Thanks so much for your help and videos!
hello sir ! i have a question ? on this video, you dont use Hal library, configuraions,.. of stm32cubemx . So Can you send me the reference document related to the configuration sequence of registers ? tks you very much
@@ControllersTech that is really true I think now. 😅 When I do OR with a zero and a 1 is in that bit -> the one doesn't change. When I use AND with a zero and a 1 is in that bit -> the result won't become true, so a 0 is written in the register bit. 😊 But why we invert a 1 to a zero with the tilde? And don't use directly a zero?
Hello sir how I reset the timer value to zero after stop when reaching a desired value . When I stop the timer at a certain value then again start the timer ,the timer start from previous value not from zero what to do.
CNT register holds the current counter value. ARR register hold the maximum counter value allowed. Thee CNT value is compared with the capture compare register (CCR), and relevant operation is performed.
what's the difference between uVision and CubeIDE ? Can I use cubeIDE to execute this same exact code with the same result ? (I apologize for this silly question, just a noobie in Embedded Software)
@@hjvanderlinden So basically both cube and keil can do the same job (with slight differences) ? In other words , they are two "equivalent" alternatives for ST like, for example, eclipse and NetBeans are two IDEs for Java?
@@mprone STM32CubeIDE is free. In fact you can, program stm32 or any Arm on you fav IDE if you know how to write linker script (.ld file), startup script (.s file) and makefile (using cross compiler to compile your code). I heard you can develop arm projects on vscode using PlatformIO but my friend said he couldn't upload code to microcontroller while using that extension. I haven't tried it yet.
14:27 but Stop! When the timer runs at 1 MHz I learned wie can't count longer then 65,535 ms? How we count then so long? Or I have a brain failure maybe?
We are not directly counting here. Check 08:28, there is another function. Also it's not 65535 ms, it's 65535 counts. There is a difference between both. If each count takes 1us, then max counts will be 65535 us. If each count takes 1ms, the it will be 65535ms. The counter resets after reaching this value.
@@ControllersTech oh, misunderstanding of my format. I mean with the comma really a comma. Then I must write so: 65.535 ms is the max counting value with 1 MHz. But I understand it yesterday after a little bit time goes over after the video. How you realize the ms delay, we don't need to count over 1ms. Because we use a delay from the other function for that....🙂
Nice tutorial. I watch ur entire vdo and write same program for my STM32F401RE. Here u have used timer6 and bus having 90 Mhz frequency for timer peripherals. In my case, I'm using timer3 and bus having 84 Mhz for timer peripherals. I set all register according to ur vdo and code is also working properly. But time delay is not exact. In your vdo, when u pass millisecond, seconds value it produces exact delay. In my case it takes 7 second OFF and 6 second ON when i pass 1000 in delay_ms() function. And it is not exact for micro-second as well. What could be problem ? I watched ur vdo many times but not able to point out, whats going on with my code. Plz give some suggestion about it. Your any answer will be appreciable.
@@ControllersTech Thank you for ur fast reply. Yes I did same as u explain in both vdo's. As a beginner i type each word one by one and for cross check i also download the code provided by u from ur website. After selecting max frequency i.e 84 Mhz for my 401RE board in CubeMX I noticed these values, if wrong correct me. PLL_M - 4 PLL_N - 84 PLL_P - 0 // PLL_P 2 SYSCLK - 84 Mhz AHB PRESCALAR - 1 HCLK - 84 Mhz APB1 PRRSCALAR - 2 APB1 Timer clock frequency is 84Mhz. I'm using Timer 3 for my delay code. These are the values I have set in my code according to ur instructions. Code is running but delay is not perfect. Plz, i request u to choose 401RE Board in your CubeMX and tell me where I'm going wrong.
@@karthikps3892 He was right. He used APB1 prescaler = 4. HCLK was 180Mhz => PCLK1 = APB1 peripheral clocks = 180/4 = 45Mhz while APB1 Timer clocks = (180/4) * 2 = 45 * 2 = 90Mhz. You should revisit 3:17. TIM6->PSC scales the APB1 Timer clocks, which is 90Mhz, not APB1 peripheral clocks (which is 45Mhz).
Best videos that I found until now for CMSIS programming😊😊😊👍👍👍
Very clear speaking and good explanations. You must know very much about microcontrollers.
❤️ from Turkey
The guide is very clear and detailed. I have got and timing error in my STM32F746ZG. When I have checked the blinking rate with the oscilloscope I observed around 1.8 second delay instead of 1 second. This was due to the reset values of the RCC's PLLCFGR register. I have added a line of code for resetting the PLLCFGR register with 0's before setting the parameters and I finally got the 1 second delay. My take from this issue is that the reset values of the registers need to be considered when we are not resetting every register manually before setting them.
Can you please elaborate
@@serpico3w767 RCC peripheral’s PLLCFGR register which can be found in the Reference Manual of the related MCU was not 0x0000 0000. Its was something like 0x0000 0101. I have observed this in step by step debugging of the code with the STM32CubeIDE and also checked the default reset value of the register wirth the reference manual. So if you do not set the register to all zeros before setting the bits with OR statement you might get different value than you wanted to set. So I needed to clear the register before setting the bits.
Thanks for all the STM32 projects you have made to date as they have been very educational. Please keep the no HAL projects coming! How about converting the SSD1306 project to no HAL?
yeah i intend to make more videos on NO HAL.. I will first cover the basic peripherals, and then move to the modules.
@@ControllersTech Thanks , waiting.
No words, just great video, thank you
Thanks for this video. Can you make a video about timer at mode interrupt? I'm investigate about it, but I can't implement it yet!😢
You are a very good programmer. I had to smile when you said you'd rather shift 16 bits left instead of shifting 21 bits left. But you are correct you saved the time it takes to shift 5 bits. Do you prefer using register programming or using ST's HAL API ? One last question .. will you be advancing to robotic applications in the videos at some point ?
I prefer registers but things gets very complicated specially with arm Cortex series. HAL is easier approach but not so much optimised
I might include more robotic stuff but not now. I still have more basic things to cover right now..
Thanks sir , keep teaching ....
Thanks for your video, i have to make a project were i need the timer works in nanoseconds. Using every 72mhz of bluepill, with no prescale, i should have a precision of 13.8nanoseconds, what do you think? I am scared about Crystal 8mhz because I don't know if it is a bottleneck. I will use a photodiode that is very fast (5nanoseconds) to send value to stm32. Thanks again and keep up the good work!
hello sir...kindly make a video for systick timer in STM32 !!!!
Great explain like programming.
How do you know that you need to check bit UIF in TIM6->SR register?
thanks very much for your turial
This clock configuration doesn't work properly with STM32 CubeIDE. Any suggestions regarding CubeIDE to do CMSIS based programming without using HAL?
Sir you have any idea about mm32f0020 timers , bcz I don't get any source to refer this controller
Thanks for your helpful videos. I just have one concern. which is to set The UG bit in TIMx_EGR registers to update the registers. otherwise, the update will not going to happen until an overflow or underflow occurs. which could take a very long time if using the 32-bit register, and this is what exactly happened with me until I noticed that in the datasheet.
This tutorial worked for me, so can you please explain a bit(lol) more?
hello, I am trying to do a similar program for 3 different LEDs using 3 different timers, I am using 2 16 bit timers and one 32 bit timer, the program works fine for the 16 bit timers with both LEDs blinking at different periods, but my other led which is using the 32bit timer does not blink it stays on for a long while and turns off. Could you explain the EGR register in more detail because I think this is the part I am missing in my code, thanks
@@justsomegamer4086 sorry just noticed your comment. Do you still need help?
@@seifelkhouly9090 figured it out boss, thanks
Hello,Very good video.
Could you please make a video of NO HAL timer delay based on interrupts?
Thanks
how will delay with interrupt work ?
@@ControllersTech If you set the prescaler and ARR such that the ARR period is the delay you want, and configure the timer’s UIF interrupt, then the interrupt handler will fire at the end of the desired delay. For longer delays, compute the multiple of the ARR period, then decrement in the interrupt handler; when it gets to 0, your time is up. For example, make the ARR period be 1ms; then you can easily do Delay_ms() without blocking. I think there may be another counter that changes on every ARR period (on advanced timers only?); if so, that would be an alternative to a software counter.
Yeah i know about that but can we call it delay ? It is more of a period update, suited for some periodic function.
Maybe be good for blinking LED but certainly can not be used for delay purpose
9:44 there I've a question: when we only write "1" with the "or" operator to the register or also without the "or" then the same result should be come out in my head. Because when we write a "1" and not 0b1: is that not the same? Because in 0b1 the zeros that are before the one are thinked before, but we don't need to write it. Is that also true when we write "1" as integer / decimal number in the register?
OR operator is for addition.
how to make the output will be on for 10 minutes?
Turn the LED on and give the delay of 10 min 🤷
I’m curious why TIM6Config waits for UIF to be set? That’s going to end up waiting for 65536 microseconds (when the timer’s counter reaches the ARR value and is reloaded). AFAICT, you don’t need to wait after configuring timers (like you do with the oscillators and PLLs).
Yeah even i am not sure about that. I tried simple way and it wasn't running.. after i almost gave up on it, i went through the hal initialisation and there i saw that they were looking for this bit to update.
I still don't know why though.. but it works with it.
I will dig deep when i have some free time for this
@@ControllersTech The problem is actually that the prescaler only starts working after the next update event. It is written in the datasheet: "The new prescaler ratio is taken into account at the next update event." So basically after you start the timer the prescaler won't work because no update event happens until it reaches the ARR value. If you wait for the UIF flag to set (like in the video) that means you wait for the counter to count until it reaches 0xffff, with lower clock speeds and higher ARR values it can take a really long time (even minutes) for your program to move forward because it is stuck in the while loop. After you enable the timer you can generate an event by software with setting the first bit of the Event Generation Register (TIMx_EGR: Update generation) and then your prescaler will work. To summerize: if you change that while loop to: TIM6 -> EGR |= 1, you don't have to wait for a UIF event, your program can instantly proceed and your timer will work corretly. I hope i was clear. Thanks for your videos they help me a lot. :)
more NO HAL FTW.
Very good
Hi...I am using stm32f407 discovery board. @168mhz. I have done everything right but my LED blinking delay is about 5 seconds, where as it should be 1 second.
I need to see the code.. contact me on discord
What was the fix to this? I am having the same problem and would appreciate any guidance. I am using stm32f767zi.
I don't remember exactly but i guess it could be due to because he was keeping the input clock at 25MHz, though his board had the 8 MHz input crystal.
@@ControllersTech Thanks for the quick reply. After some investigation, it turns out that the Nucleo board that I have has a 25 MHz external clock as you described. Thanks so much for your help and videos!
hello sir ! i have a question ? on this video, you dont use Hal library, configuraions,.. of stm32cubemx . So Can you send me the reference document related to the configuration sequence of registers ? tks you very much
The reference document is the reference manual of your controller. Watch the video properly as i have explained each and every step for configuration
11:32 why we don't simply shift a "0" 5 Bits to left with "or" operator?
You clearly don't know how bitwise operations work. Please read the topic.
OR is used for addition. Adding 0 does not has any effect on the bit.
@@ControllersTech that is really true I think now. 😅
When I do OR with a zero and a 1 is in that bit -> the one doesn't change.
When I use AND with a zero and a 1 is in that bit -> the result won't become true, so a 0 is written in the register bit. 😊
But why we invert a 1 to a zero with the tilde? And don't use directly a zero?
Hello sir how I reset the timer value to zero after stop when reaching a desired value . When I stop the timer at a certain value then again start the timer ,the timer start from previous value not from zero what to do.
Tim->cnt = 0
Nice project!!!
Have you ever thought about taking a course at Udemy?
Beginner to advanced in barel metal course
@@ControllersTech
I was telling you to create a course, you have a lot of knowledge and you are a great teacher
Ok I'll take the compliment and delete my comment. UA-cam is fine.. maybe in the future I'll think about it.
You use an 8 MHz external crystal but the external crystal position is empty?
It's there on the top. Shared between st link and the mcu
Can i give counter value directly in arr register . for examble tim2->ARR =1000;
CNT register holds the current counter value.
ARR register hold the maximum counter value allowed.
Thee CNT value is compared with the capture compare register (CCR), and relevant operation is performed.
what's the difference between uVision and CubeIDE ? Can I use cubeIDE to execute this same exact code with the same result ?
(I apologize for this silly question, just a noobie in Embedded Software)
@@hjvanderlinden So basically both cube and keil can do the same job (with slight differences) ? In other words , they are two "equivalent" alternatives for ST like, for example, eclipse and NetBeans are two IDEs for Java?
@@mprone STM32CubeIDE is free. In fact you can, program stm32 or any Arm on you fav IDE if you know how to write linker script (.ld file), startup script (.s file) and makefile (using cross compiler to compile your code). I heard you can develop arm projects on vscode using PlatformIO but my friend said he couldn't upload code to microcontroller while using that extension. I haven't tried it yet.
14:27 but Stop! When the timer runs at 1 MHz I learned wie can't count longer then 65,535 ms? How we count then so long? Or I have a brain failure maybe?
We are not directly counting here. Check 08:28, there is another function.
Also it's not 65535 ms, it's 65535 counts. There is a difference between both. If each count takes 1us, then max counts will be 65535 us. If each count takes 1ms, the it will be 65535ms.
The counter resets after reaching this value.
@@ControllersTech oh, misunderstanding of my format. I mean with the comma really a comma. Then I must write so: 65.535 ms is the max counting value with 1 MHz.
But I understand it yesterday after a little bit time goes over after the video. How you realize the ms delay, we don't need to count over 1ms. Because we use a delay from the other function for that....🙂
Nice tutorial.
I watch ur entire vdo and write same program for my STM32F401RE.
Here u have used timer6 and bus having 90 Mhz frequency for timer peripherals.
In my case, I'm using timer3 and bus having 84 Mhz for timer peripherals.
I set all register according to ur vdo and code is also working properly. But time delay is not exact.
In your vdo, when u pass millisecond, seconds value it produces exact delay.
In my case it takes 7 second OFF and 6 second ON when i pass 1000 in delay_ms() function.
And it is not exact for micro-second as well.
What could be problem ? I watched ur vdo many times but not able to point out, whats going on with my code.
Plz give some suggestion about it.
Your any answer will be appreciable.
Did you saw the first video and did the setup accordingly. The 84 MHz clock is only valid if you have set it up for 84 MHz.
@@ControllersTech Thank you for ur fast reply.
Yes I did same as u explain in both vdo's. As a beginner i type each word one by one and for cross check i also download the code provided by u from ur website.
After selecting max frequency i.e 84 Mhz for my 401RE board in CubeMX I noticed these values, if wrong correct me.
PLL_M - 4
PLL_N - 84
PLL_P - 0 // PLL_P 2
SYSCLK - 84 Mhz
AHB PRESCALAR - 1
HCLK - 84 Mhz
APB1 PRRSCALAR - 2
APB1 Timer clock frequency is 84Mhz.
I'm using Timer 3 for my delay code.
These are the values I have set in my code according to ur instructions.
Code is running but delay is not perfect.
Plz, i request u to choose 401RE Board in your CubeMX and tell me where I'm going wrong.
Mail me or use telegram to send the code
There is trick, set the same frequency value for the timer prescale, and you will get 1Mhz(1us) as output.
i cant set the clock frequency in target option . its shows undefined on that position. here im also using mdk v5. please give the solution sir....
Try without setting that.. i guess it works alright
@@ControllersTech ok sir
You have done a mistake bro...check the APB1, it is 45Mhz and you are selected 90 for pre scaling. 45 is correct for pre scaling.
Apb1 timer clock..
@@ControllersTech TIM6 ->PSC = 45-1; ... this is correct
Not APB1 peripheral clock.. look at APB1 timer clock.. they are different
@@karthikps3892 He was right. He used APB1 prescaler = 4. HCLK was 180Mhz => PCLK1 = APB1 peripheral clocks = 180/4 = 45Mhz while APB1 Timer clocks = (180/4) * 2 = 45 * 2 = 90Mhz. You should revisit 3:17. TIM6->PSC scales the APB1 Timer clocks, which is 90Mhz, not APB1 peripheral clocks (which is 45Mhz).
i cant set the clock frequency in target option . its shows undefined on that position. here im also using mdk v5. please give the solution sir....
Don't set it then. Try without that