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;
}