嵌入式爱好者

查看: 6403|回复: 5

温度湿度传感器驱动成功加载到了内核,正常工作,代码完整版

[复制链接]

0

主题

0

帖子

3

积分

扫一扫,手机访问本帖
发表于 2013-10-22 12:26:56 | 显示全部楼层 |阅读模式
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>

#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-a.h>
#include <mach/gpio-bank-b.h>
#include <mach/gpio-bank-c.h>
#include <mach/gpio-bank-d.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-f.h>
#include <mach/gpio-bank-g.h>
#include <mach/gpio-bank-h.h>
#include <mach/gpio-bank-i.h>
#include <mach/gpio-bank-j.h>
#include <mach/gpio-bank-k.h>
#include <mach/gpio-bank-m.h>
#include <mach/gpio-bank-n.h>
#include <mach/gpio-bank-o.h>
#include <mach/gpio-bank-p.h>
#include <mach/gpio-bank-q.h>

#define DEVICE_NAME "kern_time"  

//the sensor var

unsigned tmp_sensor;
unsigned int shidu=0;
unsigned int temperature=0;
int check=0;
unsigned int temp_sensor[2]={0};

#define  Sensor_SDA1_HIGH  s3c6410_ioSetData('C',0,1)    //GPC0 high
#define  Sensor_SDA1_LOW   s3c6410_ioSetData('C',0,0)
#define  Sensor_SDA1_IN    s3c6410_ioSetDir('C',0,0)
#define  Sensor_SDA1_OUT   s3c6410_ioSetDir('C',0,1)
#define  GET_Sensor_SDA1   gpio_get_value(S3C64XX_GPC(0))

unsigned char Sensor_Data[5]={0};
unsigned char Sensor_Check=0;                  //校验和

unsigned char Sensor_AnswerFlag=0;  //收到起始标志位
unsigned char Sensor_ErrorFlag=0;   //读取传感器错误标志
unsigned int  Sys_CNT=0;


extern  int s3c6410_ioSetData(char IO_id ,unsigned char IO_number,unsigned char status );
extern  int s3c6410_ioSetDir(char IO_id ,unsigned char IO_number,unsigned char status );


unsigned int count_timer0=0;
unsigned int tmp_timer0=0;
unsigned int sensor_time=0;



struct timer_list timer_list;


//传感器函数部分
/********************************************\
|* 功能: 读传感器发送单个字节                *|
\********************************************/
unsigned char Read_SensorData()
  {
        unsigned char i,cnt;
        unsigned char buffer,tmp;
        buffer = 0;

        for(i=0;i<8;i++)
        {
                cnt=0;

                while(!GET_Sensor_SDA1)        //还是否是高电平,若还是则是1若不是则是0
                {
                  udelay(1);
                  if(++cnt >= 50)   //>50us循环一次刚好是64个clk 1.28us
                   {
                    break;
                   }
                }
                tmp=0;               
                udelay(32);         
               
                if(GET_Sensor_SDA1)
                {
                  tmp = 1;
                }
                cnt =0;
                while(GET_Sensor_SDA1)                //等待平 结束
                {
                        udelay(1);
                           if(++cnt >= 50)  //>35us
                        {
                          break;
                        }
                }
         //printk(KERN_NOTICE "tmp is %d\n",tmp);
                buffer <<=1;
                buffer |= tmp;
        }
        return buffer;
  }

/********************************************\
|* 功能: 读传感器
返回值:0错误 1正确
\********************************************/
unsigned char Read_Sensor()
  {
               
         unsigned char i;
         Sensor_SDA1_OUT;
         Sensor_SDA1_LOW;  //拉低
         udelay(2000);   //延时2Ms

         Sensor_SDA1_HIGH;
         udelay(40); // 拉高 30到40us
         Sensor_SDA1_IN;//主机设置为输入

         Sensor_AnswerFlag = 0;
        if(GET_Sensor_SDA1==0)
        {
         Sensor_AnswerFlag = 1;//收到起始信号
        // printk(KERN_NOTICE "flag is %d\n",Sensor_AnswerFlag);  
         Sys_CNT = 0;
           while(!GET_Sensor_SDA1)//旦有高电平则执行下边的语句
           {
                udelay(1);
             if(++Sys_CNT>80)     //防止进入死循环>80us
                 {
                   Sensor_ErrorFlag = 1;
                   break;
                  }
            }
            Sys_CNT = 0;
            //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
            while(GET_Sensor_SDA1)
            {
                udelay(1);
               if(++Sys_CNT>80)     //防止进入死循环>80us  实际是50us
                   {
                     Sensor_ErrorFlag = 1;
                     break;
                   }
            }
        // printk(KERN_NOTICE "error is %d\n",Sensor_ErrorFlag);
            for(i=0;i<5;i++)
            {
          //    printk(KERN_NOTICE "temperature is ok\n");
              Sensor_Data[i] = Read_SensorData();
            }
          }
          else
          {
            Sensor_AnswerFlag = 0;          // 未收到传感器响应
          }

          return 1;
  }
   

static void Kern_Interupt()
{
        mod_timer(&timer_list,jiffies+2*HZ);
        sensor_time++;
        if(sensor_time==2)
        {
        sensor_time=0;
        Read_Sensor();
        temperature = Sensor_Data[2]*256+Sensor_Data[3];
        shidu=Sensor_Data[0]*256+Sensor_Data[1];       
        printk(KERN_NOTICE "The temperature is:%d\n",temperature);
         printk(KERN_NOTICE "The shidu is:%d\n",shidu);       
        }       
               
                tmp_timer0++;
                if(tmp_timer0>=2)
                tmp_timer0=0;
               
                if(tmp_timer0==0)
                s3c6410_ioSetData('M',0,0);//亮
                else
                s3c6410_ioSetData('M',0,1);//灭
               
               
}

//cmd:1:temperature,2:shidu
//arg: reserved
static long Kern_Time(struct file *filp, unsigned int cmd, unsigned long arg)
{      
init_timer(&timer_list);//初始化定时器  
timer_list.function=Kern_Interupt;//设置定时器处理函数  
timer_list.expires=jiffies+2*HZ;//处理函数1s后运行  
add_timer(&timer_list);//添加定时器
return 0;
}

static int kern_release()
{
printk(KERN_NOTICE "kern_time is close.\n");
del_timer_sync(&timer_list);
return 0;
}

static ssize_t kern_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{

temp_sensor[0]=temperature;
temp_sensor[1]=shidu;

if(copy_to_user(buffer,(unsigned int*)temp_sensor,sizeof(temp_sensor)))  
  {  
   printk("copy to user error\n");  
   goto out;  
  }  
return  (sizeof(temp_sensor));  
out:  
return -1;

}



static struct file_operations dev_fops = {
    .owner                        = THIS_MODULE,
    .unlocked_ioctl        = Kern_Time,
    .release          =kern_release,
    .read          =kern_read,
};

static struct miscdevice misc = {
        .minor = MISC_DYNAMIC_MINOR,
        .name = DEVICE_NAME,
        .fops = &dev_fops,
};
static int __init dev_init(void)
{
        int ret1=0;
        int ret=0;
        ret1 = misc_register(&misc);
        if(ret<0)
        {printk(KERN_NOTICE "Register Kern_time failed!\n");
        return ret;
        }
        printk (KERN_NOTICE "Kern_time  is ok! \n");
        return ret1;
           
}

static void __exit dev_exit(void)  
{
       
        misc_deregister(&misc);
       
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jack Sun");
MODULE_DESCRIPTION("Kern time Driver");
回复

使用道具 举报

sdq1q1555 该用户已被删除
发表于 2013-10-22 20:37:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
点评回复 支持 反对

使用道具 举报

0

主题

0

帖子

3

积分

 楼主| 发表于 2013-10-24 00:13:59 来自手机 | 显示全部楼层
我用的是外围模块,温度湿度一体的传感器哎,不是开发板上的啊
点评回复 支持 反对

使用道具 举报

249917994 该用户已被删除
发表于 2014-1-6 22:18:43 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
点评回复 支持 反对

使用道具 举报

0

主题

6

帖子

7

积分

发表于 2015-11-23 15:14:36 | 显示全部楼层
学习学习!!!!!!!!!!!!!!!!!!!
点评回复 支持 反对

使用道具 举报

0

主题

0

帖子

14

积分

发表于 2016-1-5 21:51:25 | 显示全部楼层
好好学习下!!!!!!
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-12-20 19:05

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表