管理提醒: 本帖被 qq2440 从 micro2440技术交流专区 移动到本区(2013-11-18)
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#define DEVICE_NAME "shiyan"
int i=0;
static irqreturn_t timer0_intrrupt(int irq, void *dev_id)
{
i++;
}
/*static irqreturn_t shiyan_intrrupt(int irq, void *dev_id)
{
int srcpnd,intmsk,intpnd;
int ret;
ret = request_irq(IRQ_TIMER0,TIMER0_intrrupt,IRQ_TYPE_EDGE_BOTH,DEVICE_NAME,NULL);
if(i==0)
{
tcon = __raw_readl(S3C2410_TCON);
tcon &= ~(0x7);
tcon |= 0x7;
__raw_writel(tcon,S3C2410_TCON);
if(ret < 0)printk("the irq_timer0 is not request! \n");
i=1;
srcpnd = __raw_readl(S3C2410_SRCPND);
srcpnd &= ~(1<<5);
__raw_writel(srcpnd,S3C2410_SRCPND);
intmsk = __raw_readl(S3C2410_INTMSK);
intmsk &= ~(1<<5);
__raw_writel(intmsk,S3C2410_INTMSK);
intpnd = __raw_readl(S3C2410_INTPND);
intpnd &= ~(1<<5);
__raw_writel(intpnd,S3C2410_INTPND);
}
else if(i==1)
{
tcon = __raw_readl(S3C2410_TCON);
tcon &= ~(0x7);
__raw_writel(tcon,S3C2410_TCON);
free_irq();
i=0;
srcpnd = __raw_readl(S3C2410_SRCPND);
srcpnd &= ~(1<<5);
__raw_writel(srcpnd,S3C2410_SRCPND);
intmsk = __raw_readl(S3C2410_INTMSK);
intmsk &= ~(1<<5);
__raw_writel(intmsk,S3C2410_INTMSK);
intpnd = __raw_readl(S3C2410_INTPND);
intpnd &= ~(1<<5);
__raw_writel(intpnd,S3C2410_INTPND);
}
}*/
static int shiyan_open(struct inode *inode, struct file *file)
{
//以下的三个寄存器是所有中断都要设置的
int srcpnd,intmsk,intpnd;
int tcfg0,tcfg1,tcntb0,tcntmb0,tcon,clkcon;
int ret;
srcpnd = __raw_readl(S3C2410_SRCPND);
srcpnd &= ~((1<<5)|(1<<10)); //(1<<10)代表的是TIMER0的标志位
__raw_writel(srcpnd,S3C2410_SRCPND);
intmsk = __raw_readl(S3C2410_INTMSK);
intmsk &= ~((1<<5)|(1<<10));
__raw_writel(intmsk,S3C2410_INTMSK);
intpnd = __raw_readl(S3C2410_INTPND);
intpnd &= ~((1<<5)|(1<<10));
__raw_writel(intpnd,S3C2410_INTPND);
//设置时间计时器TIMER0的相关寄存器
//有预分频TCFG0,分频TCFG1,计数器TCNTBx,和TCON
/* clkcon = __raw_readl(S32410_CLKCON)
clkcon |= (1<<8);
__raw_writel(clkcon,S3C2410_CLKCON);*/
tcntb0 = __raw_readl(S3C2410_TCNTB(0));
tcntb0 |= 0x3000;
__raw_writel(tcntb0,S3C2410_TCNTB(0));
tcfg0 = __raw_readl(S3C2410_TCFG0);
tcfg0 &= ~(0xff);
tcfg0 |=0x31;
__raw_writel(tcfg0,S3C2410_TCFG0);
tcfg1 = __raw_readl(S3C2410_TCFG1);
tcfg1 &= ~0xff;
__raw_writel(tcfg1,S3C2410_TCFG1);
//以下寄存器是外部中断的寄存器
//在申请的函数中的第三个参数设置时双沿触发S3C2410_EXTINT_BOTHEDGE
// ret = request_irq(IRQ_EINT13,shiyan_intrrupt,IRQ_TYPE_EDGE_BOTH,DEVICE_NAME,NULL);
//发出一个10us的脉冲 开启超声波模块
/* s3c2410_gpio_setpin(S3C2410_GPF(3),1);
usleep(10);
s3c2410_gpio_setpin(S3C2410_GPF(3),0);*/
tcon = __raw_readl(S3C2410_TCON);
tcon &= (~0xf) |0x02; // 0010
tcon |= (~0xf) |0x09; // 1001 1011
__raw_writel(tcon,S3C2410_TCON);
ret = request_irq(IRQ_TIMER0,timer0_intrrupt,IRQF_DISABLED,DEVICE_NAME,NULL);
if(ret<0)
printk("the dev is failure!\n");
while(1)
{
tcntb0 = __raw_readl(S3C2410_TCNTB(0));
// if(tcntb0 == 0)
// {
printk("the number is %d i is %d \n",tcntb0,i);
// break;
// }
}
free_irq(IRQ_TIMER0,NULL);
}
static int shiyan_close(struct inode *inode,struct file *file)
{
free_irq(IRQ_EINT13, NULL);
}
static struct file_operations shiyan_fops = {
.owner = THIS_MODULE,
.open = shiyan_open,
.release = shiyan_close,
// .read = shiyan_read,
//.poll = eint_led_poll,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &shiyan_fops,
};
static int __init shiyan_init(void)
{
int ret;
s3c2410_gpio_cfgpin(S3C2410_GPF(3),S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPG(5),2);
s3c2410_gpio_setpin(S3C2410_GPF(3),0);
s3c2410_gpio_setpin(S3C2410_GPG(5),0);
ret = misc_register(&misc);
if(ret<0)printk("the eint_led is insmod failure!n");
else
printk("the eint_led is insmod success!\n");
return ret;
}
static void __exit shiyan_exit(void)
{
misc_deregister(&misc);
}
module_init(shiyan_init);
module_exit(shiyan_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
我的这个程序运行起来后 TCNTB(0)这个寄存器的值是不变的 而且用ctrl+C也不能退出 ,必须要重启板子才可以
我真的很着急,希望版主能尽快的给我个建议
我就是想用timer0 来测量一个高电平的时间 高电平接在一个外部中断上 上升沿是打开timer0中断 下降沿关闭timer0中断
然后读出TCNTB寄存器的值 可是这个程序不能实现,各位大侠救命啊