⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1820drv.c.bak

📁 基于linux2.4内核下,外接于AT91RM9200处理器IO上的DS18B20驱动及测试程序。硬件平台为:中嵌科技的CE9200-1开发板
💻 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 + -