Linux——DS18B20温度读取(C语言)
运行环境及硬件: 树莓派4B、DS18B20
接线:
树莓派4B | DS18B20 |
---|---|
3.3v | vcc |
gnd | gnd |
4(BCM编码标准) | data |
前言:
1、打开树莓派的单总线驱动
sudo raspi-config
选定之后系统会提示进行重启,点击确认就行了。
2、查看系统是否自动加载单总线的驱动
lsmod | grep w
如果没有可以进行下面这个操作进行添加:
sudo vim /boot/config.txt
在最后进行添加:采用BCM GPIO的标准,使用引脚4
dtoverlay=w1-gpio-pullup,gpiopin=4
这个文件只能root权限进行,用chmod也不能进行权限修改。
3、相关系统调用
(1)文件夹的相关函数
①打开文件夹
DIR *opendir(const char *pathname);
这个函数的返回值是一个句柄,用来标识这个文件夹,实质上是一个虚拟的地址。pathname为相关操作对象的路径。
②读取文件夹里面的相关文件夹和文件的名称,相当于遍历。
struct dirent * readdir(DIR *dp);
struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
③关闭文件夹
int closedir(IDR *dp);
每次使用完一定要记得把它关闭了。
4、文件的系统调用
请阅读:https://blog.csdn.net/weixin_45062087/article/details/118880374
一、具体代码
/*
找到文件夹,
打印文件名
找到对应文件打开并读取里面的内容
找到关键数据,存进数组,指针指向数组,读取数组对应的数据,返回数值,显示出来。
*/
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int ds18b20_temp(float *temp);
int main(int argc, char *argv[])
{
float temp;
while(1)
{
if( ds18b20_temp(&temp) < 0 )
{
printf("ds18b20 get temp failure\n");
return 1;
}
printf("ds18b20 get temp: %f ℃\n", temp);
sleep(2);
}
}
int ds18b20_temp(float *temp)
{
int fd = -1;
int rv = 0, rv1 = -1;
DIR *dirp;
struct dirent *direntp;
char path[255] = "/sys/bus/w1/devices/";
char buf[512];
char *ptr;
memset(buf, 0, sizeof(buf));
/* 打开dir文件夹 */
if((dirp = opendir(path)) == NULL)
{
printf("opendir %s error: %s\n", path, strerror(errno));
return -1;
}
/* 列出dir里面的所有文件和文件夹 */
while((direntp = readdir(dirp)) != NULL)
{
//printf("Find file: %s\n", direntp->d_name);
if(strstr(direntp->d_name, "28-"))
{
printf("Find file: %s\n", direntp->d_name);
strncat(path, direntp->d_name, sizeof(direntp->d_name));
//strncpy(dir_name, direntp->d_name, sizeof(dir_name));
strncat(path,"/w1_slave",sizeof(path)-strlen(path));
rv = 1;
}
}
closedir(dirp);
if(!rv)
{
printf("cann't find the dir[%s]: %s \n", path, strerror(errno));
return -2;
}
printf("the path is : %s \n", path);
fd = open(path, O_RDONLY);
if(fd < 0)
{
printf("open the file failure : %s \n", strerror(errno));
return -3;
}
if((rv1 = read(fd, buf, sizeof(buf))) < 0 )
{
printf("read the data from file[%s] failure: %s \n", path, strerror(errno));
close(fd);
return -4;
}
lseek(fd, 0, SEEK_SET);
while(rv1 = read(fd, buf, rv1))
{
printf("%s",buf);
ptr = strstr(buf, "t=");
if(!ptr)
{
printf("Cann't get the temp!");
return -5;
}
ptr +=2;
*temp = atof(ptr)/1000.0;
}
close(fd);
return 0;
}
运行效果:
二、总结
通过这次的学习,了解了文件夹的相关操作,对于寻找相关文件来说还是用处很大的,尤其是了解了单总线的系统驱动是使用的,成功使用ds18b20读取到了环境的温度值。