【DS18B20调用函数】

#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "bmp.h"
#include "usart.h"
#include "JQ8X00.h"
#include <string.h>

#define	 SkipROM	0xCC
#define	 SearchROM	0xF0
#define	 ReadROM	0x33
#define	 MatchROM	0x55
#define	 AlarmROM	0xEC

#define	 StartConvert		0x44
#define	 ReadScratchpad		0xBE
#define	 WriteScratchpad	0x4E
#define	 CopyScratchpad		0x48
#define	 RecallEEPROM		0xB8
#define	 ReadPower			0xB4

#define	 EnableINT()
#define	 DisableINT()

#define	 DS_PRECISION		0x7f
#define	 DS_AlarmTH			0x64
#define	 DS_AlarmTL			0x8a
#define	 DS_CONVERT_TICK	1000

#define	 DS_PORT	GPIOA
#define	 DS_DQIO	GPIO_Pin_12

#define  DS_RCC_PORT	RCC_APB2Periph_GPIOA

#define  ResetDQ()		GPIO_ResetBits(DS_PORT,DS_DQIO)
#define  SetDQ()		GPIO_SetBits(DS_PORT,DS_DQIO)
#define  GetDQ()		GPIO_ReadInputDataBit(DS_PORT,DS_DQIO)

/*
			初始化、读、写 时序操作
*/
///
//			总线在空闲状态为高电平
//			总线保持低电平超过480us,则总线上的组组件都复位
///
unsigned char ResetDS18B20(void)
{
	unsigned char resport;
	SetDQ();
	delay_us(50);
	ResetDQ();
	delay_us(500);//总线保持低电平超过480us
	SetDQ();	//释放总线 
	delay_us(40);//DS18B20wait15~60us之间,得到DS18B20的存在脉冲60-240us
	//resport = GetDQ();
	while(GetDQ());//一直等待接收,只有当接收到DQ被拉低才会退出循环
	delay_us(500);//读到低电平后仍然要延时>480us,结束过程
	SetDQ();//将总线释放
	return resport;
	
}
///
//			写时序
//			
///
void DS18B20WriteByte(unsigned char Dat)
{
	unsigned char i;
	
	for(i=0;i<8;i++)
	{
		ResetDQ();	//总线由高变低电平,开始启动写入时隙
		delay(5);	//延时大于1us
		if(Dat & 0x01)//将数据LSB传到总线
			SetDQ();
		else
			ResetDQ();
		delay_us(65);//写入时隙的持续时间至少为60us
		SetDQ();	//单个写入时隙之间的周期>1us
		delay_us(2);
		Dat >> 1;
	}
}

///
//			读时序
//			
///
unsigned char DS18B20ReadByte(void)
{
	unsigned char i,Dat;
	SetDQ();		//第一位读取先置高5us延时
	delay_us(5);
	for(i=0;i<8;i++)//DS18B20输出的数据在读取时隙下降沿后的15us内有效
	{
		Dat >>= 1;
		ResetDQ();//总线从高到低电平至少保持1us
		delay_us(5);
		SetDQ();//释放总线
		delay_us(5);//延时后进行采样
		if(GetDQ())
			Dat |= 0x80;//只改变最高位为1
		else
			Dat &= 0x7f;//只改变最高位为0
		delay_us(65);//读取时隙的持续时间为60us
		SetDQ();
	}
	return Dat;
}

/*
		64位激光ROM命令函数操作
		五个ROM功能命令
	1)读取ROM	
	2)匹配ROM
	3)搜索ROM
	4)跳过ROM	DS18B20WriteByte(SkipROM); 
	5)报警搜索
		成功执行ROM功能序列后,可以访问存储器和控制功能

*/
void ReadRom(unsigned char *Read_Addr)
{
	unsigned char i;
	ResetDS18B20();		//首先复位
	DS18B20WriteByte(ReadROM);//写读ROM指令
	for(i=0;i<8;i++)
	{
		*Read_Addr=DS18B20ReadByte();	//读取八个字节的内存
		Read_Addr++;
	}
}


/*
		内存功能命令操作
		DS18B20WriteByte(WriteScratchpad);
		DS18B20WriteByte(ReadScratchpad);
		DS18B20WriteByte(CopyScratchpad);
		DS18B20WriteByte(StartConvert);
*/

void DS18B20Init(unsigned char Precision,unsigned char AlarmTH,unsigned char AlarmTL)
{
	ResetDS18B20();
	DS18B20WriteByte(SkipROM);
	DS18B20WriteByte(WriteScratchpad);
	DS18B20WriteByte(AlarmTL);
	DS18B20WriteByte(AlarmTH);
	DS18B20WriteByte(Precision);
	
	ResetDS18B20();
	DS18B20WriteByte(SkipROM);			//如果寄生电源供电,则发出copy命令后上拉10ms
	DS18B20WriteByte(CopyScratchpad);//parasite-powered寄生电源,器件由串行接口直接供电
	while(!GetDQ());//只要DS18B20忙于将暂存器复制到E2,它就会在总线输出0,复制完成后返回1
}

void DS18B20StartConvert(void)
{
	ResetDS18B20();
	DS18B20WriteByte(SkipROM);
	DS18B20WriteByte(StartConvert);
					//只要DS18B20忙于转换温度,它就会在总线输出0,转换温度后返回1
}

void DS18B20_Configuration(void)
{
	GPIO_InitTypeDef GPIO_Instructure;
	RCC_APB2PeriphClockCmd(DS_RCC_PORT,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = DS_DQIO;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DS_PORT,&GPIO_InitStructure);
}

void ds18b20_init(void)
{
	DS18B20_Configuration();
	DS18B20Init(DS_PRECISION,DS_AlarmTH,DS_AlarmTL);
	DS18B20StartConvert();
}

float ds18b20_read(void)
{
	unsigned char DL,DH;
	unsigned short TemperatureData;
	float Temperature;
	
	DS18B20StartConvert();
	while(!GetDQ());
	
	ResetDS18B20();
	DS18B20WriteByte(SkipROM);
	DS18B20WriteByte(ReadScratchpad);
	DL = DS18B20ReadByte();
	DH = DS18B20ReadByte();
	
	TemperatureData = DH;
	TemperatureData <<= 8;
	TemperatureData |=DL;
	
	Temperature = (float)((float)TemperatureData * 0.0625);
	return Temperature;
}

int WenDu;
int main(void)
{
	delay_init();
	ds18b20_init();
	while(1)
	{
		WenDu = ds18b20_read();
		delay_ms(500);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值