tq2440 pwm 驱动

xiaoxiao2021-02-28  133

/************************************************************* 基于tq2440开发板,内核2.6.30 功能 神奇了,加了几条打印语句后蜂鸣器就叫了。 估计是tcon 的写入速度比较慢吧,需要点延时。 真心伤不起啊 还有就是不知道为什么tcon  寄存器值的输出好像不对劲 这个pwm 设置其实和其他的单片机也差不多, 只不过多了个死区的概念,就是防止电器驱动时候的开关同时开启 当tcnt 和tcnp 的相等时候电平反转。 tcnt 为递减计数器 为什么出现奇怪数据的原因 是寄存器没有清零, 虽然它默认是0 但是当你错误操作,板子没有重启, 可能那寄存器的值就改变了。 没有测过时间,闲麻烦,而且蜂鸣器的接口好像没有外接。算了 。将就了。 没有写成定时器中断的原因是中断函数找不到啊,咋写。。。。 2012年7月10日22:16:37 **************************************************************/ #include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <linux/poll.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/clk.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #include <plat/regs-timer.h> #define DEVICE_NAME "driver_pwm" //gpb0 tout0 // volatile unsigned long *gpbcon = NULL; volatile unsigned long *gpbdat = NULL; volatile unsigned long *tcfg0 = NULL; //用来设置预分频 volatile unsigned long *tcfg1 = NULL; //用来设置分频 volatile unsigned long *tcon  = NULL; //定时器控制器 volatile unsigned long *tcntb0 = NULL; //计数缓冲寄存器 volatile unsigned long *tcmpb0 = NULL; //比较缓冲寄存器 volatile unsigned long *tcnto0 = NULL; //计数观察寄存器 //*gpbdat &= ~((1<<5) ); // ------------------- OPEN ------------------------ ssize_t drive_open (struct inode * inode ,struct file * file) { *gpbcon &=~(3<<0*2); *gpbcon |= (2<<0*2); //设置b0 为 tout0 //*gpbcon &= ~( (3<<0*2)|(3<<5*2) ); //*gpbcon |= (1<<0*2)|(1<<5*2); printk("-----------------drive open ok----------------\n"); return 0; } // ------------------- RELEASE/CLOSE --------------- ssize_t drive_release (struct inode  * inode ,struct file * file) { printk("-----------------drive close ok----------------\n"); return 0; } // ------------------- READ ------------------------ ssize_t drive_read (struct file * file ,char * buf, size_t count, loff_t * f_ops) { printk("-----------------drive read ok----------------\n"); //copy_to_user( buf,(const void *)press_cnt,sizeof(press_cnt) ); return 0; } // ------------------- WRITE ----------------------- ssize_t drive_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops) { printk("-----------------drive write ok----------------\n"); return 0; } // ------------------- IOCTL ----------------------- ssize_t drive_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, unsigned long arg) { struct clk *clk_p;        unsigned long pclk; unsigned long tcnt; printk("-----------------drive ioctl ok----------------\n"); //if(cmd==0) // return 0; //定时器时钟频率=pclk /( 预分频器的值+1) / 分频器 //62.5k *tcfg0 &= ~0xff; //定时器0预分配清零 *tcfg0 |=(50-1); //预分频 50 *tcfg1 &= ~0xf; //定时器0 mux 输入分频清零 *tcfg1 |=3; //mux 分频 16  clk_p = clk_get(NULL, "pclk");          pclk = clk_get_rate(clk_p); tcnt = (pclk/50/16)/10;   printk("pclk =  %d\n",pclk); printk("tcnt =  %d\n",tcnt); *tcntb0 &=0x0000; //16位寄存器 *tcmpb0 &=0x0000; *tcntb0 |= 1000; *tcmpb0|=500; //*tcon &=0x0; // printk("tcon=%d\n",*tcon); printk("tcntb0=%d\n",*tcntb0);  printk("tcmpb0=%d\n",*tcmpb0);   *tcon &= ~0x1f; //清零 // printk("tcon=%d\n",*tcon); msleep(10); //第一次必须手动更新        *tcon |= 0xb;  //关闭死区、自动重载、关反相器、手动更新TCNTB0&TCMPB0、启动定时器0 //1011 //printk("tcon=%d\n",*tcon); msleep(10);  *tcon &= ~2;  //清除定时器0的手动更新位   //printk("tcon=%d\n",*tcon);  printk("tcfg0=%d\n",*tcfg0);  printk("tcfg1=%d\n",*tcfg1);  printk("tcntb0=%d\n",*tcntb0);  printk("tcmpb0=%d\n",*tcmpb0);  printk("tcon=%d\n",*tcon);   //----------------------------------------------------- /* pclk =  50000000 tcnt =  6250 tcon=5242889 tcfg0=561 tcfg1=3 tcntb0=7295 tcmpb0=7295 tcon=5242889 pclk =  50000000 tcnt =  6250 tcntb0=8191 tcmpb0=7679 tcfg0=561 tcfg1=3 tcntb0=8191 tcmpb0=7679 tcon=5242889 *gpbdat |= 1<<0; *gpbdat |= 1<<5; msleep(500); *gpbdat &= ~(1<<0); *gpbdat &= ~(1<<5); */ //----------------------------------------------------- //msleep(500); return 0; } // ------------------------------------------------- static struct file_operations drive_ops ={ .owner  = THIS_MODULE, .open   = drive_open, .read    = drive_read, .write   = drive_write, .ioctl    = drive_ioctl, .release = drive_release, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &drive_ops, }; static int __init init_drive(void)   { int ret; ret = misc_register(&misc); gpbcon = (volatile unsigned long *)ioremap(0x56000010,32); gpbdat = (volatile unsigned long *)ioremap(0x56000014, 32); tcfg0    = (volatile unsigned long *)ioremap(0x51000000, 4); tcfg1    = (volatile unsigned long *)ioremap(0x51000004, 4); tcon     = (volatile unsigned long *)ioremap(0x51000008, 4); tcntb0  = (volatile unsigned long *)ioremap(0x5100000c, 4); tcmpb0 = (volatile unsigned long *)ioremap(0x51000010, 4); tcnto0  = (volatile unsigned long *)ioremap(0x51000014, 4); printk("-----------------drive button init ok----------------\n"); return 0; } static void __exit exit_drive(void) { *tcon &=~1; misc_deregister(&misc); printk("-----------------drive button exit ok----------------\n"); } module_init(init_drive); module_exit(exit_drive); MODULE_LICENSE("GPL"); //--------------------------------------应用测试程序---------------------------------------------------- #include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h>      // open() close() #include <unistd.h>     // read() write() #define DEVICE_NAME "/dev/driver_pwm" //------------------------------------- main --------------------------------------------- int main(int argc, char **argv) { int fd,ret;        fd = open(DEVICE_NAME, O_RDWR);   if (fd == -1) { printf("can't open device mknod %s c zhu ci \n",DEVICE_NAME); return 0; } ioctl(fd, 1); while(1) { ; }         // close  ret = close(fd);         return 0; }// end main
转载请注明原文地址: https://www.6miu.com/read-62526.html

最新回复(0)