tq2440 pwm 驱动

转载 2016年05月30日 15:43:25
基于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

TQ2440的PWM控制器的驱动编写

PWM驱动程序设计(内核2.6.30.4)   原文出自http://blog.chinaunix.net/uid-25577798-id-1761435.html 下面是以TQ2440开发板为基础...

TQ2440使用定时器产生PWM,控制蜂鸣器发声

GPBCON:引脚配置寄存器 GPBUP:端口使能上拉寄存器                               GPBDAT:端口数据寄存器 TCFG0:配置两个8位预分频器 TCF...

TQ2440上的PWM实验

PWM(Pulse Width Modulation)——脉宽调制,它是利用微控制器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量、通信、功率控制与变换等许多领域。 s3c244...

TQ2440上的PWM实验(裸机)

原文:http://m.blog.csdn.net/blog/huangzhirong19893311/6867485 PWM(Pulse Width Modulation)——脉宽调制,它是利用微...

TQ2440PWM蜂鸣器的运用

S3C2440中有5个16位定时器,timer0,timer1,timer2,timer3和timer4。其中,只有timer4是一个没有输出引脚的内部定时器。所以,只有定时器0,1,2,3有脉宽调制...

TQ2440定时器之PWM

本节主要涉及到S3C2440的定时器         概述:S3C2440有5个定时器,其中定时器0、1、2、3具有脉冲宽度调制(PWM),定时器4无输出引脚,定时器0具备死区输出功能。定时器0、1共...

TQ2440的64位串口驱动

  • 2014年04月17日 10:54
  • 1.93MB
  • 下载

按键驱动 基于tq2440改进

  • 2013年01月05日 17:21
  • 4KB
  • 下载

TQ2440简单的按键驱动程序

#include #include #include #include #include #include #include #include #include #...

tq2440 input 按键驱动

  • 2013年04月23日 21:03
  • 20KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:tq2440 pwm 驱动
举报原因:
原因补充:

(最多只允许输入30个字)