aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-06 21:33:17 +0000
committerGitHub <[email protected]>2023-04-06 21:33:17 +0000
commitda8258b7673a52a4639818f9c3f3b7ea241b4799 (patch)
tree074787c16ce64c2f6033a4d79487ad8c0321a210 /examples
parent60809edf2ce8f3cb91d31398dc347e4193e2e5f2 (diff)
parent31ef783ac1add908c4c4506d3ce4e5f6ad9bea56 (diff)
Merge #1330
1330: stm32/pwm: add complementary pwm r=Dirbaio a=xoviat This implements complementary PWM with dead time on many supported targets. The specific dead-time programming functions are passed through directly to the user, which is a bit ugly but the best compromise I could reach for now. Co-authored-by: xoviat <[email protected]>
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32f4/src/bin/pwm_complementary.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/examples/stm32f4/src/bin/pwm_complementary.rs b/examples/stm32f4/src/bin/pwm_complementary.rs
new file mode 100644
index 000000000..6e17f3fd3
--- /dev/null
+++ b/examples/stm32f4/src/bin/pwm_complementary.rs
@@ -0,0 +1,77 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::pwm::complementary_pwm::{Ckd, ComplementaryPwm, ComplementaryPwmPin};
8use embassy_stm32::pwm::simple_pwm::PwmPin;
9use embassy_stm32::pwm::Channel;
10use embassy_stm32::time::khz;
11use embassy_time::{Duration, Timer};
12use {defmt_rtt as _, panic_probe as _};
13
14#[embassy_executor::main]
15async fn main(_spawner: Spawner) {
16 let p = embassy_stm32::init(Default::default());
17 info!("Hello World!");
18
19 let ch1 = PwmPin::new_ch1(p.PE9);
20 let ch1n = ComplementaryPwmPin::new_ch1(p.PA7);
21 let mut pwm = ComplementaryPwm::new(
22 p.TIM1,
23 Some(ch1),
24 Some(ch1n),
25 None,
26 None,
27 None,
28 None,
29 None,
30 None,
31 khz(10),
32 );
33
34 /*
35 Dead-time = T_clk * T_dts * T_dtg
36
37 T_dts:
38 This bit-field indicates the division ratio between the timer clock (CK_INT) frequency and the
39 dead-time and sampling clock (tDTS)used by the dead-time generators and the digital filters
40 (ETR, TIx),
41 00: tDTS=tCK_INT
42 01: tDTS=2*tCK_INT
43 10: tDTS=4*tCK_INT
44
45 T_dtg:
46 This bit-field defines the duration of the dead-time inserted between the complementary
47 outputs. DT correspond to this duration.
48 DTG[7:5]=0xx => DT=DTG[7:0]x tdtg with tdtg=tDTS.
49 DTG[7:5]=10x => DT=(64+DTG[5:0])xtdtg with Tdtg=2xtDTS.
50 DTG[7:5]=110 => DT=(32+DTG[4:0])xtdtg with Tdtg=8xtDTS.
51 DTG[7:5]=111 => DT=(32+DTG[4:0])xtdtg with Tdtg=16xtDTS.
52 Example if TDTS=125ns (8MHz), dead-time possible values are:
53 0 to 15875 ns by 125 ns steps,
54 16 us to 31750 ns by 250 ns steps,
55 32 us to 63us by 1 us steps,
56 64 us to 126 us by 2 us steps
57 */
58 pwm.set_dead_time_clock_division(Ckd::DIV1);
59 pwm.set_dead_time_value(0);
60
61 let max = pwm.get_max_duty();
62 pwm.enable(Channel::Ch1);
63
64 info!("PWM initialized");
65 info!("PWM max duty {}", max);
66
67 loop {
68 pwm.set_duty(Channel::Ch1, 0);
69 Timer::after(Duration::from_millis(300)).await;
70 pwm.set_duty(Channel::Ch1, max / 4);
71 Timer::after(Duration::from_millis(300)).await;
72 pwm.set_duty(Channel::Ch1, max / 2);
73 Timer::after(Duration::from_millis(300)).await;
74 pwm.set_duty(Channel::Ch1, max - 1);
75 Timer::after(Duration::from_millis(300)).await;
76 }
77}