ok6410 PWM 驱动蜂鸣器

本文介绍了一个简单的S3C6410平台蜂鸣器驱动程序实现,通过配置定时器产生PWM信号来控制蜂鸣器的启停,并提供了相应的设备文件操作接口及应用程序示例。

驱动程序:

#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/fcntl.h>
#include<linux/cdev.h>
#include<linux/version.h>
#include<linux/ctype.h>
#include<linux/delay.h>
#include<linux/pagemap.h>
#include<linux/vmalloc.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/errno.h>


#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/gpio.h>
#include<asm/io.h>
#include<asm/irq.h>
#include<asm/signal.h>
#include<asm/uaccess.h>
#include<plat/regs-timer.h>
#include<plat/gpio-cfg.h>
#include<mach/gpio-bank-f.h>


#define simple_MAJOR 224
#define simple_MINOR 0


#define BEEP_S3C6410_ON 0
#define BEEP_S3C6410_OFF 1


#define PWM_TIMER1_AUTO_RELOAD (1<<11)
#define PWM_TIMER1_MANUAL_UPDATE (1<<9)
#define PWM_TIMER1_START (1<<8)


struct simple_dev
{
struct cdev cdev;
};


struct simple_dev *simple_devices;
static unsigned char simple_inc = 0;


static void startBeep(void)
{
unsigned long tcon,tcon1 , tcon2 , tcnt , pwm_PCLK , tcmp;
s3c_gpio_cfgpin(S3C64XX_GPF(15) , (0x2U<<30));//10 = PWM TOUT[1]
tcon = __raw_readl(S3C2410_TCON);
tcon |= PWM_TIMER1_AUTO_RELOAD|PWM_TIMER1_MANUAL_UPDATE;
__raw_writel(tcon , S3C2410_TCON);
printk("S3C2410_TCON %ld\n" , tcon);

tcon1 = __raw_readl(S3C2410_TCFG0);
printk("S3C2410_TCFG0 = %ld\n" , tcon1);
tcon1 |= 0x0000000F;
printk("S3C2410_TCFG0 = %ld\n" , tcon1);

tcon2 = __raw_readl(S3C2410_TCFG1);
printk("S3C2410_TCFG1 = %ld\n" , tcon2);
tcon2 |= 0x000000F0;
printk("S3C2410_TCFG1 = %ld\n" , tcon2);


pwm_PCLK = 66500000/(tcon1*tcon2);
printk("pwm_PCLK = %ld\n" , pwm_PCLK);

tcnt = pwm_PCLK/2000;
printk("tcnt is %ld\n" , tcnt);
tcmp = tcnt/3;
__raw_writel(tcnt , S3C2410_TCNTB(1));
__raw_writel(tcmp , S3C2410_TCMPB(1));

tcon = __raw_readl(S3C2410_TCON);
tcon |= PWM_TIMER1_START|PWM_TIMER1_AUTO_RELOAD;
__raw_writel(tcon , S3C2410_TCON);
}


static void stopBeep(void)
{
unsigned long tcon;
tcon = __raw_readl(S3C2410_TCON);
tcon &=~(PWM_TIMER1_AUTO_RELOAD);
tcon &=~(PWM_TIMER1_START);
__raw_writel(tcon , S3C2410_TCON);
printk("S3C2410_TCON = %ld\n" , tcon);
s3c_gpio_cfgpin(S3C64XX_GPF(15) , 0);
}


int simple_open(struct inode *inode , struct file *filp)
{
struct simple_dev *dev;
if(simple_inc > 0)
{
return -ERESTARTSYS;
}
simple_inc++;
dev = container_of(inode->i_cdev , struct simple_dev , cdev);
filp->private_data = dev;
return 0;
}


int simple_release(struct inode *inode , struct file *filp)
{
simple_inc--;
return 0;
}


static long simple_ioctl(struct file *filp , unsigned int cmd , unsigned long arg)
{
switch(cmd)
{
case BEEP_S3C6410_ON:
startBeep();
break;
case BEEP_S3C6410_OFF:
stopBeep();
break;
default:
break;
}
return 1;
}


struct file_operations simple_fops = {
.owner = THIS_MODULE,
.open = simple_open,
.release = simple_release,
.unlocked_ioctl = simple_ioctl,
};




void simple_cleanup_module(void)
{
dev_t devno = MKDEV(simple_MAJOR , simple_MINOR);
if(simple_devices)
{
cdev_del(&simple_devices->cdev);
kfree(simple_devices);
}
unregister_chrdev_region(devno , 1);
}


int simple_init_module(void)
{
int result;
dev_t dev = 0;
dev = MKDEV(simple_MAJOR , simple_MINOR);
result = register_chrdev_region(dev , 1 , "DEMO");
if(result < 0)
{
printk(KERN_WARNING"simle can't get major %d\n" , simple_MAJOR);
return result;
}
simple_devices = kmalloc(sizeof(struct simple_dev) , GFP_KERNEL);
if(!simple_devices)
{
result =  -ENOMEM;
goto fail;
}
memset(simple_devices , 0 , sizeof(struct simple_dev));
cdev_init(&simple_devices->cdev , &simple_fops);
simple_devices->cdev.owner = THIS_MODULE;
simple_devices->cdev.ops = &simple_fops;
result = cdev_add(&simple_devices->cdev , dev , 1);
if(result)
{
printk(KERN_NOTICE"Error %d adding DEMO\n" , result);
goto fail;
}
return 0;
fail:
simple_cleanup_module();
return result;
}


module_init(simple_init_module);
module_exit(simple_cleanup_module);


MODULE_LICENSE("Dual BSD/GPL");


应用程序:

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>


#define BEEP_ON 0
#define BEEP_OFF 1


int main(void)
{
int fd;
fd = open("/dev/wnb", O_RDWR);
if(fd < 0)
{
printf("can't open \n");
exit(0);
}
while(1)
{
ioctl(fd , BEEP_ON , 0);
sleep(1);
ioctl(fd , BEEP_OFF , 0);
}
close(fd);
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值