Tcar:智能车之ds18b20温度传感器实现温度采集模块

1、温度采集模块
   // env/ds18b20.zip
1.1 硬件 温度传感器 ' ds18b20'
 一线式设备( 1-wire
 ' 独立式供电': VDD接独立的电源
 ' 寄生供电': DQ连接到GPIO管脚
当GPIO管脚上为高电平时 充电 (内部有电容)
当GPIO管脚上为低电平时 放电 来维持ds18b20工作所需要的能量
  寄生电源优势: 布线简单
  驱动程序中要时刻注意是否应该拉高DQ
 一个GPIO管脚上可以有多个ds18b20
1.2 硬件驱动
  1.2.1 ds18b20的数据手册
 1.2.1.1 ds18b20的组成结构
 1.2.1.2 通信方式
// P10
 必要步骤:
1)初始化
  reset信号
  presence信号
2)发送rom command
match rom
  发送命令0x55 64bit ID 
  一线式上有多个DS18B20
skip  rom
  发送命令0xcc
  驱动程序例子ds18b20_drv.c 一线式上只有一个ds18b20
3) function command
convert T :开启温度转换
read  : 读9个字节的RAM
write : 写温度值之后的RAM
  
 P15:
复位 存在信号的时序
 
读写一个bit的时序
   
 如何开始温度转换,并获取温度值
example1: 温度转换 读取温度
 发送reset
 接收响应信号
 发送skip rom
 发送开启温度转换的命令
 
 延时等待转换完成
 
 发送reset
 接收响应信号
 发送skip rom
 发送读命令
 接收数据

example2: 配置精度


1.3 应用程序
  gui_client
  给服务器发送读温度的命令
  接收服务器返回的温度值值 
  显示温度值 Qlabel->setText("32")
  server
  如果接收到的命令读温度的
  参考ds18b20_test.c读取温度值
  把读到的温度值返回给client

/* ds18b20温度传感器驱动代码演示 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SKIP_ROM        0xcc
#define COVERTT         0x44
#define READ_MEM        0xbe

/* 参看文档P16,注意写1和0的时隙要求*/
/*11001100*/
static void ds18b20_write8(unsigned char data)
{
        int i;

        local_irq_disable();
       for (i = 0; i < 8; i++) {
                if ((data & 0x1) == 1) {
                        gpio_direction_output(S5PV210_GPH1(0), 0);
                        udelay(3);
                        gpio_direction_output(S5PV210_GPH1(0), 1);
                        udelay(80);
                } else {
                        gpio_direction_output(S5PV210_GPH1(0), 0);
                        udelay(80);
                        gpio_direction_output(S5PV210_GPH1(0), 1);
                        udelay(3);
                }
                data >>= 1;
       }
    local_irq_enable();
}

/* 参看文档P16,注意读1和0的时隙要求*/
static unsigned char ds18b20_read8(void)
{
        int i;
        unsigned char bit;
        unsigned char data = 0;

        local_irq_disable();
        for (i = 0; i < 8; i++) {
                gpio_direction_output(S5PV210_GPH1(0), 0);
                udelay(2);
                gpio_direction_input(S5PV210_GPH1(0));
                bit = gpio_get_value(S5PV210_GPH1(0));
                data |= (bit << i);
                udelay(60);
        }
    local_irq_enable();
        return data;
}

/* 参看文档P15 初始化时序图 */
static void ds18b20_reset(void)
{
        unsigned char ret;

        gpio_direction_output(S5PV210_GPH1(0), 0);
        udelay(500);
        gpio_direction_output(S5PV210_GPH1(0), 1);
        udelay(30);
        gpio_direction_input(S5PV210_GPH1(0));
        ret = gpio_get_value(S5PV210_GPH1(0));
        udelay(500);
        if (ret == 0) {
                printk("reset ok.\n");
        } else {
                printk("reset failed.\n");
        }
}

static ssize_t ds18b20_read(struct file *file, char *buf, size_t count, loff_t *pos)
{
        unsigned char h8, l8;
        int temp = 0;

        ds18b20_reset();
        ds18b20_write8(SKIP_ROM);
        ds18b20_write8(COVERTT);

        msleep(750);
        //mdelay(750);

        ds18b20_reset();
        ds18b20_write8(SKIP_ROM);
        ds18b20_write8(READ_MEM);
        
        l8 = ds18b20_read8();
        h8 = ds18b20_read8();

        temp = (h8 << 8) | l8; //0x191,组合成一个16bit数据

        temp *= 625; //扩大10000倍

        if(copy_to_user(buf, &temp, 4))
		return -EFAULT;
        return count;
}

static struct file_operations ds18b20_fops = {
        .owner  = THIS_MODULE,
        .read    = ds18b20_read,
};

static struct miscdevice ds18b20_miscdev = {
        .minor  = MISC_DYNAMIC_MINOR,       
        .name   = "ds18b20",
        .fops   = &ds18b20_fops,
};

static int ds18b20_init(void)
{
        gpio_request(S5PV210_GPH1(0), "GPH1_0");
        misc_register(&ds18b20_miscdev);
        return 0;
}

static void ds18b20_exit(void)
{
        misc_deregister(&ds18b20_miscdev);
        gpio_free(S5PV210_GPH1(0));
}

module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_LICENSE("GPL");

/* test.c */
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
        int fd;
        int data;
        
        fd = open("/dev/ds18b20", O_RDWR);
        if (fd < 0) {
                printf("open ds18b20 failed.\n");
                exit(-1);
        }

        while (1) {
                read(fd, &data, sizeof(data));
                sleep(1);
                printf("%.3f\n", (float)data / 10000);
        }
        close(fd);
        return 0;
}

# makefile for kernel module

MODNAME = ds18b20_drv
CROSS_COMPILE = arm-linux-
TESTPRE	= ds18b20_test

ifeq ($(PLATFORM), PC)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
else
CC = $(CROSS_COMPILE)gcc
KERNELDIR ?= /opt/kernel
endif

obj-m := $(MODNAME).o

default: test driver

test:
	@echo "Compiling test program..."
	$(CC) $(TESTPRE).c -o $(TESTPRE)
	@echo

driver:
	@echo "Compiling device driver..."
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
	@echo

clean:
	@echo "Cleanup test program..."
	@rm -f $(TESTPRE) $(MODNAME)
	@echo
	@echo "Cleanup device driver..."
	@rm -rf *.o *.ko *.mod.* .$(MODNAME).* .tmp* module* Module*
	@echo


你可能感兴趣的:(Embedded,Product)