S3C2440步进电机驱动中用定时器0实现1ms延时,现在延时可以实现,输出波形也比较满意,但是问题是定时器中断过大概40m就停止了
超级终端上提示:Disabling IRQ #26 禁止了定时器中断,不知掉怎么回事?纠结蛋疼中!!!!!!!
程序如下
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <asm/system.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/arch/irqs.h>
#include <asm/arch/s3c2440.h>
#include <asm/arch/regs-gpio.h>
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/arch/regs-irq.h>
#include <linux/interrupt.h>
#include <linux/regs-timer.h>
#define DEVICE_NAME "mytimer"
#define CB_MAJOR 250
MODULE_AUTHOR("0354030w");
MODULE_DESCRIPTION("S3C2440 MOTO Driver");
MODULE_LICENSE("GPL");
/*
#define TCON=(*(volatile unsigned int *)0x51000008)
#define TCNTB0=(*(volatile unsigned int *)0x5100000c)
#define TCMPB0=(*(volatile unsigned int *)0x51000010)
#define MPLLCON=(*(volatile unsigned int *)0x4C000004)
#define CLKDIVN= (*(volatile unsigned int *)0x4C000014)
*/
static bool found=0;
static unsigned char m_step[8]={0xef,0xef,0xdf,0xdf,0xbf,0xbf,0x7f,0x7f};
static unsigned int flag=0;
static int flag_1=7;
static unsigned long arg_1,GPFCON,GPFDAT;
static unsigned int cmd_1;
static unsigned long tmp;
void initial_timer(void)
{
printk("time init is on!");
unsigned long Ftclk; //s3c2440a的默认Fpclk为50MHz
iowrite32(0,S3C2410_TCFG0); //设置预分频
iowrite32(0,S3C2410_TCFG1); //设置分频和模式
Ftclk=12500; //计数值 实现1ms延时
iowrite16(Ftclk,S3C2410_TCNTB(0)); //写入定时初值
iowrite16(0,S3C2410_TCMPB(0)); //写入终点比较值
tmp=(ioread32(S3C2410_TCON)&(~0x0f))|2;
iowrite32(tmp,S3C2410_TCON); //手动刷新一次,将数据装入TCNT和TCMP
tmp=(ioread32(S3C2410_TCON)&(~0x0f))|9;
iowrite32(tmp,S3C2410_TCON); //设置自动装载初值,开始计数
}
//以下几个接口都是空壳
static ssize_t timer_open(struct inode *inode,struct file *file)
{
printk("timer_open in!");
printk("found=%d",found);
GPFCON=(unsigned long)ioremap(0x56000050,4);
GPFDAT=(unsigned long)ioremap(0x56000054,4);
GPFCON |=0x5500;
return 0;
}
static ssize_t timer_ioctl(struct inode *inode, struct file *file ,unsigned int cmd, unsigned long arg)
{
found=1;
cmd_1=cmd;
arg_1=arg;
return 0;
}
//发生中断时执行此函数
static void timer_irq(int irq,void *dev_id,struct pt_regs *reg)
{
// printk("into the ISR\n");
if(irq==IRQ_TIMER0)
{ //printk("time out irq%d",irq);
if(found==1)
{
if(arg_1==1)
{
(*(volatile unsigned long *)GPFDAT) =m_step[flag++];
if(flag>7)flag=0;
}
else
{
(*(volatile unsigned long *)GPFDAT) =m_step[flag_1--];
if(flag_1<0)flag_1=7;
}
}
}
}
static struct file_operations timer_fops={
.owner= THIS_MODULE,
.ioctl =timer_ioctl,
.open = timer_open,
};
//整个驱动的初始化入口
static int __init timer_init(void)
{
int ret;
ret=register_chrdev(CB_MAJOR,DEVICE_NAME,&timer_fops);
initial_timer();
printk("after initial_timer()\n");
if(ret<0)
{
printk(DEVICE_NAME" can't register major number\n");
return ret;
}
//关联中断和中断函数
if(request_irq(IRQ_TIMER0,(void *)&timer_irq,SA_INTERRUPT,DEVICE_NAME,NULL))
{
printk(DEVICE_NAME "can't request irqs\n");
return -1;
}
return 0;
}
static void __exit timer_exit(void)
{ found=0;
free_irq(IRQ_TIMER0,NULL);
unregister_chrdev(CB_MAJOR, DEVICE_NAME);
}
module_init(timer_init);
module_exit(timer_exit);
希望大家指教!