Freescale MC9S08AC16 读写DS18B20
0赞
发表于 11/23/2011 10:17:25 PM
阅读(2737)
Freescale MC9S08AC16 读写DS18B20
最近看到DS18B20的帖子不少,刚好我前几天也写了个,是基于Freescale HCS08内核单片机的。
//*****************************************************************************
// DS18B20.c
// V1.0
// 2009.4.12
// //
// DS18B20测温程序,将测得的温度显示在NOKIA5110液晶屏上。
//*****************************************************************************
#include <hidef.h> /* for EnableInterrupts macro */
#include "DS18B20.h"
#define DQ PTAD_PTAD1 //PTA1为MCU与DS18B20通信引脚
#define DIRECTION PTADD_PTADD1 //PTA1的方向控制位?
byte tempH; //温度高字节
byte tempL; //温度低字节
byte tempL; //温度低字节
byte integer; //整数,转换后的温度整数部分
byte decimal1; //小数点后第一位,转换后的温度小数部分
byte decimal2; //小数点后第二位,转换后的温度小数部分
byte decimal1; //小数点后第一位,转换后的温度小数部分
byte decimal2; //小数点后第二位,转换后的温度小数部分
//----------------------------------------------------------------------------
//延时1us
//BUSCLK为16M,故每执行一条指令的时间为1/16M 秒,即0.0625us?
//winter
//2009.4.12
//---------------------------------------------------------------------------
//延时1us
//BUSCLK为16M,故每执行一条指令的时间为1/16M 秒,即0.0625us?
//winter
//2009.4.12
//---------------------------------------------------------------------------
void Delay_us(word usTime)
{
while(usTime)
{
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
{
while(usTime)
{
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
asm(NOP);
usTime--;
}
}
}
//*****************************************************************************
// PTA1引脚初始化
//*****************************************************************************
void PTA1_Init(void)
{
DQ = 0;
DIRECTION = 1;
PTADS_PTADS1 = 1; //设置PTA1为高输出强度。
}
//*****************************************************************************
//功能: 初始化DS18B20器件
//输出: DS18B20的响应信号。
//winter
//2009.4.12
//*****************************************************************************
byte DS18B20_Init(void)
{
byte State = 0;
//功能: 初始化DS18B20器件
//输出: DS18B20的响应信号。
//winter
//2009.4.12
//*****************************************************************************
byte DS18B20_Init(void)
{
byte State = 0;
DQ = 1;
DIRECTION = 1;
Delay_us(1);
DQ = 0;
Delay_us(720); //将DS18B20的DQ脚拉低至少480us
DIRECTION = 1;
Delay_us(1);
DQ = 0;
Delay_us(720); //将DS18B20的DQ脚拉低至少480us
DIRECTION = 0; //将此引脚通过上拉电阻拉高,并等待DS18B20发送状态数据。
DQ = 1;
Delay_us(30);
State = DQ; //读取DS18B20状态,若State = 0则初始化成功。
Delay_us(450); //再延时450,完成整个读DS18B20状态时序
return State; //返回DS18B20的当前状态值
}
//--------------------------------------------------------------------
//向DS18B2O写一位数据程序
//bitTemp : 1 or 0
//winter
//2009.4.12
//-------------------------------------------------------------------
void WriteBit_Fun(byte bitTemp)
{
DQ = 1;
DIRECTION = 0;
//--------------------------------------------------------------------
//向DS18B2O写一位数据程序
//bitTemp : 1 or 0
//winter
//2009.4.12
//-------------------------------------------------------------------
void WriteBit_Fun(byte bitTemp)
{
DQ = 1;
DIRECTION = 0;
DQ = 0;
DIRECTION = 1; //由高到低电平,产生写时间片。
DIRECTION = 1; //由高到低电平,产生写时间片。
if (bitTemp)
{
DQ = 1;
}
{
DQ = 1;
}
Delay_us(60); //延时60us供DS18B20读取数据。
DQ = 1; //拉高总线
DIRECTION = 0;
}
DIRECTION = 0;
}
//-------------------------------------------------------------------
//向DS18B20写一个字节的数据
//ByteTemp : 要写入的8位数据,先写低位
//winter
//2009.4.12
//-------------------------------------------------------------------
void WriteByte_Fun(byte ByteTemp)
{
byte i, temp;
//向DS18B20写一个字节的数据
//ByteTemp : 要写入的8位数据,先写低位
//winter
//2009.4.12
//-------------------------------------------------------------------
void WriteByte_Fun(byte ByteTemp)
{
byte i, temp;
DisableInterrupts;
for (i=0;i<8;i++)
{
Delay_us(1);
temp = ByteTemp>>i;
temp &= 0x01;
WriteBit_Fun(temp);
}
for (i=0;i<8;i++)
{
Delay_us(1);
temp = ByteTemp>>i;
temp &= 0x01;
WriteBit_Fun(temp);
}
EnableInterrupts; /* enable interrupts */
}
}
//--------------------------------------------------------------------
//从DS18B20读取一位数据
//
//winter
//2009.4.12
//--------------------------------------------------------------------
byte ReadBit_Fun(void)
{
byte bitTemp;
//从DS18B20读取一位数据
//
//winter
//2009.4.12
//--------------------------------------------------------------------
byte ReadBit_Fun(void)
{
byte bitTemp;
DQ = 0;
DIRECTION = 1; //拉低,进入读时间片
Delay_us(2); //延时2us 开始读取DS18B20
DIRECTION = 0;
Delay_us(1);
bitTemp = DQ;
Delay_us(70);
return bitTemp;
Delay_us(1);
bitTemp = DQ;
Delay_us(70);
return bitTemp;
}
//--------------------------------------------------------------------
//从DS18B20读取一个字节数据
//
//winter
//2009.4.12
//--------------------------------------------------------------------
byte ReadByte_Fun(void)
{
byte i, byteTemp;
DisableInterrupts;
//--------------------------------------------------------------------
//从DS18B20读取一个字节数据
//
//winter
//2009.4.12
//--------------------------------------------------------------------
byte ReadByte_Fun(void)
{
byte i, byteTemp;
DisableInterrupts;
for (i=0;i<8;i++)
{
Delay_us(1);
if (ReadBit_Fun() )
{
{
Delay_us(1);
if (ReadBit_Fun() )
{
byteTemp |= (1<<i);
}
else
{
byteTemp &= ~(1<<i);
}
else
{
byteTemp &= ~(1<<i);
}
}
EnableInterrupts; /* enable interrupts */
return byteTemp;
return byteTemp;
}
//-------------------------------------------------------------------
//读取DS18B20所测量的温度
//
//winter
//2009.4.12
//------------------------------------------------------------------
void ReadDS18B20_Fun(void)
{
word temp;
//读取DS18B20所测量的温度
//
//winter
//2009.4.12
//------------------------------------------------------------------
void ReadDS18B20_Fun(void)
{
word temp;
if (DS18B20_Init())
{
return;
}
{
return;
}
WriteByte_Fun(0xCC); //跳过ROM检测
WriteByte_Fun(0x44); //启动温度转换
WriteByte_Fun(0x44); //启动温度转换
DIRECTION = 0;
while (DQ == 0);
while (DQ == 0);
if (DS18B20_Init())
{
return;
}
{
return;
}
WriteByte_Fun(0xCC);
WriteByte_Fun(0xBE); //读取DS18B20存储器命令
WriteByte_Fun(0xBE); //读取DS18B20存储器命令
tempL = ReadByte_Fun();
tempH = ReadByte_Fun();
tempH = ReadByte_Fun();
temp = (tempH<<8)|tempL;
integer = (byte)(temp>>4); //所测量温度的整数部分
//DS18B20默认设置时分辨率为12位,对应温度的分辨率
//为0.0625摄氏度。故所测得的数值需乘以0.0625
//即除以16,可以采用右移4位的方式来完成?
//DS18B20默认设置时分辨率为12位,对应温度的分辨率
//为0.0625摄氏度。故所测得的数值需乘以0.0625
//即除以16,可以采用右移4位的方式来完成?
//温度低字节的低四位为测得温度的小数部分。
decimal1 = (byte)((tempL&0x0f)*10/16); //小数点后第一位
decimal2 = (byte)((tempL&0x0f)*100/16%10); //小数点后第二位
decimal1 = (byte)((tempL&0x0f)*10/16); //小数点后第一位
decimal2 = (byte)((tempL&0x0f)*100/16%10); //小数点后第二位
