K210入门-裸机开发(六)之定时器pwm

2021-03-104747
AI 快速预览详细 收起
本文介绍了在K210 AIRV R3版widora开发板上进行定时器PWM的裸机开发。首先配置开发环境,然后通过修改代码实现PWM输出。通过调整PWM通道和参数设置,最终实现了呼吸灯效果。文章详细讲解了定时器初始化、PWM频率设置和占空比调整的过程,适合嵌入式开发初学者。

K210入门-裸机开发(六)之定时器pwm

开发板:K210 AIRV R3版 widora

开发环境:kendryte IDE 官方的

必须的参考文档:Standalone SDK编程指南v0.5.0,以及widora的原理图

1.新建文件夹 06my_code_pwm

K210入门-裸机开发(六)之定时器pwm图1
礼物+地球

K210入门-裸机开发(六)之定时器pwm图2

实例->输入pwm->选择开发develop版本->然后下载到刚才的文件夹中

K210入门-裸机开发(六)之定时器pwm图3

安装依赖

K210入门-裸机开发(六)之定时器pwm图4

清理+构建

K210入门-裸机开发(六)之定时器pwm图5

环境配置完成 下面开始修改代码

1. 修改代码

PWM在第20章

K210入门-裸机开发(六)之定时器pwm图6

也有举例 等下就抄

K210入门-裸机开发(六)之定时器pwm图7
定义了两个宏定义 方便以后移植的

K210入门-裸机开发(六)之定时器pwm图8

代码修改完如下

K210入门-裸机开发(六)之定时器pwm图9
下面说PWM

K210入门-裸机开发(六)之定时器pwm图10

参数类型如下

K210入门-裸机开发(六)之定时器pwm图11

同样的 为了方便移植 先搞个宏定义

K210入门-裸机开发(六)之定时器pwm图12

初始化代码如下

K210入门-裸机开发(六)之定时器pwm图13

配置PWM 设置占空比

K210入门-裸机开发(六)之定时器pwm图14
K210入门-裸机开发(六)之定时器pwm图15

使能PWM输出, 最后再开总中断开关

K210入门-裸机开发(六)之定时器pwm图16

K210入门-裸机开发(六)之定时器pwm图17

定时器中断服务函数 , 例程这里是呼吸灯(暗->亮->暗->亮) 不错 不用改

K210入门-裸机开发(六)之定时器pwm图18

3.灯呢 找灯

K210入门-裸机开发(六)之定时器pwm图19

点开这个device管理, 发现他居然配置到了TIMER1

K210入门-裸机开发(六)之定时器pwm图20

我们用到的 定时器设备0,把他改一改 LED是对应IO17 ,18

但我们只配置了通道0 所以只有1个灯输出,那就配置一个灯, 保存

K210入门-裸机开发(六)之定时器pwm图21

一条龙 清理 + 构建 +下载

K210入门-裸机开发(六)之定时器pwm图22

4.效果

灯亮了 但好像没有呼吸效果?

K210入门-裸机开发(六)之定时器pwm图23

5.发现问题

K210入门-裸机开发(六)之定时器pwm图24

PWM那边改为通道1 这个问题我调了大半个小时才想起数据手册写的内容

K210入门-裸机开发(六)之定时器pwm图25

配置那边改为通道2

K210入门-裸机开发(六)之定时器pwm图26

再一条龙走起

K210入门-裸机开发(六)之定时器pwm图27

效果

出现了呼吸灯了

K210入门-裸机开发(六)之定时器pwm图28

定时器PWM学习完毕 ,下次再见


代码

#include <fpioa.h>
#include <plic.h>
#include <pwm.h>
#include <stdio.h>
#include <sysctl.h>
#include <syslog.h>
#include <timer.h>

#define TIMER_DEVICE TIMER_DEVICE_0
#define TIMER_DEVICE_CH TIMER_CHANNEL_0

#define TIMER_PWM PWM_DEVICE_0
#define TIMER_PWM_CHN PWM_CHANNEL_1

int timer_callback(void *ctx) {
  static double cnt = 0.1;
  static int flag = 0;

  // 重新赋值PWM输出频率以及占空比
  pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN, 200000, cnt);

  // 三目运算,构成呼吸灯
  flag ? (cnt -= 0.01) : (cnt += 0.01);

  //越界判断
  if (cnt > 1.0) {
    cnt = 1.0;
    flag = 1;
  } else if (cnt < 0.0) {
    cnt = 0.0;
    flag = 0;
  }
}

int main(void) {
  /* Init Platform-Level Interrupt Controller(PLIC) */
  plic_init();  // 初始化中断
  /* Init timer */
  timer_init(TIMER_DEVICE);  //初始化定时器

  /* Set timer interval to 10ms (1e7ns) */
  // 配置定时器时间
  timer_set_interval(TIMER_DEVICE, TIMER_DEVICE_CH, 1e7);

  /* Set timer callback function with repeat method */
  // 绑定下中断回调函数(不带形参)
  timer_irq_register(TIMER_DEVICE, TIMER_DEVICE_CH, 0, 1, timer_callback, NULL);

  // 定时器0, 通道0,定时器回调函数,优先级
  // //上一节学的定时器,可以替代上面的注册函数吧 timer_set_irq(TIMER_DEVICE,
  // TIMER_DEVICE_CH, timer_callback, 1);

  /* Enable timer */
  //使能定时器
  timer_set_enable(TIMER_DEVICE, TIMER_DEVICE_CH, 1);

  /* Init PWM */
  // 初始化PWM
  pwm_init(TIMER_PWM);
  /* Set PWM to 200000Hz */
  // 设置PWM的频率 以及占空比
  pwm_set_frequency(TIMER_PWM, TIMER_PWM_CHN, 200000, 0.5);
  /* Enable PWM */
  // 启动产生PWM
  pwm_set_enable(TIMER_PWM, TIMER_PWM_CHN, 1);

  /* Enable global interrupt for machine mode of RISC-V */
  sysctl_enable_irq();  // 开中断
  while (1)
    ;
}

版权声明:本文为CSDN博主「jwdeng1995」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jwdeng1995/article/details/108033986

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(0)
- 没有更多了 -