主题 : 急求高手 版主来帮个忙 是关于timer0中断的 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 21289
精华: 0
发帖: 6
金钱: 30 两
威望: 6 点
综合积分: 12 分
注册时间: 2010-05-14
最后登录: 2010-09-14
楼主  发表于: 2010-06-10 18:12

 急求高手 版主来帮个忙 是关于timer0中断的

管理提醒: 本帖被 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寄存器的值 可是这个程序不能实现,各位大侠救命啊