本帖最后由 arm菜鸟人 于 2012-9-12 22:01 编辑
用 LPC2109 芯片读取 DS18B20 温度信号。P1.20 引脚为 DQ。打算将温度高低字节数据读取之后通过数据打包发给上位机做处理。
程序代码如下:
/*********************************************************************************
*
***********************************************************************************/
#include "..\config.h" // 与硬件信息对接:引脚以及相应寄存器映射关系;
// 如果与主函数同文件可不用。
/*************************************************************************
#include "LPC1700PinCfg.h" // 硬件的引脚映射文件
#include "lpc1700.h" // 寄存器映射文件
*************************************************************************/
/***********************************************************************************
* 函数声明,可以放到头文件里
************************************************************************************/
void DQ_HIGH(void);
void DQ_LOW(void);
void Delay(INT32U nCount);
void ResetDB(void);
unsigned char Read_bitDB(void);
unsigned char Read_ByteDB(void);
void Write_bitDB(unsigned char dat)
void Write_ByteDB(unsigned char dat);
void Get_temp(void);
void Read_ROMDB(void);
/***************************************************************************
* DS18b20 与硬件连接处理定义 先没有 DQ 方向定义
***************************************************************************/
/*******************************************************************************
#define DQ 1 << 20 // 将引脚 P1.20 连接到 DS18b20 温度传感器的 DQ 引脚
#define DQ_HIGH() FIO1SET = DQ // 将 DQ 设置为高
#define DQ_LOW() DQ = 0 // 将 DQ 设置为低
*********************************************************************************/
/********************************************************************************
* Function: void DQ_HIGH(void)
* Descript: Write 1 to the pin of DQ.
* Input : void
* Output : void
* Return : void
*********************************************************************************/
void DQ_HIGH(void)
{
PINSEL2 &= (0 << 2); // 将 P1.20 配置成 GPIO 模式
FPO1DIR |= (1 << 20); // 将 P1.20 配置为输出端口
FIO1SET |= (1 << 20); // 将 DQ 拉高
}
/********************************************************************************
* Function: void DQ_LOW(void)
* Descript: Write 0 to the pin of DQ.
* Input : void
* Output : void
* Return : void
*********************************************************************************/
void DQ_LOW(void)
{
PINSEL2 &= (0 << 2); // 将 P1.20 配置成 GPIO 模式
FPO1DIR |= (1 << 20); // 将 P1.20 配置成输出端口
FIO1CLR |= (1 << 20); // 将 DQ 拉低
}
/********************************************************************************
* DS18b20 温度变量
********************************************************************************/
unsigned char TempH = 0; // 采集到的温度高 8 位
unsigned char TempL = 0; // 采集到的温度低 8 位
unsigned char FLAG_DB; // DS18B20 存在标志位
/*******************************************************************************
* 说明: 延时函数 void Delay_usDB(unsigned int nCount)
* 输入: nCount 要延长的时间
* 输出: 无
* 返回: 无
*******************************************************************************/
void Delay_usDB(unsigned int nCount)
{
unsigned int i, n;
for (i = 0; i < nCount; i++)
{
for (n = 0; n < 8; n++);
}
}
/**********************************************************************************
* Function: void ResetDB(void)
* Descript: To reset DS18B20. The MCU sends the reset pulse,that is a nagtive pulse
holds on 480us - 960us. After DS18B20 recieving the pulse, it holds on
15us - 60us then the DS18B20 puts a nagtive reply pulse. With this to
prove the DS18B20 is working.
* Input : void
* Output : void
* Return : void
**********************************************************************************/
void ResetDB(void)
{
// int FLAG_DB = 1; // 标志位
// while (FLAG_DB) // 一直搜索循环,如果 DS18B20不存在或出故障,容易陷入死循环
// { // 不循环,可能没进行复位,可以进行抛出异常处理
DQ_LOW(); // 拉低 DQ 引脚
Delay_usDB(503); // 延时 503 微秒,产生复位脉冲
DQ_HIGH(); // 拉高 DQ 引脚,释放总线
Delay_usDB(20); // 延时 20 微秒,等待应答信号
if ((FIO1PIN | (1 << 20)) == 0) // 判断是否应答信号
FLAG_DB = 1; // 存在 DS18B20
else
FLAG_DB = 0; // 没搜索到 DS18B20
Delay_usDB(430); // 延时 430 微秒
// }
}
/*********************************************************************************
* Function: unsigned char Read_bitDB(void)
* Descript: To read a bit from DS18B20.
* Input : void
* Output : unsigned char
* Return : dat
**********************************************************************************/
unsigned char Read_bitDB(void)
{
unsigned char dat; // 读到的位
dat = 0; // 赋初值
unsigned long tmp;
DQ_LOW(); // 拉低 DQ引脚,准备读时间隙
Delay_usDB(2); // 拉低至少 1 微秒
DQ_HIGH(); // 拉高 DQ 引脚,释放总线,以输出有效数据
Delay_usDB(5); // 小延时一下,数据在之后的 15 微秒之内有效
tmp = FIO1PIN; // 读数据
if (tmp & (1 << 20)) // 写到是 1
{
tmp = 1;
}
Delay_usDB(50); // 延时,整个读时间隙为 60 微秒
DQ_HIGH(); // 释放总线
return dat;
}
/***********************************************************************************
* Function: unsigned char Read_ByteDB(void)
* Descript: To read a Byte data from DS18B20.
* Input : void
* Output : uch
* Return : T_value
*************************************************************************************/
unsigned char Read_ByteDB(void)
{
unsigned char T_value, T_j;
T_value = 0;
unsigned char i;
for (i = 0; i < 8; i++) // 一字节 8 位,从 DQ 引脚读 8 次
{
T_j = Read_bitDB();
T_value = (T_j << 7) | (T_value >> 1); // 一字节数据保存在 T_value 里
}
return T_value;
}
/*************************************************************************************
* Function: void Write_bitDB(unsigned char dat)
* Descript: To write a bit to the DS18B20.
* Input : unsigned char dat
* Output : void
* Return : void
***************************************************************************************/
void Write_bitDB(unsigned char dat)
{
if (dat == 0) // 写 0 时间隙
{
DQ_LOW(); // 拉低电平
Delay_usDB(66); // 持续至少 60 us
DQ_HIGH(); // 释放总线
Delay_usDB(3); // 小延时
}
if (dat == 1) // 写 1 时间隙
{
DQ_LOW(); // 拉低电平
Delay_usDB(13); // 在第 1-15us 期间置位 DQ
DQ_HIGH(); // 拉高电平
Delay_usDB(66); // 在第 15-60 us 期间对数据线采样
}
}
/*************************************************************************************
* Function: void Write_ByteDB(unsigned char dat)
* Descript: To write a byte data to the DS18B20.
* Input : unsigned char dat
* Output : void
*Return : void
***************************************************************************************/
void Write_ByteDB(unsigned char dat)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
if (dat & 0x01)
{
Write_bitDB(1);
}
else
{
Write_bitDB(0);
}
dat >>= 1;
}
}
/******************************************************************************************
* Function: void Get_temp(void)
* Descript: To get the temperature from the DS18B20.
* Input : void
* Output : void
* Return : void
********************************************************************************************/
void Get_temp(void)
{
/***********************************************************
* 向 DS18B20 发送温度转换指令
************************************************************/
ResetDB(); // 复位 DS18B20
Delay_usDB(60); // 延时 60 微秒,用不用?
Write_ByteDB(0xcc); // 跳过 ROM 指令
Write_ByteDB(0x44); // 发送温度转换指令
/**********************************************************
* 得到温度数据,对其数据做相应变化
***********************************************************/
ResetDB(); // reset the DS18B20.
Delay_usDB(25); // delay 25us, whether need to do it?
Write_ByteDB(0xcc); // skip the process of reading the ROM.
Write_ByteDB(0xbe); // to read the data from the RAM.
TempL = Read_ByteDB(); // read the low byte of the temperature.
TempH = Read_ByteDB(); // read the high byte of the temperature.
/**************************************************************************
* To process the data. as we get the data with char first, we have to transfer
* it to int. But we do not have to do it now, and it is easy for us to send the
* data by CAN. And to transfer it by PC.
******************************************************************************
temp = TempH; // get the data of the temperature
temp = temp << 8;
temp = temp | TempL;
wendu = temp * 0.0625; // the decimal number
temp = wendu * 10 +0.5;
return temp;
*****************************************************************************/
}
/*************************************************************************************
* Function: void Read_ROMDB(void)
* Input : void
* Output : void
* Return : void
*************************************************************************************/
void Read_ROMDB(void)
{
unsigned char a, b; // the memeroy used to save the data from ROM
ResetDB(); // reset the DS18B20.
Delay_usDB(3); // dalay a short time.
Write_ByteDB(0x33); // to read ROM
a = Read_ByteDB();
b = Read_ByteDB();
}
大家有什么想法都尽管提吧。谢谢你们的拍砖。 |