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

📄 sht11_driver.c

📁 自己写的SHT11驱动 CPU为AT9200
💻 C
字号:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <asm/irq.h>
#include <asm/arch/hardware.h>
//#include <asm/arch/irqs.h>
#include <linux/devfs_fs_kernel.h>
//#include <asm/arch/AT91RM9200_TWI.h>
#include <asm/arch/pio.h>

/////////////////////////////////

void sht_ack();
////////////////////////////////
#define IO_MAJOR 101     //
#define DEVICE_NAME "sht11_driver"
#define AT91C_BASE_PIOA   0xFFFFF400 // TWI PIOA Base Address
#define AT91C_BASE_PMC    0xFFFFFC00 // PMC
static void * pioa_base;
static void * pmc_base;
#define uchar unsigned char

unsigned char com_data,com_datal,com_datah;

int io_open(struct inode * inode, struct file * filp);
int io_release(struct inode * inode, struct file * filp);
ssize_t io_read(struct file * filp, char * buf, size_t count, loff_t * l);
ssize_t io_write(struct file * filp,const char *buf,size_t count,loff_t * l);
//static int io_ioctl(struct inode *inode,struct file * file,unsigned int cmd,unsigned long arg);
int io_ioctl(struct inode *inode,struct file * file,unsigned int cmd,unsigned long arg);
struct file_operations io_fops = {
	open:           io_open,
	ioctl:	       	io_ioctl,
	release:        io_release,
	read:           io_read,
	write:	        io_write,
};
void delay(int n)
{
 int i;
 for(i=0;i<n*1000;i++); 
}
void sht_start()
{
   int i;
   outl(0x02000000,pioa_base+0x14);       //sda=1
   delay(2);
   for(i=0;i<9;i++)
   {
      sht_ack();
   }
   outl(0x04000000,pioa_base+0x30);       //scl=1
   delay(2);
   outl(0x02000000,pioa_base+0x10);
   outl(0x02000000,pioa_base+0x34);       //sda=0
   delay(4);
   outl(0x04000000,pioa_base+0x34);       //scl=0
   delay(1); 
   
   outl(0x04000000,pioa_base+0x30);       //scl=1
   delay(2);  

   outl(0x02000000,pioa_base+0x14);       //sda=1
   delay(1);
   outl(0x04000000,pioa_base+0x34);
   delay(2);
}
////////////////////////////////////////////0x04000000是对scl写一个数,
//////////////////////0x02000000是对SDA写数,

void sht_ack()
{
   outl(0x04000000,pioa_base+0x34);       //scl=0
   delay(1);
   outl(0x04000000,pioa_base+0x30);       //scl=1
   delay(2);  
   outl(0x04000000,pioa_base+0x34);       //scl=0
   delay(1);
}   

void shift8(uchar a)  //8位移位输出
{
   unsigned char i;
   com_data=a;
   for(i=0;i<8;i++)
   {
   	  if((com_data&0x80)!=0)
   	  {
   	  outl(0x02000000,pioa_base+0x14);
          delay(2);
          outl(0x04000000,pioa_base+0x30);
          delay(1);
          outl(0x04000000,pioa_base+0x34);
          delay(1);
          com_data=com_data*2;
   	  }
   	  if((com_data&0x80)==0)
   	  {
          outl(0x02000000,pioa_base+0x10);
     	  outl(0x02000000,pioa_base+0x34);
          delay(2);   	  	
     	  outl(0x04000000,pioa_base+0x30);
          delay(2);
          outl(0x04000000,pioa_base+0x34);
          delay(1);
          com_data=com_data*2;   	  	
   	  }	

   }
}


int io_open(struct inode * inode, struct file * filp)
{
	MOD_INC_USE_COUNT;
	pioa_base=ioremap_nocache(AT91C_BASE_PIOA,0x100); 
	pmc_base =ioremap_nocache(AT91C_BASE_PMC,0x100);
        outl(0xffffffff,pmc_base+0x10);   
	outl(0x06000000,pioa_base);
//	outl(0xf9ffffff,pioa_base+0x04);  //25/26 out 
	outl(0x04000000,pioa_base+0x10);
        outl(0x02000000,pioa_base+0x14);
//	outl(0xf9ffffff,pioa_base+0x14);  //26 out 
//	outl(0x00000000,pioa_base+0x30);
//	outl(0xffffffff,pioa_base+0x34);  //25/26 out 
//	outl(0x00000000,pioa_base+0x40);
	outl(0xffffffff,pioa_base+0x44);  //25/26 out 
//	outl(0x00000000,pioa_base+0xA0);
	outl(0xffffffff,pioa_base+0xA4);  //25/26 out 
	
	return 0;
}
int io_release(struct inode * inode,struct file * filp)
{
  MOD_DEC_USE_COUNT;
	iounmap(pioa_base);      
	iounmap(pmc_base);
        return 0;
}

ssize_t io_read(struct file * filp, char * buf, size_t count, loff_t * l)
{
	
}


ssize_t io_write(struct file * filp,const char *buf,size_t count,loff_t * l)
{

}

int io_ioctl(struct inode *inode,struct file * file,unsigned int cmd,unsigned long arg)
{
	 
  int 	  temp;
   long  tem,tem1,tem2;
  
    uchar i;
   uchar command;  //command=3时,测量温度;command=5时,测量湿度
   command =cmd;
///////////////////////////   

//   data_sht11=1;
//   sck_sht11=0;
///////////////////////////   
   sht_start();

   shift8(command);  //向SHT11发送测量命令
   outl(0x02000000,pioa_base+0x14);
   sht_ack();
   delay(10);   //等待测量
   while((inl(pioa_base+0x3c)&0x02000000)!=0);
   com_data=0;
   for(i=0;i<8;i++)       //取高八位
   {
      com_data=com_data*2;
      outl(0x04000000,pioa_base+0x30);
      delay(2);
      if(((inl(pioa_base+0x3c))&0x02000000)!=0)
      {
      	 com_data=com_data+1;
      }
      outl(0x04000000,pioa_base+0x34);
      delay(2);
   }
   outl(0x02000000,pioa_base+0x10);
   outl(0x02000000,pioa_base+0x34);
   sht_ack();
   com_datah=com_data;
   outl(0x02000000,pioa_base+0x14);
   for(i=0;i<8;i++)       //取低八位
   {
      com_data=com_data*2;
      outl(0x04000000,pioa_base+0x30);
      delay(2);
      if((inl(pioa_base+0x3c)&0x02000000)!=0)
      {
      	 com_data=com_data+1;
      }
      outl(0x04000000,pioa_base+0x34);
      delay(2);
   }
//   data_sht11=0;
//   sck_sht11=1;
//   outl(0x02000000,pioa_base+0x10);
//   outl(0x02000000,pioa_base+0x34);
   outl(0x04000000,pioa_base+0x30);
   
   com_datal=com_data;
   //通过运算得出测量结果
   if(command==3)
   {
      temp=(com_datah&0x3f)*256+com_datal; //得到温度测量结果
      temp=temp/100-40;    //实际的温度值  
//      printk("%d\n",temp);
  //    printk("%d\n",com_datah);
    //  printk("%d\n",com_datal);

   }
   else
   {
      temp=(com_datah&0x0f)*256+com_datal; //得到湿度测量结果
 //     temp=
      tem =(long)temp;
//      tem=(tem*40)/1000+(tem*5)/10000-(((tem*2.8)/1000)*tem)/1000-4; //实际的湿度值
//      tem=(tem*40)/1000+(tem*5)/10000;
      tem1=tem*405;
      tem1=tem1/10000;
      tem2=tem*2.8;
      tem2=tem2/1000;
      tem2=tem2*tem;
      tem2=tem2/1000;
      tem=tem1-tem2-4; 
      temp=(int)tem;
//      printk("%d\n",temp);
//      printk("%f\n",tem);
//      printk("%d\n",com_datah);
//      printk("%d\n",com_datal);
 
   }
   return(temp);

}

int __init myio_init(void)
{
	int ret_val=0;
	ret_val=register_chrdev(IO_MAJOR,DEVICE_NAME,&io_fops);
	if (ret_val < 0) 
			{
		printk("can't get major %d", IO_MAJOR);
		return ret_val;
    	}
    		printk("<1>register_chrdev: %d\n", ret_val);
	return 0;
}
static void __exit myio_cleanup(void)
{
		unregister_chrdev(IO_MAJOR, DEVICE_NAME);		
}



module_init(myio_init);
module_exit(myio_cleanup);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -