linux驱动 -- PWM配置和SysFs操作方法

1:PWM介绍

PWM的定义为:可调节脉冲调节器,换句话来说就是一个总周期不变,占空比可调节的方波。

2:PWM的总周期和占空比、有效点平

方波:在信号领域一般分为数字信号和模拟信号,数字信号就两种状态:0和1,相互交替成为方波。

总周期:从1状态到1状态。也就是总周期为:从一个电平再回到这个电平。

占空比:有效电平占据占总周期的比例

有效电平:器件生效的电平

3:linux内核下的PWM

3.1 linux下的PWM的设备树编写方式

我所使用的开发板为RK3588S支持15路的PWM,经过裁剪之后配置三个PWM,分别为PWM7、PWM11、PWM12。

设备树编写:

&pwm7{
    pinctrl-0 = <&pwm7m0_pins>;//pwm作用的引脚
    status = "okay";
}
引脚配置:
pwm7m0_pins->GPIO0_RKPD0
pwm7m1_pins->GPIO4_RKPD4
pwm7m2_pins->GPIO1_RKPC3

额外说明:

        pwm开启后会按照从0的 ID号依次生成内核设备!

        PWM7        PWM11        PW12

                0               1                2

3.2 linux下PWM操作的中间接口

头文件:

#include "linux/pwm.h"

函数功能:向内核申请一个pwm设备,通过ID申请

函数原型:

struct pwm_device *pwm_request(
    int pwm_id,
    const char *label
);

函数参数:

        pwm_id:

                申请PWM的ID号,一般从0开始

        label:

                申请PWM使用的标签名

函数返回值:

        内核抽象出来的PWM设备结构体

        后续操作PWM都依靠这个结构体

函数功能:设置一个PWM 、总周期、占空比

函数原型:

int pwm_config(
    struct pwm_device *pwm,
    int duty_ns,
    int period_ns
)

函数参数:

        pwm:

                刚才申请得到的PWM的设备结构体

        duty_ns:

                占空周期的时间

        period_ns:

               总周期时间

函数返回值:

        成功返回0;失败返回非0

其他接口函数:

pwm_free();//释放函数

pwm_enable();//使能

pwm_disable();//失能

4:linux下SysFs下的PWM操作方法

linux驱动 -- PWM配置和SysFs操作方法_第1张图片

PWM设备分别对PWM7 PWM11 PWM12

在sys系统中:

        export注册接口文件

        unexport取消注册

echo 0 > export 注册 PWM7 的通道 0
echo 0 > unexport 取消注册 PWM7 的通道 0
如果注册成功就会生成 pwm0 这个文件夹
linux驱动 -- PWM配置和SysFs操作方法_第2张图片

生成pwm0就是sys下的控制接口文件

duty_cycle:占空比

enble:使能        0代表失能  1代表使能

period:总周期

polarity:极性反转;inverse 翻转的 normal正常

5:设备文件呼吸灯代码示例:

#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/of.h"
#include "linux/cdev.h"
#include "linux/fs.h"
#include "linux/gpio.h"
#include "linux/of_gpio.h"
#include "linux/device.h"
#include "linux/platform_device.h"
#include "linux/miscdevice.h"
#include "asm/uaccess.h"
#include "linux/input.h"
#include "linux/irq.h"
#include "linux/interrupt.h"
#include "linux/pwm.h"
#define MAX_PWM_VALUE 100000
struct miscdevice  misc;
struct file_operations *fop;
struct pwm_device * pwm_dev;//pwm核心结构体
//打开函数
int pwm_open (struct inode *ino, struct file *f)
{
	//pwm初始化函数
	pwm_config(pwm_dev, 0,MAX_PWM_VALUE);
	//使能PWM
	pwm_enable(pwm_dev);
	return 0;
}
//出口函数
int pwm_close (struct inode *i, struct file *f)
{
	pwm_config(pwm_dev, 0,0);//清零
	pwm_disable(pwm_dev	);
	return 0;
}
ssize_t pwm_write (struct file *f, const char __user *buf, size_t size, loff_t *lof)
{
	int ret = 0;
	uint32	value =0;
	ret = copy_from_user(&value,buf,size);
	if(value > MAX_PWM_VALUE)
	{
		return -EIO;
	}
	ret =ret;
	pwm_enable(pwm_dev);
	pwm_config(pwm_dev,value,MAX_PWM_VALUE)
	return 0;
	
	
}

//加载函数
static int __init pwm_init(void)
{
	pwm_dev = pwm_request(0,"pwm_led");
	if(pwm_dev == NULL)
	{
		printk("PWM Reuqest Failed\r\n");
		return -EINVAL;
	}
	fop.open = pwm_open;
	fop.owner = THIS_MODULE;
	fop.release = pwm_close;
	fop.write = pwm_write;
	
	misc.minor = 255;
	misc.name = "pwm_led";
	misc.fops =&fop ;
	return misc_register(&misc);
	
}
//卸载函数
static void __exit pwm_exit(void)
{
	misc_deregister(&misc);
	pwm_free(pwm_dev);
}
module_init(pwm_init);
module_exit(pwm_exit);
MODULE_LICENSE("GPL");

终端控制法:

#include "stdio.h"
#include 
#include 
#include 
#include "unistd.h"#include "stdint.h"
#include "linux/input.h"
#include 
#include 
struct input_event myreadvalue;
#define MAX_VALUE 10000
int main()
{
    int readvalue = 0;
    char buf[128]={0};
    system("echo 0 > /sys/class/pwm/pwmchip0/export");
    usleep(1000);
    system("echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable");
    usleep(1000);
    system("echo normal > /sys/class/pwm/pwmchip0/pwm0/polarity");
    usleep(1000);
    system("echo 10000 > /sys/class/pwm/pwmchip0/pwm0/period");
    usleep(1000);
    while(1)
    {
        printf("请输入一个占空比的值! :\r\n\t");
        scanf("%d",&readvalue);
        sprintf(buf,"echo %d > /sys/class/pwm/pwmchip0/pwm0/duty_cycle",readvalue);
        system(buf);
        memset(buf,0,128);
    }
    return 0;
}

你可能感兴趣的:(linux驱动,linux,运维,服务器)