6718 views|12 replies

40

Posts

0

Resources
The OP
 

Problems with adjusting the duty cycle of stm32f203 general timer output PWM wave [Copy link]

 
Question: I use the firmware library to program in stm32f103 to make the TIM3 of the general timer output four PWM waves. I want to use the button to adjust the duty cycle of PWM when the program is executed. My approach is to use an if statement to detect when the button is pressed. If the button is detected, the value of the CCR register increases. I put the if statement and the function of outputting PWM in parallel in the main function, and the original set PWM will be output, but pressing the button will not change the duty cycle; #include "stm32f10x.h" #include "bsp_led.h" #include "bsp_GeneralTim.h" uint16_t CCR1_Val = 999; int main(void) { /* key port configuration*/ LED_GPIO_Config(); /* timer initialization*/ GENERAL_TIM_GPIO_Config(); //Detect button press if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0) { CCR1_Val += 100; //Add 100 to the value of CCR } //Output PWM GENERAL_TIM_Mode_Config(CCR1_Val,CCR2_Val,CCR3_Val,CCR4_Val); } But I put the if statement and the PWM output function into a while (1) loop. No matter how I press the button, the output PWM period is only a dozen microseconds, and the high level time is only a few microseconds less than the period. Why is this??????? #include "stm32f10x.h" #include "bsp_led.h" #include "bsp_GeneralTim.h" uint16_t CCR1_Val = 999; int main(void) { /* key port configuration*/ LED_GPIO_Config(); /* timer initialization*/ GENERAL_TIM_GPIO_Config(); while(1) { //Detect button press if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0) { CCR1_Val += 100; //CCR value plus 100 } //Output PWM GENERAL_TIM_Mode_Config(CCR1_Val,CCR2_Val,CCR3_Val,CCR4_Val); } } The following is the timer sub-function #include "bsp_GeneralTim.h" void GENERAL_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; //Output comparison channel 1 GPIO initialization RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } void GENERAL_TIM_Mode_Config(uint16_t CCR1_Val) { // Turn on the timer clock, that is, the internal clock CK_INT=72M GENERAL_TIM_APBxClock_FUN(RCC_APB1Periph_TIM3,ENABLE); /*--------------------Time base structure initialization-------------------------*/ // Configuration period, here configured as 20ms TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Automatically reload the value of the register, accumulate TIM_Period+1 frequency and generate an update or interrupt TIM_TimeBaseStructure.TIM_Period=19999; // The clock that drives the CNT counter = Fck_int/(psc+1) TIM_TimeBaseStructure.TIM_Prescaler= 71; // Clock division factor, required for configuring dead time TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // Counter counting mode, set to count up TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // Repeat counter value, ignore it if not used TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // Initialize timer TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /*--------------------Output comparison structure initialization-------------------*/ // Duty cycle configuration TIM_OCInitTypeDef TIM_OCInitStructure; // Configure as PWM mode 1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // Output enable TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Output channel level polarity configuration TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // Output compare channel 1 TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // Enable counter TIM_Cmd(GENERAL_TIM, ENABLE); } The following is the key sub-function #include "bsp_led.h" void LED_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOE, &GPIO_InitStructure); }

This post is from stm32/stm8

Latest reply

In the main loop, execute the function that only changes the duty cycle or period, and see if there is such a function in the library. Try not to change other settings.  Details Published on 2018-2-3 14:18
 

3471

Posts

11

Resources
2
 
First, the while (1) loop is necessary. You should have a debounce check when reading the keystrokes. Otherwise, the value of CCR1_Val will change frequently and be unstable.
This post is from stm32/stm8

Comments

Hello, thank you. But I don't use the buttons in the big loop, just output the originally set PWM wave, and it can't be output. I set the cycle to 20ms, but the output cycle is only a few microseconds. Why is this?  Details Published on 2018-1-30 14:01
 
 

40

Posts

0

Resources
3
 
ienglgge posted on 2018-1-30 12:48 First of all, the while (1) loop is necessary. You should have a debounce judgment when reading the key. Otherwise, the value of CCR1_Val will change frequently. Unstable.
Hi, thank you, but I don’t use the key in the big loop, just output the originally set PWM wave, and it can’t be output. I set the period to 20ms, but the output period is only a few microseconds. Why is this?
This post is from stm32/stm8

Comments

The period is 20ms, but the output period is only a few microseconds. Increase the period. See the actual change. Note whether the actual duty cycle is the same as the setting.  Details Published on 2018-1-31 13:52
 
 

4005

Posts

0

Resources
4
 
This post was last edited by huo_hu on 2018-1-30 16:18 There is no need to repeatedly initialize the timer setting like you did. The result cannot be predicted during this period. Just pay the value to the channel register. In addition, your continuous accumulation of CCR1 is problematic. CCR1 overflows and returns to 0 instantly, which is definitely not the result you want. Key jitter will also have an impact. When the channel value is greater than the period, the output is an invalid level, which must also be considered. It is best to enable preloading when the channel is frequently assigned.
This post is from stm32/stm8

Comments

Hello, first of all, thank you. According to what you said, how should I achieve the result I want? How to turn on preloading?  Details Published on 2018-2-1 08:58
 
 
 

11

Posts

1

Resources
5
 
Put your if conditional statement in a while() loop, in which you can detect the key press program
This post is from stm32/stm8

Comments

Thanks  Details Published on 2018-2-1 08:59
 
 
 

3471

Posts

11

Resources
6
 
平淡最真 posted on 2018-1-30 14:01 Hello, thank you. But I don't use the buttons in the big loop, just output the original PWM wave, and it can't be output. I set the cycle to 20ms...
The cycle is 20ms, but the output cycle is only a few microseconds. Increase the cycle. See the actual changes. Pay attention to whether the actual duty cycle is the same as the setting.
This post is from stm32/stm8

Comments

Ok, I'll try it, thanks.  Details Published on 2018-2-1 09:23
Ok, I'll try it, thanks.  Details Published on 2018-2-1 09:00
 
 
 

40

Posts

0

Resources
7
 
huo_hu posted on 2018-1-30 16:15 There is no such thing as repeatedly initializing the timer settings. The results cannot be predicted during this period. Just pay the value to the channel register. ...
Hello, first of all, thank you for following your instructions. How should I achieve the results I want? How do I turn on preloading?
This post is from stm32/stm8
 
 
 

40

Posts

0

Resources
8
 
Tian Jianping posted on 2018-1-30 17:56 Put your if conditional judgment statement into the while() loop, and you can detect the key program in the loop
Thank you
This post is from stm32/stm8
 
 
 

40

Posts

0

Resources
9
 
ienglgge posted on 2018-1-31 13:52 The period is 20ms, but the output period is only a few microseconds. Increase the period. See the actual changes. Note whether the actual duty cycle is the same as the setting.
OK, I'll try it. Thank you
This post is from stm32/stm8
 
 
 

40

Posts

0

Resources
10
 
ienglgge posted on 2018-1-31 13:52 The cycle is 20ms, but the output cycle is only a few microseconds. Increase the cycle. See the actual changes. Pay attention to whether the actual duty cycle is the same as the setting.
Hi, I tried it according to what you said. No matter how I change the cycle, the output PWM cycle in while(1) does not change. It is always the original ten microseconds. I change the duty cycle, but the output duty cycle does not change. It is completely different from the setting. It is not running at all as I set it.
This post is from stm32/stm8

Comments

I don't know how you changed it. Don't judge the key. Just give a dead configuration. Look at different situations and output the results.  Details Published on 2018-2-1 13:37
 
 
 

3471

Posts

11

Resources
11
 
平淡最真 posted on 2018-2-1 09:23 Hi, I tried it as you said. No matter how I change the cycle, the output PWM cycle in while(1) remains unchanged, and is always the original ten microseconds. ...
I don't know how you changed it specifically. Don't judge the key. Just give a dead configuration. Look at the different situations and output the results.
This post is from stm32/stm8

Comments

Give a dead configuration, as long as you don't put the output PWM function in the big loop, everything is normal  Details Published on 2018-2-2 20:28
 
 
 

40

Posts

0

Resources
12
 
ienglgge posted on 2018-2-1 13:37 I don't know how you changed it specifically. Don't judge the key. Just give a dead configuration. Look at different situations and output the results.
Give a dead configuration. As long as you don't put the PWM output function in the big loop, everything is normal
This post is from stm32/stm8

Comments

In the main loop, execute a function that only changes the duty cycle or period. Check the library to see if there is such a function. Try not to change other settings.  Details Published on 2018-2-3 14:18
 
 
 

3471

Posts

11

Resources
13
 
平淡最真 posted on 2018-2-2 20:28 Give a dead configuration, as long as you don't put the PWM output function in the big loop, everything will be normal
In the main loop, execute the function that only changes the duty cycle or period, and see if there is such a function in the library. Try not to change other settings.
This post is from stm32/stm8
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building, Block B, 18 Zhongguancun Street, Haidian District, Beijing 100190, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list