Pwm module,How to understand set_duty
i want to use pwm drive steering engine,but I don't understand set_duty how to set value, in c design formulas
Freq = CK_PSC/((PSC+1)*(ARR+1)) Duty = CCR/(ARR+1)
freq = 50Hz
Duty should how to set value
1 PWM cycle contains (ARR+1) ticks. You can take this number with .get_max_duty(). It is 100% of cycle. If you set 50Hz, it match 2ms.
Duty is part of cycle when pin is high.
For example .get_max_duty() gives you 8000.
If you pass .set_duty(4000) you take square wave with 50% duty cycle. .set_duty(2000) => 25%
1PWM cycle contains(ARR+1)ticks. You can take this number with.get_max_duty(). It is 100% of cycle. If you set 50Hz, it match 2ms.Dutyis part of cycle when pin is high. For example.get_max_duty()gives you 8000. If you pass.set_duty(4000)you take square wave with 50% duty cycle..set_duty(2000)=> 25%
thanks very much
let mut pwm = dp
.TIM2
.pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 50.Hz(), &clocks);
let (mut c1) = pwm.split();
let max = c1.get_max_duty();
why max =53333.
then
c1.set_period(50.Hz()); let max = c1.get_max_duty(); max still is 53333
1PWM cycle contains(ARR+1)ticks. You can take this number with.get_max_duty(). It is 100% of cycle. If you set 50Hz, it match 2ms.Dutyis part of cycle when pin is high. For example.get_max_duty()gives you 8000. If you pass.set_duty(4000)you take square wave with 50% duty cycle..set_duty(2000)=> 25%
let mut pwm = dp
.TIM2
.pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz(), &clocks);
let (mut c1) = pwm.split();
let max = c1.get_max_duty();
the max is 8000
pwm_hz automatically select values of PRE and ARR registers to make ARR as much big as possible. So you can't control them.
Instead you could use .pwm::<Tim2NoRemap, _, SAMPLING_FREQ_YOU_NEED>(pins, &mut afio.mapr, 2.ms(), &clocks).
https://docs.rs/stm32f1xx-hal/0.9.0/stm32f1xx_hal/timer/pwm/trait.PwmExt.html#tymethod.pwm
NOTE. Sampling is time of 1 tick (not 1 cycle). For example 1MHz (1_000_000) or 10kHz (10_000)
pwm_hzautomatically select values ofPREandARRregisters to makeARRas much big as possible. So you can't control them.Instead you could use .
pwm::<Tim2NoRemap, _, SAMPLING_FREQ_YOU_NEED>(pins, &mut afio.mapr, 2.ms(), &clocks).https://docs.rs/stm32f1xx-hal/0.9.0/stm32f1xx_hal/timer/pwm/trait.PwmExt.html#tymethod.pwm
NOTE. Sampling is time of 1 tick (not 1 cycle). For example 1MHz (1_000_000) or 10kHz (10_000)
let mut pwm =
dp.TIM2
.pwm::<Tim2NoRemap, _, _, 1_000>(pins, &mut afio.mapr,2.millis() , &clocks);
when after execute above code,programe shutdown. what't the wrong about above code.
i use vscode+cotex-debug(openocd) to debug code,no any error
1_000 is ~ lower limit use 1_000_000 for start. In this case max_duty will be 2000
1_000 is ~ lower limit use 1_000_000 for start. In this case max_duty will be 2000
thanks,programe right
I have still some question: i'm try to drive steering engine steering engine requirement:
- FREQ: 50Hz
- Duty: (0.5- route to -90°, 1 - route to -45°,1.5 - route to 0, 2 - route to 45°,2.5-route to 90°)
in C Project Freq = 72M/((PSC+1)*(ARR+1)) Duty=CCR/(ARR+1)
ARR+1=20ms=20k Freq = 50Hz PSC=720000000-1
so CRR =500,Duty=1.5ms CRR=2500,Duty=2.5ms
let mut pwm =
dp.TIM2
.pwm::<Tim2NoRemap, _, _, 50_000>(pins, &mut afio.mapr,2.millis() , &clocks);
let (mut c1) = pwm.split();
should i how to set this value will generate result to same c code
ARR+1=20ms=20k Freq = 50Hz ~~PSC=720000000-1~~ Your C prject looks broken. You cannot get
ARR+1=20kas you cannot get 10 MHz from 72 MHz on stm32f1 (you need other chip like stm32f411 or other oscillator). Correct values are 9 MHz, 9.6 MHz (and maybe 10285714 Hz). This is what you need for 10 MHz on TIM is set sys clock to 40 Mhz and APB1 to 20 MHz:
let clocks = rcc.cfgr
.use_hse(8.Mhz())
.sysclk(40.Mhz())
.pclk1(20.Mhz()) // bus with clocking for TIM2
.freeze(&mut flash.acr);
.pwm::<Tim2NoRemap, _, _, 10_000_000>This will setPSC+1=20_000_000/10_000_000=2;ARR+1 = 200002a..pwm::<Tim2NoRemap, _, _, 20_000_000>ARR+1 = 40000` - maximum round number you can get
PS. Alternative is:
let clocks = rcc.cfgr
.use_hse(8.Mhz())
.sysclk(72.Mhz())
.pclk1(36.Mhz()) // bus with clocking for TIM2
.freeze(&mut flash.acr);
.pwm::<Tim2NoRemap, _, _, 9_000_000>. Then ARR+1 will be 18000 2a..pwm::<Tim2NoRemap, _, _, 18_000_000>. Then ARR+1 will be 36000
ARR+1=20ms=20k Freq = 50Hz ~PSC=720000000-1~ Your C prject looks broken. You cannot get
ARR+1=20kas you cannot get 10 MHz from 72 MHz on stm32f1 (you need other chip like stm32f411 or other oscillator). Correct values are 9 MHz, 9.6 MHz (and maybe 10285714 Hz). This is what you need for 10 MHz on TIM is set sys clock to 40 Mhz and APB1 to 20 MHz:let clocks = rcc.cfgr .use_hse(8.Mhz()) .sysclk(40.Mhz()) .pclk1(20.Mhz()) // bus with clocking for TIM2 .freeze(&mut flash.acr);
.pwm::<Tim2NoRemap, _, _, 10_000_000>This will setPSC+1=20_000_000/10_000_000=2
thanks, i understand
