linux驱动之定时器,linux驱动之PWM(定时器)

说明:以下由两部分组成,定时器驱动、定时器应用程序构成;

1.驱动程序;

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME "CL_beep"

#define BEEP_MAJOR 233

static int CL_beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

unsigned long temp;

unsigned long gpbcon;

unsigned long tcfg0;

unsigned long tcfg1;

unsigned long tcntb;

unsigned long tcmpb;

unsigned long tcon;

struct clk *clk_p;

unsigned long pclk;

printk("Kernel info: cmd=%d....\n", cmd);

if (cmd <= 0) {

temp = __raw_readl(S3C2410_GPBCON);

temp &= ~3;

temp |= 1; /*管脚功能定义为-输出*/

__raw_writel(temp, S3C2410_GPBCON);

temp = __raw_readl(S3C2410_GPBDAT);

temp &= ~1;

__raw_writel(temp, S3C2410_GPBDAT);

} else {

gpbcon = __raw_readl(S3C2410_GPBCON);

gpbcon &= ~3;

gpbcon |= 2; /*管脚功能定义为-定时器*/

__raw_writel(gpbcon, S3C2410_GPBCON);

/*定时器输入时钟频率=PCLK/(预分频值+1)/(分频值)

=PCLK/(15+1)/(1/8) */

tcfg0 = __raw_readl(S3C2410_TCFG0);

tcfg0 &= ~0xff;

tcfg0 |= 15; /*定时器预分频值为15*/

__raw_writel(tcfg0, S3C2410_TCFG0);

tcfg1 = __raw_readl(S3C2410_TCFG1);

tcfg1 &= ~0xf;

tcfg1 |= 2; /*定时器分频值为2,即1/8分频*/

__raw_writel(tcfg1, S3C2410_TCFG1);

clk_p = clk_get(NULL, "pclk");

pclk = clk_get_rate(clk_p);

printk("Kernel info: pclk=%d\n", pclk);

if (arg == 0)

arg = 1;

tcntb = (pclk/128)/arg; /*定时器计数缓冲寄存器*/

__raw_writel(tcntb, S3C2410_TCNTB(0));

printk("Kernel info: tcntb=%d\n", tcntb);

tcmpb = tcntb>>1; /*定时器比较缓冲寄存器*/

__raw_writel(tcmpb, S3C2410_TCMPB(0));

printk("Kernel info: tcmpb=%d\n", tcmpb);

tcon = __raw_readl(S3C2410_TCON);

tcon &= ~0x1f;

tcon |= 0x0b;

__raw_writel(tcon, S3C2410_TCON);

tcon &= ~2; /*这里比较特殊,此为必须在下次写操作时清零!*/

__raw_writel(tcon, S3C2410_TCON);

}

return 0;

}

static struct file_operations CL_beep_fops = {

.owner = THIS_MODULE,

.ioctl = CL_beep_ioctl,

};

static struct class *beep_class;

static int __init CL_beep_init(void)

{

int ret;

/*注册字符设备驱动程序*/

ret = register_chrdev(BEEP_MAJOR, DEVICE_NAME, &CL_beep_fops);

if (ret) {

printk(DEVICE_NAME" can`t register major number.\n");

return ret;

}

/*注册一个类,使mdev可以在/dev目录下创建设备节点*/

beep_class = class_create(THIS_MODULE, DEVICE_NAME);

if (IS_ERR(beep_class)) {

printk("Err: create class failed.\n");

return -1;

}

/*创建一个设备节点,节点名为DEVICE_NAME*/

device_create(beep_class, NULL, MKDEV(BEEP_MAJOR, 0), NULL, DEVICE_NAME);

printk(DEVICE_NAME" initialized.\n");

return 0;

}

static void __exit CL_beep_exit(void)

{

unregister_chrdev(BEEP_MAJOR, DEVICE_NAME);

printk(DEVICE_NAME" exit!\n");

}

module_init(CL_beep_init);

module_exit(CL_beep_exit);

MODULE_AUTHOR("Cl learning...");

MODULE_DESCRIPTION("[2016-02-22] Cl Time0 for PWM test");

MODULE_LICENSE("GPL");

2.应用程序;

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME "/dev/CL_beep"

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

{

int fd;

int i;

int cmd = 1;

unsigned long temp = 0;

fd = open(DEVICE_NAME, O_RDWR);

if (fd < 0){

perror("open fail:");

exit(1);

}

while(1){

scanf("%d", &temp);

printf("temp = %d\n", temp);

ioctl(fd, cmd, temp);

if (temp == 0)

break;

}

close(fd);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值