温度湿度传感器驱动成功加载到了内核,正常工作,代码完整版
#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={0};
#defineSensor_SDA1_HIGHs3c6410_ioSetData('C',0,1) //GPC0 high
#defineSensor_SDA1_LOW s3c6410_ioSetData('C',0,0)
#defineSensor_SDA1_IN s3c6410_ioSetDir('C',0,0)
#defineSensor_SDA1_OUT s3c6410_ioSetDir('C',0,1)
#defineGET_Sensor_SDA1 gpio_get_value(S3C64XX_GPC(0))
unsigned char Sensor_Data={0};
unsigned char Sensor_Check=0; //校验和
unsigned char Sensor_AnswerFlag=0;//收到起始标志位
unsigned char Sensor_ErrorFlag=0; //读取传感器错误标志
unsigned intSys_CNT=0;
externint s3c6410_ioSetData(char IO_id ,unsigned char IO_number,unsigned char status );
externint 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*256+Sensor_Data;
shidu=Sensor_Data*256+Sensor_Data;
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=temperature;
temp_sensor=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_timeis 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");
我用的是外围模块,温度湿度一体的传感器哎,不是开发板上的啊 学习学习!!!!!!!!!!!!!!!!!!! 好好学习下!!!!!!
页:
[1]