Chinaunix首页 | 论坛 | 博客
  • 博客访问: 686311
  • 博文数量: 152
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1793
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 12:26
个人简介

相信自己,只有不想做的,没有做不到的。

文章分类

全部博文(152)

文章存档

2021年(1)

2015年(2)

2014年(74)

2013年(75)

分类: LINUX

2013-12-12 13:26:16

//在s5pc100_pwm.c
#include  
#include
#include
#include
#include

#include

#include

#include

#include "s5pc100_pwm.h"

MODULE_LICENSE("Dual BSD/GPL");
static int pwm_major = 500;
static int pwm_minor = 0;
static struct cdev pwm_cdev;
static int cnt_def = 300;


static void beep_init(void) //蜂鸣器初始化
{
writel((readl(S5PC100_GPD_BASE) & (~0xF << 4)) | (0x2 << 4), S5PC100_GPD_BASE);
writel(readl(S3C2410_TCFG0) & ~0xff, S3C2410_TCFG0);
writel((readl(S3C2410_TCFG1) & ~(0xf << 4)) | (0x1 << 4), S3C2410_TCFG1);
writel(cnt_def, S3C2410_TCNTB(1));
writel(cnt_def/2, S3C2410_TCMPB(1));
writel((readl(S3C2410_TCON) & ~(0xf << 8)) | (0xa << 8), S3C2410_TCON);
}


static void beep_on(void) //蜂鸣器开
{
writel((readl(S3C2410_TCON) & ~(0xf << 8)) | (0x9 << 8), S3C2410_TCON);
}


static void beep_off(void)//蜂鸣器关闭
{
writel((readl(S3C2410_TCON) & ~(0xf << 8)), S3C2410_TCON);
}


static void set_cnt(unsigned long arg)
{
beep_off();
writel(arg, S3C2410_TCNTB(1));
writel(arg/2, S3C2410_TCMPB(1));
beep_on();
}


static void set_pre(unsigned long arg)
{
beep_off();
writel((readl(S3C2410_TCFG0) & ~0xff) | (arg & 0xff), S3C2410_TCFG0);
beep_on();
}


static int s5pc100_pwm_open(struct inode *inode, struct file *file)
{
printk("pwm: device open\n");
beep_init(); 
return 0;
}


static int s5pc100_pwm_close(struct inode *inode, struct file *file)
{
printk("pwm: device close\n");
beep_off();
return 0;
}

//根据应用程序传递的ioctl的参数cmd,arg来做对于的动作
static int s5pc100_pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
printk("pwm: device ioctl\n");
switch(cmd)
{
case BEEP_ON:
printk("pwm: BEEP ON\n");
beep_on();
break;
case BEEP_OFF:
printk("pwm: BEEP OFF\n");
beep_off();
break;
case SET_CNT:
printk("pwm: SET CNT\n");
set_cnt(arg);
break;
case SET_PRE:
printk("pwm: SET PRE\n");
set_pre(arg);
break;
default:
printk("pwm: available command\n");
break;
}
return 0;
}
//对字符设备操作的函数open close write read ioctl
static struct file_operations s5pc100_pwm_ops = {
.owner = THIS_MODULE,
.open = s5pc100_pwm_open,
.release = s5pc100_pwm_close,
.ioctl = s5pc100_pwm_ioctl
};

static int pwm_setup_cdev(struct cdev *cdev, 
struct file_operations *fops)
{
int result;
dev_t devno = MKDEV(pwm_major, pwm_minor);
cdev_init(cdev, fops);  //字符设备初始化  获得fops
cdev->owner = THIS_MODULE;
result = cdev_add(cdev, devno, 1); //添加字符设备
if(result)
{
printk("pwm: cdev add faipwm\n");
return result;
}
return 0;
}

//入口函数初始化
static int __init s5pc100_pwm_init(void)
{
int result;
dev_t devno = MKDEV(pwm_major, pwm_minor); //通过主次设备号来获得字符设备号
result = register_chrdev_region(devno, 1, "s5pc100_pwm"); //注册设备号
if(result)
{
printk("pwm: unable to get major %d\n", pwm_major);
return result;
}

result = pwm_setup_cdev(&pwm_cdev, &s5pc100_pwm_ops); //设备初始化函数
if(result)
return result;
printk("pwm: driver instalpwm, with major %d!\n", pwm_major);
return 0;
}

static void __exit s5pc100_pwm_exit(void)
{
dev_t devno = MKDEV(pwm_major, pwm_minor);
cdev_del(&pwm_cdev);
unregister_chrdev_region(devno, 1);
printk("pwm: driver uninstalpwm!\n");
}
//入口函数,出口函数
module_init(s5pc100_pwm_init);
module_exit(s5pc100_pwm_exit);

在s5pc100_pwm.h中
#ifndef __S5PC100_PWM_H
#define __S5PC100_PWM_H

#define BEEP_ON  _IO('k', 0)
#define BEEP_OFF _IO('k', 1)
#define SET_CNT  _IO('k', 2)
#define SET_PRE  _IO('k', 3)

#endif

//在你测试程序test.c中
#include
#include
#include
#include
#include
#include
#include
#include


#include "s5pc100_pwm.h"


int main()
{
int i = 0;
int n = 2;
int dev_fd;
dev_fd = open("/dev/dota_beep",O_RDWR | O_NONBLOCK);
if ( dev_fd == -1 ) {
perror("open");
exit(1);
}
//每隔一秒开,每隔一秒关。
while(1)
{
ioctl(dev_fd,BEEP_ON,0);
sleep(1);
ioctl(dev_fd,BEEP_OFF,0);
sleep(1);
}
return 0;
}

//以上就是一个简单pwm蜂鸣器的驱动


阅读(913) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~