#夏日挑战赛#【FFH】BearPi_Micro南向开发PWM驱动代码 原创 精华

X丶昕雪
发布于 2022-6-14 23:15
浏览
3收藏

本文正在参加星光计划3.0–夏日挑战赛

PWM介绍

PWM的频率是指在1秒钟内,信号从高电平到低电平再回到高电平的次数,也是指一秒钟能有多少个周期。占空比是一个脉冲周期内,高电平的时间与整个周期时间的比例。
在一定的频率下,PWM通过不同的占空比得到不同大小的输出模拟电压,通过这种原理实现数字模拟信号转换。
如下图第一个计数周期,当CNT<CCRx时输出低电平;当CNT>=CCRx时输出高电平。周期即是(t2-0)s,占空比是t1/t2.
#夏日挑战赛#【FFH】BearPi_Micro南向开发PWM驱动代码-鸿蒙开发者社区

打开PWM

首先注册一个DevHandle对象,用于存放PWM口驱动相关的配置和操作
static DevHandle MyHandler =NULL;
在驱动代码中添加引用PWM头文件
#include "pwm_if.h"

MyHandler = PwmOpen(uint32_t num);

其中PwmOpen函数内的操作如下:

DevHandle PwmOpen(uint32_t num)
{
struct PwmDev *pwm = PwmGetDevByNum(num);   //创建控制器结构体
//判断pwm是否成功启用
(void)OsalSpinLock(&(pwm->lock));   //上锁
//判断pwm->busy是否为繁忙,若为繁忙则解锁退出报错
//判断pwm->method和method->open是否不为空
 pwm->busy = true;
(void)OsalSpinUnlock(&(pwm->lock)); //解锁
return (DevHandle)pwm;
}
st=>start: Start
op=>operation: PwmDev *pwm
cond=>condition: pwm!=NULL
op1=>operation: 上锁
cond1=>condition: pwm->busy !=ture
op2=>operation: 解锁、报错
cond2=>condition: pwm->method == NULL 或 pwm->method->open == NULL
cond3=>condition: pwm->method->open(pwm)==0
a=>operation: pwm->busy=true
b=>operation: 解锁
e=>end

st->op->cond
cond(yes)->op1
cond(no)->e
op1->cond1
cond1(no)->op2
cond1(yes)->cond2
cond2(yes)->a
cond2(no)->cond3
cond3(yes)->a
cond3(no)->op2
a->b->e
op2->e

PWM结构体分析

其中PwmDev是核心层控制器结构体

struct PwmDev {
    struct IDeviceIoService service;
    struct HdfDeviceObject *device;
    struct PwmConfig cfg;       // 属性结构体,相关定义见下
    struct PwmMethod *method;   // 钩子函数模板
    bool busy;                  //PWM是否在使用
    uint32_t num;               // 设备号
    OsalSpinlock lock;
    void *priv;                 // 私有数据,一般存储自定义结构体首地址,方便调用
};

对于PwmConfig类型,该类型是结构体用于配置初始化PWM的参数

struct PwmConfig {
    uint32_t duty;              // 占空时间 
    uint32_t period;            // pwm 周期 
    uint32_t number;            // pwm 连续个数
    uint8_t polarity;           // 输出的极性 
    uint8_t status;             // 运行状态
};

polarity(PWM输出的极性,有效电平):

Bit Polarity meaning
0 PWM_NORMAL_POLARITY Normal polarity
1 PWM_INVERTED_POLARITY Inverted polarity

status(运行的状态):

Bit Status meaning
0 PWM_DISABLE_STATUS Disabled
1 PWM_ENABLE_STATUS Enabled

对于PwmMethod结构体,该结构体包含有

struct PwmMethod {
    int32_t (*setConfig)(struct PwmDev *pwm, struct PwmConfig *config);
    int32_t (*open)(struct PwmDev *pwm);
    int32_t (*close)(struct PwmDev *pwm);
};

以上三个参数都是返回int类型的函数指针

PWM配置

方法一

当我们需要配置pwm时,只需要配置好一个PwmConfig类型的一个结构体,再使用PwmSetConfig函数进行配置

PwmSetConfig(DevHandle handle, struct PwmConfig *config);

方法二

小熊派上有许多PWM配置的具体函数,每一个函数配置一个PWM的配置参数,便于操作,下面列举其中几个:

关闭PWM

PwmClose(DevHandle Handler);

PWM设置周期(自动重装载值)

PwmSetPeriod(DevHandle handle, uint32_t period);

PWM设置占空比

PwmSetDuty(DevHandle handle, uint32_t duty);

PWM输出的极性,有效电平

一个PWM信号的极性,决定了是高占空比的信号输出电平高,还是低占空比信号输出电平高。假设一个信号的占空比为100%,如果为正常极性,则输出电平最大,如果为翻转的极性,则输出电平为0。

PwmSetPolarity(DevHandle handle, uint8_t polarity);

PWM使能

PwmEnable(DevHandle handle);

PWM失能

PwmDisable(DevHandle handle);

驱动代码中启动PWM的配置流程图:

st=>start: PwmOpen
op=>operation: PwmSetPeriod
cond=>operation: PwmSetDuty
cond1=>operation: PwmSetPolarity
cond2=>operation: PwmEnable
e=>end

st->op->cond->cond1->cond2->e

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-6-14 23:16:15修改
9
收藏 3
回复
举报
3条回复
按时间正序
/
按时间倒序
FFH杞人
FFH杞人

写得很好,赞一个

回复
2022-6-15 17:04:56
FFH_magic_H
FFH_magic_H

大佬,求带!

回复
2022-6-16 14:06:17
Whyalone
Whyalone

PWM 不要太重要

回复
2022-6-16 16:34:15
回复
    相关推荐