使用Platformio平台的libopencm3开发框架来开发STM32G0,下面使用PWM来实现LED呼吸灯效果。
1 新建项目
在PIO主页新建项目pwm,框架选择libopencm3,开发板选择 MonkeyPi_STM32_G070RB;
新建完成后在src目录新建主程序文件main.c;
然后更改项目文件platformio.ini的烧写和调试方式:
1upload_protocol = cmsis-dap
2debug_tool = cmsis-dap
2 PWM配置
GPIO设置为复用PWM输出
1/**
2 * @brief gpio config
3 *
4 */
5static void gpio_setup(void)
6{
7 rcc_periph_clock_enable(RCC_GPIOC);
8
9 gpio_mode_setup(GPIOC,
10 GPIO_MODE_AF,
11 GPIO_PUPD_NONE,
12 GPIO12);
13
14 gpio_set_output_options(GPIOC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO12);
15
16 //TIM14_CH1 , AF2
17 gpio_set_af(GPIOC,GPIO_AF2,GPIO12);
18}
PWM配置
1/**
2 * @brief pwm channel setup
3 *
4 */
5static void pwm_setup(void)
6{
7 rcc_periph_clock_enable(RCC_TIM14);
8
9 /* Timer global mode:
10 * - No divider
11 * - Alignment edge
12 * - Direction up
13 */
14 timer_set_mode(TIM14, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
15
16 /*
17 * APB1 PRE = 1, TIMPCLK = PCLK
18 * APB1 PRE != 1, TIMPCLK = PCLK * 2
19 */
20 timer_set_prescaler(TIM14, (rcc_apb1_frequency/100000-1)); //100KHz
21
22 /* Disable preload. */
23 timer_disable_preload(TIM14);
24 timer_continuous_mode(TIM14);
25
26 /* Timer Period */
27 timer_set_period(TIM14, 20-1); /* 100kHz /20 = 5 KHz */
28
29 /* Set the initual output compare value for OC1. */
30 timer_set_oc_mode(TIM14, TIM_OC1, TIM_OCM_PWM1);
31 timer_set_oc_value(TIM14, TIM_OC1, 20*0.3); //duty = 0.3
32
33 /* Enable output */
34 timer_enable_oc_output(TIM14, TIM_OC1);
35 timer_enable_counter(TIM14);
36}
先配置定时器的预分频和周期,这里设置到周期为5KHz,可以参考定时器章节的说明;
然后使用timer_set_oc_value 设置占空比,占空比根据定时器周期计算,比如这里设置为30%占空比;
3 呼吸灯效果
实现呼吸灯效果就是更改占空比,让其从0-100变化在从100-0变化即可;
1int duty = 0;
2
3while(1){
4
5 //from 0 - 100
6 for(duty=0; duty <= 100; duty++){
7 duty = duty + 1;
8 timer_set_oc_value(TIM14,TIM_OC1, 20*duty/100);
9
10 //delay some time
11 for(int i=0; i<600000; i++){
12 __asm__("nop");
13 }
14 }
15
16 //from 100-0
17 for(duty=100;duty>=0; duty--){
18 duty = duty - 1;
19 timer_set_oc_value(TIM14,TIM_OC1, 20*duty/100);
20
21 //delay some time
22 for(int i=0; i<600000; i++){
23 __asm__("nop");
24 }
25
26 }
27
28}
通过 timer_set_oc_value 改变输出占空比,然后延时一定时间即可达到呼吸灯的效果。