查看: 2546|回复: 4

[Linux技术] 温度湿度传感器驱动成功加载到了内核,正常工作,代码...

[复制链接]
  • TA的每日心情

    2014-4-10 13:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-1-22 11:28:46 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 forlinx2013 于 2014-1-24 09:39 编辑

    欢迎大家来到飞凌爱板网专区,对嵌入式技术感兴趣的朋友不妨多多关注一下,我们提供了公司所有开发板的所有资料,也会更新大量技术文章,欢迎大家一块学习提高!!!

    #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 = 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");
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-12-26 22:31
  • 签到天数: 102 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2014-1-22 12:47:08 | 显示全部楼层
    看来写个传感器驱动还是蛮方便的 .
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2014-4-10 13:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

     楼主| 发表于 2014-1-22 13:23:17 | 显示全部楼层
    harvardx 发表于 2014-1-22 12:47
    看来写个传感器驱动还是蛮方便的 .

    呵呵  咱们飞凌几乎所有源码都是开源开放
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-12-26 22:31
  • 签到天数: 102 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2014-1-22 13:26:12 | 显示全部楼层
    真好 有机会 要用用
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2014-4-10 13:56
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

     楼主| 发表于 2014-1-22 13:28:27 | 显示全部楼层
    harvardx 发表于 2014-1-22 13:26
    真好 有机会 要用用

                                              
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-24 10:48 , Processed in 0.156455 second(s), 23 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.