历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2021年12月30日 | 4412 4路pwm输出

发布者:心灵舞动 来源: eefocus关键字:4路  pwm输出 手机看文章 扫描二维码
随时随地手机看文章

一、4412 xpwmTOUT1

这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能。因此如果使用教程中的代码,同样操作GPD0_1是行不通的。


会出现错误,所以需要解除在内核中的占用

修改arch/arm/mach-exynos/mach-itop4412.c,找到并注释


samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);


在内核中取消相关的模块编译,(不确定)

Device Driver>>Graphics support>>Backlight & LCD device support(取消)

 

然后在平台文件中增加注册设备:


&s3c_device_timer[1],


然后是测试代码:

my_pwm3.c

#include <linux/module.h>

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#define DEVICE_NAME "my_pwm3_dev"

#define DRIVER_NAME "my_pwm3_drv"


#define PWM_MAGIC 'p'

#define PWM_MAX_NR 3


#define PWM_IOCTL_STOP      _IO(PWM_MAGIC, 0)

#define PWM_IOCTL_SET_FREQ  _IO(PWM_MAGIC, 1)

#define PWM_IOCTL_SET_DUTY  _IO(PWM_MAGIC, 2)


#define NS_IN_1HZ                               (1000000000UL)


#define BUZZER_PWM_ID                   0

#define PWM1_ID                                 1

#define PWM2_ID                 2

#define PWM3_ID                 3



#define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)

#define PWM1_GPIO               EXYNOS4_GPD0(1)

#define PWM2_GPIO       EXYNOS4_GPD0(2)

#define PWM3_GPIO       EXYNOS4_GPD0(3)


static struct pwm_device *pwm4buzzer;

static struct semaphore lock;

static int period_ns = 1000;

static unsigned long freq = 50;

static unsigned long duty = 2;


static void pwm_set_freq(void)

{

    //配置周期

    period_ns = NS_IN_1HZ / freq;

    //配置占空比

        if(duty < 1)

                duty = 1;

    pwm_disable(pwm4buzzer);

    pwm_config(pwm4buzzer, period_ns / duty, period_ns);

    pwm_enable(pwm4buzzer);

    //配置相应的GPIO,蜂鸣器IO配置成PWM输出模式

    s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN(2));

}


static void pwm_stop(void)

{

    s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT);


    pwm_config(pwm4buzzer, 0, NS_IN_1HZ / 100);

    pwm_disable(pwm4buzzer);

}


static int ops_pwm_open(struct inode *inode, struct file *file)

{

    if(!down_trylock(&lock))

        return 0;

    else

        return -EBUSY;

}


static int ops_pwm_close(struct inode *inode, struct file *file)

{

    up(&lock);

    return 0;

}


static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,

                unsigned long arg)

{

    if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;

    if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL;


    switch(cmd) {

    case PWM_IOCTL_SET_FREQ:

        if(arg == 0)

            return -EINVAL;

        get_user(freq, (unsigned long __user *)arg);

        printk(KERN_EMERG "freq is %ldn", freq);

        pwm_set_freq();

        break;

    case PWM_IOCTL_STOP:

        pwm_stop();

                break;

        case PWM_IOCTL_SET_DUTY:

        get_user(duty, (unsigned long __user *)arg);

        printk(KERN_EMERG "duty is %ldn", duty);

        pwm_set_freq();

                break;

    default:

        pwm_stop();

        break;

    }

    return 0;

}


static struct file_operations pwm_ops = {

    .owner = THIS_MODULE,

    .open  = ops_pwm_open,

    .release = ops_pwm_close,

    .unlocked_ioctl = ops_pwm_ioctl,

};


static struct miscdevice pwm_misc_dev = {

    .minor = MISC_DYNAMIC_MINOR,

    .name  = DEVICE_NAME,

    .fops  = &pwm_ops,

};


static int __init iTop4412_pwm_dev_init(void)

{

    int ret;

    gpio_free(PWM3_GPIO);


    ret = gpio_request(PWM3_GPIO, DEVICE_NAME);

    if(ret) {

                printk(KERN_EMERG "request GPIO %d for pwm failedn", PWM3_GPIO);

                return ret;

    }


        gpio_set_value(PWM3_GPIO, 0);

        s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT);


        pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);

        if (IS_ERR(pwm4buzzer)) {

                printk(KERN_EMERG "request pwm %d for %s failedn", PWM3_ID, DEVICE_NAME);

                return -ENODEV;

        }

    pwm_stop();


    sema_init(&lock, 1);

    ret = misc_register(&pwm_misc_dev);

        if(ret < 0) {

                gpio_free(BUZZER_PMW_GPIO);

                pwm_free(pwm4buzzer);

                misc_deregister(&pwm_misc_dev);

        }


    printk(KERN_EMERG "tinitializedn");


    return ret;

}


static void __exit iTop4412_pwm_dev_exit(void)

{

    gpio_free(BUZZER_PMW_GPIO);

        pwm_free(pwm4buzzer);

    misc_deregister(&pwm_misc_dev);


    printk(KERN_EMERG "texitn");

    return;

}


module_init(iTop4412_pwm_dev_init);

module_exit(iTop4412_pwm_dev_exit);


MODULE_LICENSE("GPL");

MODULE_AUTHOR("Chen Tuo");

MODULE_DESCRIPTION("Exynos4 PWM Driver");


然后是应用程序

my_pwm3_app.c

#include

#include

#include

#include

#include

#include


#define PWM2_NAME "/dev/my_pwm3_dev"


#define PWM_MAGIC 'p'

#define PWM_MAX_NR 3


#define PWM_IOCTL_STOP      _IO(PWM_MAGIC, 0)

#define PWM_IOCTL_SET_FREQ  _IO(PWM_MAGIC, 1)

#define PWM_IOCTL_SET_DUTY  _IO(PWM_MAGIC, 2)


int fd = -1;


void open_pwm1(void);

void close_pwm1(void);

void set_pwm_freq(int freq);

void set_pwm_duty(int duty);

void stop_pwm(void);


void open_pwm1(void)

{

    fd = open(PWM2_NAME, O_RDWR);

    if(fd < 0) {

        perror("open pwm1 device");

        exit(1);

    }


//    atexit(close_pwm1);

}


void close_pwm1(void)

{

    if(fd >= 0) {

        ioctl(fd, PWM_IOCTL_STOP);

        close(fd);

        fd = -1;

    }

}


void set_pwm_freq(int freq)

{

    int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, &freq);

    if(ret < 0) {

        perror("set the frequency of the buzzer");

        exit(1);

    }

}


void set_pwm_duty(int duty)

{

    int ret = ioctl(fd, PWM_IOCTL_SET_DUTY, &duty);

    if(ret < 0) {

        perror("set the duty of the pwm");

        exit(1);

    }

}


void stop_pwm(void)

{

    int ret = ioctl(fd, PWM_IOCTL_STOP);

    if(ret < 0) {

        perror("Stop the buzzer");

        exit(1);

    }

}


int main(int argc, char *argv[])

{

    int freq = 1000;


    open_pwm1();

    stop_pwm();

    if(argc < 3) {

        printf("usage:%s [cmd] [arg]n", argv[0]);

        printf("tstop:%s [0] [0] n",argv[0]);

        printf("tset freq:%s [1] [arg]n", argv[0]);

        printf("tset duty:%s [2] [arg]n", argv[0]);

    }

        switch(atoi(argv[1]))

        {

        case 2:

                set_pwm_duty(atoi(argv[2]));

        break;

        case 1:

                set_pwm_freq(atoi(argv[2]));

                break;

    case 0:

        default:

                stop_pwm();

                return -1;

        }


        return 0;

}


最后是Makefile:

Makefile

TARGET_NAME = my_pwm3

#TARGET_NAME = example_pwm

APP1_NAME = my_pwm3_app

#APP2_NAME = open_atomic_int_two

obj-m += $(TARGET_NAME).o


KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3.0


PWD ?= $(shell pwd)


all:app1

        make -C $(KDIR) M=$(PWD) modules

app1:

        arm-none-linux-gnueabi-gcc $(APP1_NAME).c -o $(APP1_NAME) -static

#app2:

#       arm-none-linux-gnueabi-gcc $(APP2_NAME).c -o $(APP2_NAME) -static


clean:

        rm -rf *.o *.ko *.mod.c *.symvers *.order

        .$(TARGET_NAME)* $(APP1_NAME) $(APP2_NAME)

[1] [2]
关键字:4路  pwm输出 引用地址:4412 4路pwm输出

上一篇:4412 gpio读取pwm
下一篇:4412 Linux定时器

推荐阅读

        新浪手机讯 12月29日上午消息,国外著名视频网站Netflix为节省用户成本,将取消应用内订阅选项,从而规避苹果30%的抽成。  目前,Netflix已经在Apple TV中取消“观看历史”以及“内容建议”等功能,仅能搜索其站内的视频内容,该公司可能会进一步疏远与苹果之间的关系。  根外媒报道,Netflix将取消新用户通过iTunes进行订阅付费的...
近日,国家知识产权局公布了vivo公司在2019年7月1日申请了三项手机的设计专利,通过展示草图可以看到这三款手机的设计细节。从图中可以看到,vivo三款手机的屏幕均采用四个打孔设计,但是位置不同;第一个手机在屏幕的四个角各有一个打孔;第二个四个打孔位置在上方,左右各两个;第三个设计的打孔位置也在手机上方,和第二个相比孔更小,看起来像是独立打...
引言煤炭作为一种重要的能源,在工业生产等许多方面发挥着举足轻重的作用,关系着国民经济的命脉。煤炭开采中的安全问题一直是受到极大重视的。如果一旦出现安全问题,不仅会造成巨大的经济损失,而且直接威胁到煤炭工人的生命安全。近年来,我国煤炭开采的安全问题形势不容乐观,各地矿难时有发生,特别是一些小煤矿更存在着严重的安全隐患。所以,采取现...
6地举办发布会,并且即将搬到CES的现场——是德科技日前推出的雷达场景仿真器获得了如此高规格的待遇。雷达场景仿真器为何受到公司及客户的一致认可?日前,是德科技汽车与新能源事业部大中华区业务拓展经理祝晓悦以及是德科技汽车与新能源事业部大中华区业务经理马健锐进行了详细解读。汽车自动驾驶技术的普及离不开测试技术目前汽车市场正在朝向电动化、...

史海拾趣

问答坊 | AI 解惑

edacn究竟怎么了?

这个大二经常上的网址,前一段时间是一直维护中,现在出现的是域名无法解析,有谁知道原因吗? 很好的一个网站啊…

查看全部问答∨

随着时间的推移我们都要毕业了

时间真的是很快!我很无奈!但又能怎么样呢?一切的一切都要真实的面对! 祝福我自己吧!…

查看全部问答∨

关于wince hive-based registry的疑问

我的wince5.0和4.2,\"Start DevMgr\"=0都是一样,5.0的hive可以永久保存,4.2却不行,5.0和4.2的 PB doc都说要把\"Start   DevMgr\"=1才能永久保存,但我的5.0设为0也能永久保存,感觉很奇怪。 还有一个问题,很严重,我邻居家的两条大 ...…

查看全部问答∨

DMA branch有什么用

我目前为止还想不到它的具体用途  那为什么要有这个branch功能呢…

查看全部问答∨

关于一帧图像显示的问题 急~~在线等

我用摄像头获得了一帧图像的数据,存储在一个unsigned char*型的缓冲区中,请问如何才能将这帧图像显示到picture control控件上啊?我指的不是一个bmp文件,而是一块缓冲区中的图像数据。而且处理时不要存成文件。 请教大家了!请不吝赐教!在线等 ...…

查看全部问答∨

VS2005创建WinCE5.0的SDI程序CommandBar帮助和关闭按钮不可用,Why?

const DWORD dwAdornmentFlags = CMDBAR_HELP | CMDBAR_OK; m_wndCommandBar.AddAdornments(dwAdornmentFlags); 只有OK键可用,请指教!…

查看全部问答∨

【视频分享】TMS320C64x+网络课程5——多极高速缓冲存储器

TMS320C64x+网络课程5——多极高速缓冲存储器,包cache的概念,cache miss的一些类型以及关于cache的使用优化。此网络培训针对C64x+,每次一个专题,由DSP高性能部门技术支持工程师为您全程指导,敬请期待。     $(\'swf_yTJ\').inne ...…

查看全部问答∨

djyos主页全新改版

欢迎各位大驾光临 www.djyos.com [ 本帖最后由 djyos 于 2012-8-20 10:24 编辑 ]…

查看全部问答∨

MOS管的栅极充电电流

如图所示,在半桥驱动的高端驱动中,从源极接出来的10K电阻接地,是否会减小栅极的充电电流?…

查看全部问答∨

CAN总线的电路设计

看了一些资料,貌似用PCA82C250芯片的CAN总线电路都是加了光耦隔离,但是我看TI开发板上用SN65HVD1050D芯片,电路中没有加光耦隔离。想问问是因为芯片的原因,还是说TI开发板就没有管光耦隔离这回事?…

查看全部问答∨
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved