DS18B20温度传感器编程

DS18B20温度传感器编程

首页模拟经营代号DS更新时间:2024-05-05

来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)

作者:韦东山

本文字数:4327,阅读时长:5分钟

设置精度相关的位

创建ds18b20目录 查看使用那个引脚

使用GPG6引脚

#include "../../s3c2440_soc.h" /* 使用GPG6作用ds18b20的DATA引脚 */ /*定义命令和函数的宏*/ /* rom commands */ #define SEARCH_ROM 0xF0 #define READ_ROM 0x33 #define MATCH_ROM 0x55 #define SKIP_ROM 0xCC #define ALARM_ROM 0xEC /* functions commands */ #define CONVERT_TEAMPERATURE 0x44 #define WRITE_SCRATCHPAD 0x4E #define READ_SCRATCHPAD 0xBE #define COPY_SCRATCHPAD 0x48 #define RECALL_EEPROM 0xB8 #define READ_POWER_SUPPLY 0xB4 /* 先实现GPIO的基本操作 */ static void ds18b20_data_cfg_as_output(void) { GPGCON &= ~(3<<12); GPGCON |= (1<<12); } static void ds18b20_data_cfg_as_input(void) { GPGCON &= ~(3<<12); } static void ds18b20_data_set(int val) { if (val) GPGDAT |= (1<<6); else GPGDAT &= ~(1<<6); } static int ds18b20_data_get(void) { if (GPGDAT & (1<<6)) return 1; else return 0; } /*通过函数设置时间 */ static void ds18b20_data_set_val_for_time(int val, int us) { ds18b20_data_cfg_as_output(); ds18b20_data_set(val); udelay(us); } /* ds18b20释放总线 */ static void ds18b20_data_release(void) { ds18b20_data_cfg_as_input(); } /* ds18b20的代码 *先实现ds18b20初始化操作 */ static int ds18b20_initialization(void) { int val; ds18b20_data_set_val_for_time(0, 500); ds18b20_data_release(); udelay(80); val = ds18b20_data_get(); udelay(250); return val; } /* 实现写入一位数据 */ static void ds18b20_write_bit(int val) { if (0 == val) { ds18b20_data_set_val_for_time(0, 60); ds18b20_data_release(); udelay(2); } else { ds18b20_data_set_val_for_time(0, 2); ds18b20_data_release(); udelay(60); } } /* 实现一位数据的读操作 */ static int ds18b20_read_bit(void) { int val; ds18b20_data_set_val_for_time(0, 2); ds18b20_data_release(); udelay(10); val = ds18b20_data_get(); udelay(50); return val; } /* 实现写一字节数据函数 */ static void ds18b20_write_byte(unsigned char data) { /* 优先传输最低位 */ int i; for (i = 0; i < 8; i ) { ds18b20_write_bit(data & (1<<i)); } } /* 实现读一字节数据函数 */ static unsigned char ds18b20_read_byte(void) { int i; unsigned char data = 0; for (i = 0; i < 8; i ) { if (ds18b20_read_bit() == 1) data |= (1<<i); } return data; } /* 写入一字节的命令数据 */ static void ds18b20_write_rom_cmd(unsigned char cmd) { ds18b20_write_byte(cmd); } /* 写入一字节的功能命令数据 */ static void ds18b20_write_function_cmd(unsigned char cmd) { ds18b20_write_byte(cmd); } /* 实际操作函数 读rom */ int ds18b20_read_rom(unsigned char rom[]) { int i; if (ds18b20_initialization() != 0) { printf("ds18b20_initialization err!\n\r"); return -1; } ds18b20_write_rom_cmd(READ_ROM); for (i = 0; i < 8; i ) { rom[i] = ds18b20_read_byte(); } return 0; } int ds18b20_wait_when_processing(int timeout_us) { while (timeout_us--) { if (ds18b20_read_bit() == 1) return 0; /* ok */ udelay(1); } return -1; } /* 启动温度传输 */ int ds18b20_start_convert(void) { /* 所有操作到要先发出初始化操作,再发出rom命令 */ if (ds18b20_initialization() != 0) { printf("ds18b20_initialization err!\n\r"); return -1; } ds18b20_write_rom_cmd(SKIP_ROM); ds18b20_write_function_cmd(CONVERT_TEAMPERATURE); /* 等待/判断转换成功 */ if (0 != ds18b20_wait_when_processing(1000000)) { printf("ds18b20_wait_when_processing err!\n\r"); return -1; } return 0; } /* 读ram中的数据 */ int ds18b20_read_ram(unsigned char ram[]) { int i; if (ds18b20_initialization() != 0) { printf("ds18b20_initialization err!\n\r"); return -1; } ds18b20_write_rom_cmd(SKIP_ROM); ds18b20_write_function_cmd(READ_SCRATCHPAD); for (i = 0; i < 9; i ) { ram[i] = ds18b20_read_byte(); } return 0; } /* 读温度 */ int ds18b20_read_temperature(double *temp) { int err; unsigned char ram[9]; /*每一位都是前面一位的两倍*/ double val[] = {0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64}; double sum = 0; int i; err = ds18b20_start_convert(); if (err) return err; err = ds18b20_read_ram(ram); if (err) return err; /* 计算温度 */ /* 先判断精度 byte4 的4位和6位*/ if (ram[4] & (3<<5) == 0) /* 精度: 9bit */ i = 3; else if (ram[4] & (3<<5) == (1<<5)) /* 精度: 10bit */ i = 2; else if (ram[4] & (3<<5) == (2<<5)) /* 精度: 11bit */ i = 1; else /* 精度是 12 bit */ i = 0; for (; i < 8; i ) { if (ram[0] & (1<<i)) sum = val[i]; } for (i = 0; i < 3; i ) { if (ram[1] & (1<<i)) sum = val[8 i]; } if (ram[1] & (1<<3)) sum = 0 - sum; *temp = sum; return 0; } void ds18b20_init_state(void) { ds18b20_data_release(); } void ds18b20_test(void) { unsigned char rom[8]; int i; double temp; int m,n; /*一开始我们应该保证为高电平*/ ds18b20_init_state(); //while (1) { if (ds18b20_read_rom(rom) == 0) { printf("ds18b20 rom: "); for (i = 0; i < 8; i ) { printf("x ", rom[i]); } printf("\n\r"); } } while (1) { /*循环打印温度*/ if (0 == ds18b20_read_temperature(&temp)) { /*实现浮点数的打印*/ m = (int)temp; /* 3.01, m = 3 */ temp = temp - m; /* 小数部分: 0.01 */ n = temp * 10000; /* 10 */ /* 在串口上打印 */ printf("ds18b20 temperature: %d.d\n\r", m, n); /* 3.010v */ } } }

修改main.c 添加

ds18b20_test();

修改Makefile 添加

objs = sensors/ds18b20/ds18b20.o

由于使用数组涉及到了memcpy 所以编译出错,现在需要实现在string_utils.c实现memcpy函数

void *memcpy(void *dest, const void *src, int count) { char *tmp = dest; const char *s = src; while (count--) *tmp = *s ; return dest; }

烧写

课后作业:

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved