Actually there is a dedicated PWM input mode for advanced timer like TIM1/8, you can find the description in STM reference manual. Its implementation resembles yours, but easier to configure.
@BaronRosenhein4 жыл бұрын
Another great example that demonstrates how to use timers to measure pulse width. In case someone also wants to measure signal frequency you can do so using the formula: frequency (in Hertz) = 1 / period (in seconds) frequency(Hz) = 1 * 1000 * 1000 / 5000(us) = 200 Hetz
@iforce2d4 жыл бұрын
Thanks for the helpful tutorial. If you use uint16_t instead of uint32_t for those variables, you don't need to reset the timer to zero, and you don't need to check if val2 > val1 before doing the subtraction. Not needing to reset the timer is very important, because then you can run one of these PWM inputs on each channel of the timer. If one channel is allowed to reset the timer to zero, you can't really do anything useful with the other 3 channels. uint16_t pwmVal1 = 0; uint16_t pwmVal2 = 0; uint16_t pwmLength = 0; uint8_t whichEdge = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if ( htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3 ) { if ( whichEdge == 0 ) { pwmVal1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_3, TIM_INPUTCHANNELPOLARITY_FALLING); whichEdge = 1; } else { pwmVal2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_3, TIM_INPUTCHANNELPOLARITY_RISING); pwmLength = pwmVal2 - pwmVal1; whichEdge = 0; } } }
@code55414 жыл бұрын
Thx alot for this video! Best way of learning something is by doing it. This gave me a grasp on all the concepts that eluded me when I tried to understand it only through documentation and PDF's.
@fernandomontesfernandez50483 жыл бұрын
Great I was looking forward this video long time ago, I 've seen similaers videos but didn't explain this exactly, good explanation
@fisikamodern5209 Жыл бұрын
why is the prescaler value 72 reduced by 1, and why is the period value also 0xFFFF reduced by 1, is it ok if not reduced by 1
@ControllersTech Жыл бұрын
No it won't work. That's how the registers are designed. If you input the value 0, it will be assumed as 1. That's why we need to set the value 1 less than what we actallu want.
@im5341 Жыл бұрын
10:55 STM Studio error message "Error opening target connection" Does anybody knows how to fix it?
@rikilshah4 жыл бұрын
Commenting to encourage awesome educators like you! Good job!
@XxwkatsxX5 жыл бұрын
What compiler version are you using? the __HAL_TIM_SET_CAPTUREPOLARITY just give me errors, say that the definition of that macro is messed up "../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h:1745:106: error: expected ':' before ')' token" I have the 1.8.0 "STM32CUBE MCU Package for STM32F1 Series"
@XxwkatsxX5 жыл бұрын
The __HAL_TIM_SET_CAPTUREPOLARITY macro calls for another two macros. In order to set a new Capture Polarity, the first one must be erased, so first calls for TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); then for TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); BUT the reset macro had a ')' in a wrong place, so it wouldn't work until I erase it. Originaly: (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP))) :\ just ereasing the extra ')' (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\ I don't know why, I started 3 different projects and It was always the same problem so I fixed it manually
@ControllersTech5 жыл бұрын
I think at the time of making the video, i was using v1.70.
@iforce2d4 жыл бұрын
@@XxwkatsxX thanks man, helped me too :)
@keithsaldanha26174 жыл бұрын
Thanks
@TechBuZZ2016 Жыл бұрын
From which pin are you getting the output of the signal? Like from PA1 you are providing the input. But from which pin you are getting the output?
@ControllersTech Жыл бұрын
I guess you mean which signal is being measured in the video ? I used a NE555 chip which outputs the square wave of variable frequency and width.
@AlifLearn-org5 жыл бұрын
Please can you do the spi connection sd card with stm32 ?? With cubMX and Attolic
@ControllersTech5 жыл бұрын
Yeah it's in my to do list. Will try to make it soon
@davidrosario36423 жыл бұрын
i just love the content of this channel. muchas Gracias
@osdmss3 жыл бұрын
thank you so much. I can't speak English, but it was still a very easy-to-understand video.
@yashchoudhary66053 жыл бұрын
I am dooing same thing on kiel, initialized through stm32cubeMX using timer 3-channel-1, but code showing error on __HAL_TIM_SET_CAPTUREPOLARIT(........);
@ControllersTech3 жыл бұрын
Are u sure about that spelling ?
@liutoelektronika3 жыл бұрын
Do u connected GND to GND and just one signal pin to PB3? Because now i'm capturing 100% of duty cycle because i'm reading just rissing edge, how i can read falling edge?
@ControllersTech3 жыл бұрын
It's mentioned in the code. We change the polarity during the runtime itself and measure the falling edge.
@mehmetcancitak57153 жыл бұрын
how can i measure multiple pwm signals from one timer and different channels? Is it possible?
@ControllersTech3 жыл бұрын
I guess yes. In the interrupt callback, i am checking for the active channel. You just write another if statement and check for another channel. I don't know if there is some restriction about IC selection within the channels. That depends on the timer and your MCU.
@mehmetcancitak57153 жыл бұрын
@@ControllersTech thank you, i will try and than i will write result here
@luisfelipemoncadacalmet74213 жыл бұрын
What did you substract 1 from 72 at the preescaler?
@ControllersTech3 жыл бұрын
It's given in the reference manual and I can't explain the same reason in every video.
@luisfelipemoncadacalmet74213 жыл бұрын
@@ControllersTech Sorry, at least could you tell me what video is it?
@MrTimohus Жыл бұрын
The range of values starts with "0". "0" means: divide by "1" (aka "no division"). So if we enter "72", it will mean: divide by 73. Thus in order to divide by 72 we need to enter "71", aka "72-1".
@曲晉逸4 жыл бұрын
Thank you so much!! This is really very useful!! Helped me a lot!
@manisrinivas_hyd4 жыл бұрын
I have tried and followed same method which you are doing above but it didnot wokring . IM using stm32GX series - generating PWM output with 10Khz output freq , Dutycycle -50% and in another channel doing Input capture with 1us time.
@manisrinivas_hyd4 жыл бұрын
what I found is when im changing dutycycle of pwm, the Difference is not changing for any dutycycle, it is showing same DIfference value for all the dutycycle (Difference = IC_val2- IC_val1). how to figure out this? @Controllers Tech
@ControllersTech4 жыл бұрын
Probably some issue with your timer code. Check properly if you have started the timer or not
@khoatrancongang59813 жыл бұрын
very useful video. That's all i need for my small project. Thank you, and hope you create more video like that
@sindhurenu93564 жыл бұрын
reading one pwm value i have to split 3 outputs any idea pls suggest me
@BaronRosenhein4 жыл бұрын
Not very clear what you're asking. Are you asking how to split one PWM value (timer channel) into three signals? Which doesn't make sense unless your PWM signal is somehow encoded. I suspect you're asking how to read multiple PWM values (timer channels). (I haven't tried but) It should be straight forward by selecting more than one channel to capture the input (each timer offers four channels). Then in your main start capturing like so: HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // TIM2 Channel 1 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); // TIM2 Channel 2 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_3); // TIM2 Channel 3 As each signal goes HIGH microcontroller will set an interrupt. You just need to add appropriate logic inside HAL_TIM_IC_CaptureCallback() function to distinguish between multiple channels and that should be it. Of course, if that doesn't work then you set up three single-channel captures just like this example demonstrate. You have four times at your disposal (assuming that you're using STMF103C8).
@fuyeli91114 жыл бұрын
does this make sense? duty cycle = (IC_Val2 - IC_Val1)/IC_Val2. thanks
@berkcan24393 жыл бұрын
Hi we don't measured period here. We need period to calculate duty. (IC_Val2 - IC_Val1)/ period is duty cycle. duty cycle = ton/T. T = ton + toff if you measure between 2 rising edge then this is period.
@sampoteste5 жыл бұрын
awesome video. thanks for posting. I also use AC6, how do you enable the predictive text in the editor? of are you just using a combination of keys to do that? Thanks
@ControllersTech5 жыл бұрын
Just press Ctrl+Space while typing
@sampoteste5 жыл бұрын
@@ControllersTech thank you
@saurabhjha54014 жыл бұрын
I think u r measuring only ON time period??
@ControllersTech4 жыл бұрын
That is the width of the pulse..
@mhshokuhi99174 жыл бұрын
thank u very much, it helped me a lot
@duckhainguyentran67084 жыл бұрын
can i do the samething on keil?
@ControllersTech4 жыл бұрын
Yes you can
@duckhainguyentran67084 жыл бұрын
@@ControllersTech i did try to copy the code but when i set it on stm studio all the ic value and difference got the same address (0x00) but i dont know why, btw im using stm32f4
@ControllersTech4 жыл бұрын
Did u start the capture in the main function HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
@duckhainguyentran67084 жыл бұрын
@@ControllersTech yes i did
@duckhainguyentran67084 жыл бұрын
@@ControllersTech oh and sorry that i didnt mention earlier but i didn't need the LCD so should i use printf instead?
@thanhnamnguyen88882 жыл бұрын
I want to more channel, can you help me ?
@ControllersTech2 жыл бұрын
You should use 2 different timers for 2 different signals
@thanhnamnguyen88882 жыл бұрын
@@ControllersTech but "void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)" function is only one. now, i am student, i don't know how to use 2 timer for 1 function.
@ControllersTech2 жыл бұрын
You can use the check in the beginning of the callback. If (htim->instance == TIM1)..... If (htim->instance == TIM2)....
@thanhnamnguyen88882 жыл бұрын
@@ControllersTech thank you very much!
@thanhnamnguyen88882 жыл бұрын
@@ControllersTech i will try it. but Timer 3 is not respond. this is code i use: uint32_t IC_Val1=0; uint32_t IC_Val2=0; uint32_t Different2=0; uint8_t Is_First_Captured2=0; uint32_t IC_Val3=0; uint32_t IC_Val4=0; uint32_t Different3=0; uint8_t Is_First_Captured3=0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1) { if(Is_First_Captured2==0) { IC_Val1=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1); Is_First_Captured2=1; __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING); } else if(Is_First_Captured2==1) { IC_Val2=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1); __HAL_TIM_SET_COUNTER(htim,0); if(IC_Val2>IC_Val1) { Different2=IC_Val2-IC_Val1; } Is_First_Captured2=0; __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING); } } } if(htim->Instance==TIM3) { if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1) { if(Is_First_Captured3==0) { IC_Val1=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1); Is_First_Captured3=1; __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING); } else if(Is_First_Captured3==1) { IC_Val2=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1); __HAL_TIM_SET_COUNTER(htim,0); if(IC_Val4>IC_Val3) { Different3=IC_Val4-IC_Val3; } Is_First_Captured3=0; __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING); } } } in the CubeMX, i config timer 3 is the same timer2 mode interrupt : Tim3 global interrup Tim2 global interrup
@javaddehghan87374 жыл бұрын
This is Very Good. Thank You so much
@pusatberk41935 жыл бұрын
thank you so much, please eeprom project
@ControllersTech5 жыл бұрын
What kind of project are u asking ? You can simply use i2c to read and write data to the eeprom