zoukankan      html  css  js  c++  java
  • ambarella H2平台用PWM控制LCD背光

    ambarella H2系列Soc的GPIO口能作PWM使用的个数有限(GPIO0-GPIO3),从PRM里GPIO: Function Selection章节可以得到如何配置GPIO为PWM功能。

     假设想把GPIO0配置成PWM输出,根据上图修改ambarella/boards/h2_xxx/bsp/bsp.h ,如下:

    即DEFAULT_IOMUX_REG0_2、DEFAULT_IOMUX_REG0_1、DEFAULT_IOMUX_REG0_0的第0位要分别设为0、1、1。

    一、系统层用脚本控制PWM0示例

    echo 0 > /sys/class/pwm/pwmchip0/export
    echo 5000000 > /sys/class/pwm/pwmchip0/pwm0/period (设置周期)
    echo 2000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle (设置有效时间)
    echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable (使能PWM)

    占空比= 有效时间/周期, 占空比越大,LCD背光越亮(有效时间要小于等于周期时间)。

    为了方便使用写成脚本set_pwm.sh:

    #! /bin/bash
    #
    # set_pwm.sh <gpio_id>  < 1 | 0 > <duty_cycle> <period>
    
    do_cmd()
    {
            local id=$1
            local ena=$2
            local d_cycle=$3
            local per=$4
            local GPIO_ROOT=/sys/class/pwm/pwmchip0
            local GPIO_DIR=$GPIO_ROOT/pwm$id
    
            if [[ ! -d $GPIO_DIR ]]; then
                    echo $id > $GPIO_ROOT/export
            fi
    
            echo $ena > $GPIO_DIR/enable
            echo $per > $GPIO_DIR/period
            echo $d_cycle > $GPIO_DIR/duty_cycle
    }
    
    usage()
    {
            echo " set_pwm.sh <gpio_id>  < 1 | 0 > <duty_cycle> <period>"
    }
    
    do_main()
    {
            case "$2" in
                    1)
                            do_cmd $1 1 $3 $4
                            ;;
                    0)
                            do_cmd $1 0 $3 $4
                            ;;
                    *)
                            usage
                            ;;
            esac
    }
    
    if [[ -z $4 ]]; then
            usage
    else
            do_main $*
    fi

     二、写一个pwm驱动

    pwm.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/miscdevice.h>
    #include <linux/fs.h>
    #include <linux/ioctl.h>
    #include <linux/pwm.h>
    #include <linux/uaccess.h>
    
    
    #define PWM_MAGIC 'P' //定义一个幻数
    #define PWM_ON _IOW(PWM_MAGIC, 0, struct pwm_capture_t) //定义一个ioctl cmd
    #define PWM_OFF _IOW(PWM_MAGIC, 1, struct pwm_capture_t) //定义另一个ioctl cmd struct pwm_device *pwm_dev_0; struct pwm_capture_t { unsigned int period; unsigned int duty_cycle; }pwmm; static long pwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret; switch(cmd) { case PWM_ON: ret = copy_from_user(&pwmm, (void *)arg, sizeof(struct pwm_capture_t)); if (ret < 0) return ret; ret = pwm_config(pwm_dev_0, pwmm.duty_cycle, pwmm.period); if (ret < 0) { printk("pwm_dev_0 ioctl fail"); return 0; } pwm_enable(pwm_dev_0); break; case PWM_OFF: ret = copy_from_user(&pwmm, (void *)arg, sizeof(struct pwm_capture_t)); if (ret < 0) return ret; ret = pwm_config(pwm_dev_0, 0, pwmm.period); if (ret < 0) { printk("pwm_dev_2 ioctl fail"); return 0; } pwm_disable(pwm_dev_0); break; } return 0; } //定义初始化硬件操作方法 static struct file_operations pwm_fops = { .owner = THIS_MODULE, .unlocked_ioctl = pwm_ioctl }; //定义初始化混杂设备对象 static struct miscdevice pwm_misc = { .minor = MISC_DYNAMIC_MINOR, //动态分配次设备号 .name = "mypwm", //dev/mypwm .fops = &pwm_fops }; static int pwm_init(void) { int ret; printk("regisger pwm_misc device "); //1.申请pwm资源,设置输出为0 pwm_dev_0 = pwm_request(0, "pwm_0"); if (pwm_dev_0 == NULL) { printk("pwm_dev_0 register fail "); } ret = pwm_config(pwm_dev_0, 0, 500000); if (ret < 0) { printk("pwm_dev_0 config fail "); return 0; } ret = pwm_enable(pwm_dev_0); if (ret == 0) { printk("pwm_dev_0 enable success "); } else if (ret < 0 ) { printk("pwm_dev_0 enable fail "); return 0; } //2.注册混杂设备 misc_register(&pwm_misc); return 0; } static void pwm_exit(void) { printk("unregister pwm_misc device "); //1.卸载混杂设备 misc_deregister(&pwm_misc); //2.释放pwm资源 pwm_config(pwm_dev_0, 0, 500000); pwm_disable(pwm_dev_0); pwm_free(pwm_dev_0); } module_init(pwm_init); module_exit(pwm_exit); MODULE_LICENSE("GPL");

    测试程序pwm_test.c:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define PWM_MAGIC 'P' //定义一个幻数,要和pwm.c里定义的相同
    #define PWM_ON _IOW(PWM_MAGIC, 0, struct pwm_capture_t)  //定义一个ioctl cmd, 要和pwm.c里定义的相同
    #define PWM_OFF _IOW(PWM_MAGIC, 1, struct pwm_capture_t) //同上
    
    struct pwm_capture_t {
        unsigned int period;
        unsigned int duty_cycle;
    };
    
    int main(int argc, char **argv)
    {
        int fd;
        int a;
        int period, duty_cycle;
        if (argc < 4) {
            printf("usage: %s on/off duty_cycle period
    ", argv[0]);
            return -1;
        }
        duty_cycle = strtol(argv[2], NULL, 10);
        period = strtol(argv[3], NULL, 10);
        if (duty_cycle > period) {
            printf("duty_cycle shouldn't larger than period
    ");
            return -1;
        }
        struct pwm_capture_t pwmm = {period, duty_cycle};
    
        fd = open("/dev/mypwm", O_RDWR);
        if (fd < 0)
            return -1;
        while(1) {
        /*    for(a = 0; a <= period; a += 5) {
                pwmm.duty_cycle = a;
                ioctl(fd, PWM_ON, &pwmm);
                usleep(1000);
            }
            
            for(a = period; a >= 0; a -= 5) {
                pwmm.duty_cycle = a;
                ioctl(fd, PWM_ON, &pwmm);
                usleep(1000);
            }
            usleep(1000000);
        }
        */
    
        if (strcmp(argv[1], "on") == 0) {
            ioctl(fd, PWM_ON, &pwmm);
        } else if (strcmp(argv[1], "off") == 0) {
            ioctl(fd, PWM_OFF, &pwmm);
        } else {
            printf("invalid parameter
    ");
        }
    
    
        close(fd);
        return 0;
    }

     执行./pwm_test on 200000 500000,会看到LCD背光点亮,增加duty_cycle的值,背光会变得更亮。

    pwm除了可以控制屏幕亮度外还可以控制风扇转速,根据 cpu/主板 温度调整散热风扇的转速,也是一个常用的功能。

  • 相关阅读:
    IO流基础
    DB2 存储过程创建、系统表
    dubbo实现原理简单介绍
    Java 标准 I/O 介绍
    mysql由于权限问题看不到用户数据库
    java 字符常量池
    Java NIO:NIO概述
    128 C语言实现文件复制功能(包括文本文件和二进制文件)
    Linux 下各个目录的作用及内容
    Linux文件系统详解
  • 原文地址:https://www.cnblogs.com/wanglouxiaozi/p/11759068.html
Copyright © 2011-2022 走看看