lcp2103怎么成功读取ds18b20温度值
坐等高手
再等高手
DS1621的温度我读出来了 你那个型号的没用过
你好,不知道你用的是定时器还是软件yanshi?
我是一个都没做出来,最近考试也没有做这东西。
你的LPC2103控制DS18B20的问题解决没啊?
我在IAR环境下写的程序,片子是LPC2103的,验证能读出,给你参考下。
/*****************************************************************************************
名称:DS18B20测温
功能:GPIO口实现温度测量功能
**********************************************************************************************************/
#include"config.h"
#define DQ 1 << 19
/*************************************************
初始化
**************************************************
void F_18B20_IO_Initial()
{
PINSEL1 |= 0x00; //定义P0.16为低速GPIO
IO0DIR &= (~DQ); //默认P0.16为输入口
}
*/
/*********************************************************************************************************
** Function name: Delaynus
** Descriptions: 延时函数,传递参数为1时大约延时1us
** Input parameters: uiDly
** Output parameters: 无
*********************************************************************************************************/
void Delaynus1(U32 uiDly)
{
U32 i;
for(;uiDly>0;uiDly--)
for(i=0;i<5;i++);
}
/************************************************
DS18b20初始化
************************************************/
U8 F_DS18B20_Reset()
{
U8 uiTimeCnt,uiIOValue;
IO0DIR = IO0DIR | DQ; //DQ设置为输出
IO0SET = IO0SET | DQ; //DQ = 1; //DQ复位
Delaynus1(10); //稍做延时
IO0CLR = IO0CLR | DQ; // 将DQ拉低
Delaynus1(600); //精确延时 大于 480us 小于960us
IO0SET = DQ; //主机释放单总线 // DQ = 1; //拉高总线
Delaynus1(50); //15~60us 后 接收60-240us的存在脉冲
for(uiTimeCnt=0;uiTimeCnt<5;uiTimeCnt++) //输出60-240us低电平作为应答脉冲
{
uiIOValue = IO0PIN;
uiIOValue &= DQ;
if(uiIOValue) //读入1,复位错误,返回
{
return 0;
}
}
Delaynus1(400); //复位需要,和上次的应答低脉冲之和至少480us,否则复位错误
return 1;
}
/********************************************
向DS18B20写入0
********************************************/
void F_DS18B20_Write_0()
{
PINSEL1 = 0x00000000;
IO0DIR = IO0DIR | DQ ; //DQ设为输出口
IO0CLR = DQ; //拉低总线
Delaynus1(60); //写0就一直拉低到写周期结束
IO0SET = DQ; //主机释放单总线 //释放总线
}
/********************************************
向DS18B20写1
*********************************************/
void F_DS18B20_Write_1()
{
PINSEL1 = 0x00000000;
IO0DIR = IO0DIR | DQ; //DQ为输出口
IO0CLR = DQ; //拉低总线1微秒
Delaynus1(5); //写周期开始
IO0SET = DQ; //主机释放单总线 //拉高总线120微秒到写周期结束,写1
Delaynus1(50);
}
/*******************************************
写入一个字节
********************************************/
void WriteOneChar(U8 WriteData)
{
U8 i=0;
for(i=0;i<8;i++)
{
if(WriteData&0x01)
F_DS18B20_Write_1();
else
F_DS18B20_Write_0();
WriteData >>= 1;
}
}
/******************************************
主机读时序
*******************************************/
U32 F_DS18B20_ReadDQ()
{
U32 uiTemp = 0;
PINSEL1 = 0x00000000;
IO0DIR = IO0DIR | DQ; // DQ为输出口
IO0CLR = DQ;
Delaynus1(5);
IO0SET = DQ; //主机释放单总线 //拉低1毫秒后拉高,开始读
Delaynus1(3);
uiTemp=IO0PIN;
Delaynus1(60);
uiTemp &= DQ; //读DQ状态
return(uiTemp);
}
/********************************************
读取一个字节
*******************************************/
U16 ReadOneChar()
{
U16 i;
U16 dat = 0;
for(i=0;i<8;i++)
{
dat>>=1;
if(F_DS18B20_ReadDQ())
dat |= 0x80;
}
return dat;
}
/***********************************************************************
**开始测温
***********************************************************************/
float F_DS18B20_Start()
{
U16 uiTemp;
U16 uiData[9];
fp32 fTemp = 0.0;
if(F_DS18B20_Reset())
{
WriteOneChar(0xcc); //Skip ROM,单点总线系统,不需读取分辨
/*WriteOneChar(0x7f);*/
WriteOneChar(0x44); //Start one convert
while(F_DS18B20_ReadDQ()==0); //启动后发送读操作,若器件忙于温度转化则输出0,转化完毕输出1
F_DS18B20_Reset(); //一次完整操作包括初始化,ROM操作,存储器和控制操作,处理数据四步,每次都要遵循该流程
Delaynus1(1000);
WriteOneChar(0xcc); //Skip ROM
/*WriteOneChar(0x1f);*/
WriteOneChar(0xBE); //Read Scratchpad,读缓冲寄存器
for(uiTemp=0;uiTemp<9;uiTemp++)
uiData[uiTemp] = ReadOneChar();
uiTemp=((uiData[1]<<8) | uiData[0] ); //缓冲存储器中的Byte0、1数据为测得的温度信息,以16位补码形式存放
if(uiTemp & 0x8000)
uiTemp=(~uiTemp)+1;
uiTemp=uiTemp/16.0;
fTemp=(float)uiTemp;
fTemp=fTemp/16.0;
}
return fTemp;
}