kernel(十三)1-wire (DS18B20)

Linux 内核实现了一套通用的 1-wire 子系统框架, 只需简单的配置芯片引脚,就可以实现对单总线芯片的驱动。
参考文档:
Documentation/w1/masters/w1-gpio
Documentation/w1/slaves/w1_therm
查看 TQ210 原理图

XEINT8 对应的 GPIO GPH1_0
mach-smdkv210.c 中添加头文件<linux/w1-gpio.h>

构造w1=-gpi平台设备


注意: ext_pullup_enable_pin 没有使用,必须设置为-1,否则内核启动文件系统后,控制台没法输入。
有疑问的可以分析
drivers/w1/masters/w1-gpio.c 的下面代码段

分析一下 gpio_is_valid 函数就明白了。
添加到
smdkv210_devices

配置内核

Device Drivers --->
        <*> Dallas's 1-wire support --->
                1-wire Bus Masters --->
                        <*> GPIO 1-wire busmaster
                1-wire Slaves --->
                        <*> Thermal family implementation

编译内核,运行测试


28-000004de67f8 这个目录就是为 DS18b20 生成的, 28 表示 28 系列,后面的为设备 ID

28-000004de67f8 目录下有个属性文件 w1_slave,读取这个文件可以读取到 DS18B20 的当前温度值。
YES 表示 crc 校验正确, t=34312 表示当前温度值。 除以 1000 即为实际温度值。

应用程序操作方法 get_temp.c

get_temp.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DS18B20_DEV		"/sys/devices/w1_bus_master1/28-04146f63f3ff/w1_slave"

/* return 0 on success, or -1 on erro */
int get_temp(float *value, const char *dev)
{
	int ret;
	FILE *fp;
	char buf1[100], buf2[100];
	
	fp = fopen(dev, "r");
	if (fp == NULL)
	{
		perror("fopen");
		return -1;
	}
	
	fgets(buf1, 100, fp);
	sscanf(buf1, "%*[^:]: crc=%[^ ]%s\n", buf2);
	if (strcmp(buf2, "YES") == 0)
	{
		fgets(buf1, 100, fp);
		sscanf(buf1, "%*[^t]t=%s\n", buf2);
		*value = atoi(buf2) * 1.0 / 1000;
		ret = 0;
	}
	else
	{
		fprintf(stderr, "CRC error\n");
		ret = -1;
	}

	fclose(fp);
	return ret;
}

int main(int argc, char **argv)
{
	float value;
	if (get_temp(&value, DS18B20_DEV) == 0)
		printf("%.3f °C\n", value);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jerrygou/article/details/80918199