来源:百问网_嵌入式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