DS18B20温度传感器编程(DS18B20温度传感器编程)
DS18B20温度传感器编程(DS18B20温度传感器编程)objs = sensors/ds18b20/ds18b20.o由于使用数组涉及到了memcpy 所以编译出错,现在需要实现在string_utils.c实现memcpy函数ds18b20_test();修改Makefile 添加创建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 comm

来源:百问网_嵌入式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;
}
    
烧写
课后作业:
- a. 使用CRC较验 64bit rom数据
 - b. 使用CRC较验 9byte的 ram数据
 - c. 增加写ram 写eeprom的功能 设置转换精度
 
「新品首发」STM32MP157开发板火爆预售!首批仅300套




