|
使用Platformio平台的libopencm3开发框架来开发STM32G0,下面使用PWM来实现LED呼吸灯效果。
/ q* \& {0 z5 \: z. D, L/ j& P 1 新建项目在PIO主页新建项目pwm,框架选择libopencm3,开发板选择 MonkeyPi_STM32_G070RB; 新建完成后在src目录新建主程序文件main.c; 然后更改项目文件platformio.ini的烧写和调试方式: ' Q* a9 Q, O2 Q9 T+ Y) S
- 1upload_protocol = cmsis-dap
' I9 p' m5 E+ z) R/ k' w0 ]/ w - 2debug_tool = cmsis-dap
复制代码 : e x2 r6 K: _$ c! o& `+ h) g) I$ o% P
2 PWM配置GPIO设置为复用PWM输出 ' c T4 W+ ]9 C" @* K& T: c
- 1/**
2 ?) B0 I2 e4 y. I2 w. a0 ]" x - 2 * @brief gpio config " Z3 B& N( f& p4 d
- 3 *
0 K: }- |; Z& p6 f - 4 */
8 S* q9 K- h2 I - 5static void gpio_setup(void)- [8 \$ U# o1 m- i' j# M# X; t- ?/ i
- 6{' X, V& P8 B8 z9 M' Z6 o
- 7 rcc_periph_clock_enable(RCC_GPIOC);
. H: A8 G' F( A1 B# f! K - 87 j: }. C# i' V7 \
- 9 gpio_mode_setup(GPIOC,
- O. C. Z* H8 ?1 G" t - 10 GPIO_MODE_AF,
4 H6 Z2 S9 p. T3 {$ I/ v - 11 GPIO_PUPD_NONE,- J5 x, J$ g' i
- 12 GPIO12);% c6 p( X" q8 H, g+ v+ H. k6 y5 {
- 13
5 R' L0 K. v0 E - 14 gpio_set_output_options(GPIOC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO12);
; p6 N% w' z7 a/ o& w: w; F' B" ~ - 15
$ }2 w, Y5 G, [ - 16 //TIM14_CH1 , AF2
, n; _5 A* p3 K) x& x' ? - 17 gpio_set_af(GPIOC,GPIO_AF2,GPIO12);, U9 a5 B: g; Z* V/ c
- 18}
复制代码
; n! _+ T) p$ z. i, [* _# A
1 X$ u x/ A8 Q1 [PWM配置
4 n' `( ?. e/ @$ L5 J, p
- 1/**
1 K7 a' o. w; ]$ I! _: j+ d/ n- } - 2 * @brief pwm channel setup
% w! h' r6 l# Y% K: Y( h - 3 *
9 n$ }. `4 x+ }) f& h, t5 u4 O - 4 */
8 T8 i# P( A6 X( y" x) } - 5static void pwm_setup(void)
' J' w W* I. k - 6{
8 \* |+ r2 o: c7 H - 7 rcc_periph_clock_enable(RCC_TIM14);" F$ k/ G, a# h7 q! n Y: Y/ U
- 8. b A* h) r- X) o. o/ V6 Q8 ?
- 9 /* Timer global mode:
6 m8 ` X: w; \) D - 10 * - No divider$ @& g$ N* @) d, D% g, E d
- 11 * - Alignment edge
8 h5 G! y4 s. [$ O" R$ D - 12 * - Direction up
& K/ A- A: B/ _5 C5 [' L: t - 13 */
* }& y% u7 I5 ^" q$ B$ f9 _ - 14 timer_set_mode(TIM14, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);0 A8 F4 R( G7 Y7 `
- 150 w( u2 m+ ?6 T1 ~4 h8 J6 a( ~
- 16 /*
( A# B1 f* J/ S7 l) d9 j; v7 c! [ - 17 * APB1 PRE = 1, TIMPCLK = PCLK* Z' u8 d- s8 V$ V* ^! l7 H$ K
- 18 * APB1 PRE != 1, TIMPCLK = PCLK * 2
* D7 H- O" y9 K2 e - 19 */
+ b4 ?$ c, P8 I) } - 20 timer_set_prescaler(TIM14, (rcc_apb1_frequency/100000-1)); //100KHz
2 ]2 T, Z& R7 F) W2 u% v - 21
- L( H- |# ~2 g- a - 22 /* Disable preload. */
+ X u( w/ Y5 p. l) w9 H2 y - 23 timer_disable_preload(TIM14);
+ m; s7 U6 u Q$ Q B' s - 24 timer_continuous_mode(TIM14);1 K2 P- `1 r# E
- 259 S& P. m; |5 Y0 @' i! a& {' [
- 26 /* Timer Period */
# g* ~. b7 d# ]5 w& D r - 27 timer_set_period(TIM14, 20-1); /* 100kHz /20 = 5 KHz */
9 u# G* K4 u" w - 28
+ s [+ ], f9 }( y - 29 /* Set the initual output compare value for OC1. */
1 K$ M% P0 [9 A1 x1 U# {" t" k - 30 timer_set_oc_mode(TIM14, TIM_OC1, TIM_OCM_PWM1);
6 d0 C, L: m, p7 s5 f - 31 timer_set_oc_value(TIM14, TIM_OC1, 20*0.3); //duty = 0.3
, z: k3 i+ X. `7 \5 F - 32
4 i/ e, v% p3 F' b( W- U - 33 /* Enable output */; }7 c9 H/ ~/ L8 d# y( ]" x
- 34 timer_enable_oc_output(TIM14, TIM_OC1);, p* C8 g: _7 ]% O
- 35 timer_enable_counter(TIM14);- l/ \4 a- a$ `" b4 s9 x
- 36}
复制代码 , I" R- ?& s: B9 k8 ]+ B
; ?, |2 T7 ~5 L8 x3 N8 Q; b9 @8 b
先配置定时器的预分频和周期,这里设置到周期为5KHz,可以参考定时器章节的说明; 然后使用timer_set_oc_value 设置占空比,占空比根据定时器周期计算,比如这里设置为30%占空比; # C- m* y9 L C! Y$ Y
! `' F0 @- g# @7 f
3 呼吸灯效果实现呼吸灯效果就是更改占空比,让其从0-100变化在从100-0变化即可; - 1int duty = 0;5 }5 N: U6 t1 d+ @! D; ]
- 2# m- C* J. j. {- V3 I, N# _
- 3while(1){( G- U& H/ V# o7 ?8 g9 u
- 4
5 f& |5 w7 r( M1 z - 5 //from 0 - 100
' Y0 I& ]7 {- e* T9 p+ ~ - 6 for(duty=0; duty <= 100; duty++){
( w a0 v( d. u8 T+ y - 7 duty = duty + 1;# W% e/ q( U% w6 W* }7 o& X
- 8 timer_set_oc_value(TIM14,TIM_OC1, 20*duty/100);
" ^' v. w2 b4 b2 i0 z9 b8 a - 9) n3 Q7 u( Q; Y# i" w; t& s6 [
- 10 //delay some time
% D9 e f, Z0 p( A! k$ y% ] - 11 for(int i=0; i<600000; i++){/ F: o, g' i/ n! E
- 12 __asm__("nop");
% W4 Q0 A G) N* s - 13 }
7 s- t7 h; C! g - 14 }
8 p" X" _# I6 s" S! I6 m0 ?! c5 K - 15
1 n( m7 E4 t1 p r) M U4 w - 16 //from 100-0
( I$ p- t- c. ~# V, e } - 17 for(duty=100;duty>=0; duty--){
D; T7 l5 ^6 q0 q - 18 duty = duty - 1;
4 i+ x& ?: w! m - 19 timer_set_oc_value(TIM14,TIM_OC1, 20*duty/100);: x# o# d4 I5 ~; H" i, o& g3 u( r
- 20
: ]: `' _5 ^2 M1 O( c f - 21 //delay some time
; b( c; p' z- X7 R - 22 for(int i=0; i<600000; i++){
`: ? P$ \4 M- O8 }- A' v- t% P - 23 __asm__("nop");
; W% h1 E1 T+ @- W- r5 ] - 24 }
4 W" T0 ?& P+ P; z1 h7 l - 25
) r9 h! H# ?4 b! w& a) C0 K3 z' Q - 26 }3 t/ V7 U# Z- u4 T/ O0 W
- 27* F* p/ N% q+ d" d4 x' T
- 28}
复制代码 4 V" a+ c- z! |
转载自:MakerInChina.cn
6 V. Q, z9 E* m) v |