温湿度传感器在工业当中运用的比较广泛,通常用于检测设备所处环境的温度和湿度,温度过高,设备就有可能自动关机来保证设备不被烧坏。
我所采用的温湿度传感器是si7020-a20的芯片,I2C接口,地址如图描述:
也就是说,作为从机,si7020地址是0x40。另外,cpu采用atml 9x35,内核2.6.39。知道0x40这个地址之后,就要在板级文件board-sam9x5ek中添加相应的代码。</span>
找到ek_i2c_devices数组,在数组中添加如下代码:
- {
- I2C_BOARD_INFO("si7020", 0x40)
- },
第一个是这个模块的名字,待会儿要和驱动中的.name 匹配。0x40是i2c地址。这个数组在ek_board_init函数中,通过i2c_register_board_info(0,ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); 注册进内核。
新建makefile:
- obj-m := si7020.o
- KDIR := ../linux-2.6.39
- all:
- make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
- clean:
- rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
然后新建驱动代码源文件si7020.c:
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <linux/init.h>
- #include <linux/cdev.h>
- #include <asm/uaccess.h>
- #include <linux/slab.h>
- #include <linux/spi/spi.h>
- #include <linux/miscdevice.h>
- #include <linux/device.h>
- #include <linux/io.h>
- #include <asm/uaccess.h>
- #include <linux/sched.h>
- #include <linux/i2c.h>
- #include <linux/delay.h>
-
- struct si7020_data{
- struct i2c_client *client;
- struct mutex lock;
- int buf[2];
- };
-
- enum
- {
- humidity,
- temperature,
- };
-
- struct si7020_data *si7020;
-
- static void get_humi_val()
- {
- unsigned int ret = 0;
- char tmp[2] = {0};
-
-
- i2c_smbus_write_byte(si7020->client, 0xf5);
- msleep(100);
- i2c_master_recv(si7020->client, tmp, 2);
- ret =((tmp[0]<<8)|tmp[1]);
- if(ret < 0)
- dev_err(&si7020->client->dev, "Read Error\n");
-
-
- si7020->buf[humidity] = 125*ret/65536 - 6;
- if(si7020->buf[humidity] < 1)
- si7020->buf[humidity] = 0;
- if