📄 ds1820drv.c.bak
字号:
/*****************************************************************************
;Institue of Automation, Chinese Academy of Sciences
;www.emsyschina.com
;File Name: DS1820驱动程序
;
;Description: 读取DS18B20温度
;Date: 2007-11-30
;Author: 王亮
;E_mail: wangl@emsyschina.com
*****************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/AT91RM9200_SYS.h>
#include <asm/arch/hardware.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/devfs_fs_kernel.h>
// 定义模块名
char DS1820_name[]="DS1820";
// 指定主设备号
static int major = 0;
//*********************************************************
//函数定义;
//*********************************************************
static int DS1820_release(struct inode * inode,struct file * filp);
static int DS1820_open(struct inode * s_node,struct file * s_file);
ssize_t DS1820_read(struct file *DS1820_file, const char * buf, size_t count, loff_t * l);
//**********************************************************
// 大延迟程序(1us级)
//**********************************************************
void delay_us(unsigned int time)
{
unsigned int i;
while(time--)
{
i=44;
while(--i);
}
}
//*********************************************************
//文件操作结构体;
//*********************************************************
static struct file_operations DS1820_fops=
{
release: (void(*))DS1820_release,
open : (void(*))DS1820_open,
read : (void(*))DS1820_read,
};
//*********************************************************
//初始化模块函数;
//*********************************************************
static devfs_handle_t devfs_handle;
static int __init DS1820drv_init_module(void)
{
int ret;
// 注册模块;
if ((ret=devfs_register_chrdev(major,DS1820_name,&DS1820_fops)) < 0)
{
printk("\r\n<1>Register Fail!\r\n");
return ret;
}
// 动态分配主设备号;
if(major == 0)
major = ret;
// 建立设备文件;
devfs_handle = devfs_register(NULL, DS1820_name ,DEVFS_FL_DEFAULT,
major, 0, S_IFCHR | S_IRUSR | S_IWUSR,&DS1820_fops, NULL);
printk("<1>DS1820 device OK!\n");
return 0;
}
//*********************************************************
//清除模块函数;
//*********************************************************
static void __exit DS1820drv_cleanup(void)
{
int retv;
// 注销模块
retv=devfs_unregister_chrdev(major,DS1820_name);
if(retv<0)
{
printk("<1>UnRegister Fail!\n");
return;
}
MOD_DEC_USE_COUNT;
printk("<1>DS1820DRV:GOOD-bye!\n");
}
//*********************************************************
//DS18B20 open 函数;
//*********************************************************
static int DS1820_open(struct inode * s_node,struct file * s_file)
{
// 设定PC14为输出
// PIO Enable Register
AT91_SYS->PIOC_PER |= (1<<14);
// PIO Output Enable Register
AT91_SYS->PIOC_OER |= (1<<14);
// PIO Output Write Register
AT91_SYS->PIOC_OWER |= (1<<14);
// PC14 enable Pull up;
AT91_SYS->PIOC_PPUER |= (1<<14);
// enable PIOC clock
AT91_SYS->PMC_PCER = 0x1<< AT91C_ID_PIOC;
MOD_INC_USE_COUNT;
return 0;
}
//*********************************************************
//DS18B20 release 函数 :
//*********************************************************
int DS1820_release(struct inode * inode,struct file * filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
//*********************************************************
//DS18B20 reset 函数 :
//*********************************************************
void reset(void)
{
// int a = 0;
// PIO Output Enable Register
AT91_SYS->PIOC_OER |= (1<<14);
AT91_SYS->PIOC_CODR |= (1<<14);
delay_us(500); //480us以上
// 设定PC14为输入
// PC14 enable input;
AT91_SYS->PIOC_ODR |= (1<<14);
delay_us(25); //15~60us
/*
a = AT91_SYS->PIOC_PDSR;
while((a & 0x4000) == 0x4000)
a = AT91_SYS->PIOC_PDSR;
*/
delay_us(300); //60~240us
}
//*********************************************************
//DS18B20 write 函数 :
//*********************************************************
void write(unsigned char command)
{
unsigned char i;
// PIO Output Enable Register
AT91_SYS->PIOC_OER |= (1<<14);
for(i=0;i<8;i++)
{
AT91_SYS->PIOC_CODR |= (1<<14);
delay_us(5);
if(command & (1<<i)) //写数据,从低位开始
{
AT91_SYS->PIOC_SODR |= (1<<14);
}
else
{
AT91_SYS->PIOC_CODR |= (1<<14);
}
delay_us(80); //15~60us
AT91_SYS->PIOC_SODR |= (1<<14);
delay_us(10);
}
AT91_SYS->PIOC_SODR |= (1<<14);
delay_us(80);
}
//*********************************************************
//DS18B20 read 函数 :
//*********************************************************
unsigned int read(void)
{
unsigned char n;
int a = 0;
int Input_temp = 0;
for(n=0;n<8;n++)
{
// PIO Output Enable Register
AT91_SYS->PIOC_OER |= (1<<14);
AT91_SYS->PIOC_CODR |= (1<<14);
delay_us(3);
// 设定PC14为输入
// PC14 enable input;
AT91_SYS->PIOC_ODR |= (1<<14);
delay_us(5);
a = AT91_SYS->PIOC_PDSR & 0x4000; //读数据,从低位开始
if(a == 0x4000)
Input_temp |= (1<<n);
else
Input_temp &= ~(1<<n);
delay_us(50); //60~120us
}
delay_us(80);
return (Input_temp);
}
//*********************************************************
//DS18B20 read 函数;
//*********************************************************
ssize_t DS1820_read(struct file *DS1820_file, const char * buf, size_t count, loff_t * l)
{
union
{
unsigned char c[2];
signed short int x;
}temp;
reset();
write(0xCC);
write(0xBE);
temp.c[0] = read();
temp.c[1] = read();
reset();
write(0xCC);
write(0x44);
delay_us(1000);
temp.x *= 10;
temp.x +=8;
temp.x /=16;
// printk("kernel temp = %d.%d \n",temp.x/10,temp.x%10);
if(copy_to_user( buf, (char *)&temp.x, count))
return -EFAULT;
return count;
}
module_init(DS1820drv_init_module);
module_exit(DS1820drv_cleanup);
MODULE_AUTHOR("<wangl@emsyschina.com>");
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -