常用的传感器DS1320 DS18B20.docx
《常用的传感器DS1320 DS18B20.docx》由会员分享,可在线阅读,更多相关《常用的传感器DS1320 DS18B20.docx(17页珍藏版)》请在冰豆网上搜索。
常用的传感器DS1320DS18B20
好几天没有更新了,呵呵~~今天我把咱们常用的传感器DS1320DS18B20给大家介绍下。
对于市面上的大多数51单片机开发板来说。
ds1302和ds18b20应该是比较常见的两种外围芯片。
ds1302是具有SPI总线接口的时钟芯片。
ds18b20则是具有单总线接口的数字温度传感器。
下面让我们分别来认识并学会应用这两种芯片。
首先依旧是看DS1302的datasheet中的相关介绍。
(原文件名:
1.jpg)
上面是它的一些基本的应用介绍。
下面是它的引脚的描述。
(原文件名:
2.jpg)
下面是DS1302的时钟寄存器。
我们要读取的时间数据就是从下面这些数据寄存器中读取出来的。
当我们要想调整时间时,可以把时间数据写入到相应的寄存器中就可以了。
(原文件名:
3.jpg)
这是DS1302内部的31个RAM寄存器。
在某些应用场合我们可以应用到。
如我们想要做一个带定时功能的闹钟。
则可以把闹钟的时间写入到31个RAM寄存器中的任意几个。
当单片机掉电时,只要我们的DS1302的备用电池还能工作,那么保存在其中的闹钟数据就不会丢失~~
(原文件名:
4.jpg)
由于对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。
因此在我们应用这些器件的时候一定要对照着手册上面的要求来进行操作。
如果觉得还不够放心的话。
可以到网上下载一些参考程序。
对着手册看别人的程序,看别人的思路是怎么样的。
DS1302和单片机的连接很简单。
只需一根复位线,一根时钟线,一根数据线即可。
同时它本身还需要接一个32.768KHz的晶振来提供时钟源。
对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。
同时可以在第8脚接上一个3.6V的可充电的电池。
当系统正常工作时可以对电池进行涓流充电。
当系统掉电时,DS1302由这个电池提供的能量继续工作。
下面让我们来驱动它。
sbitio_DS1302_RST =P2^0;
sbitio_DS1302_IO =P2^1;
sbitio_DS1302_SCLK=P2^2;
//-------------------------------------常数宏---------------------------------//
#defineDS1302_SECOND_WRITE 0x80 //写时钟芯片的寄存器位置
#defineDS1302_MINUTE_WRITE 0x82
#defineDS1302_HOUR_WRITE 0x84
#defineDS1302_WEEK_WRITE 0x8A
#defineDS1302_DAY_WRITE 0x86
#defineDS1302_MONTH_WRITE 0x88
#defineDS1302_YEAR_WRITE 0x8C
#defineDS1302_SECOND_READ 0x81 //读时钟芯片的寄存器位置
#defineDS1302_MINUTE_READ 0x83
#defineDS1302_HOUR_READ 0x85
#defineDS1302_WEEK_READ 0x8B
#defineDS1302_DAY_READ 0x87
#defineDS1302_MONTH_READ 0x89
#defineDS1302_YEAR_READ 0x8D
//-----------------------------------操作宏----------------------------------//
#defineDS1302_SCLK_HIGH io_DS1302_SCLK=1;
#define DS1302_SCLK_LOW io_DS1302_SCLK=0;
#defineDS1302_IO_HIGH io_DS1302_IO =1;
#defineDS1302_IO_LOW io_DS1302_IO =0;
#defineDS1302_IO_READ io_DS1302_IO
#defineDS1302_RST_HIGH io_DS1302_RST =1;
#defineDS1302_RST_LOW io_DS1302_RST =0;
/******************************************************
*保存时间数据的结构体 *
******************************************************/
struct
{
uint8Second;
uint8Minute;
uint8Hour;
uint8Day;
uint8Week;
uint8Month;
uint8Year;
}CurrentTime;
/******************************************************************************
*Function:
staticvoidv_DS1302Write_f(uint8Content) *
*Description:
向DS1302写一个字节的内容 *
*Parameter:
uint8Content:
要写的字节 *
* *
******************************************************************************/
staticvoidv_DS1302Write_f(uint8Content)
{
uint8i;
for(i=8;i>0;i--)
{
if(Content&0x01)
{
DS1302_IO_HIGH
}
else
{
DS1302_IO_LOW
}
Content>>=1;
DS1302_SCLK_HIGH
DS1302_SCLK_LOW
}
}
/******************************************************************************
*Function:
staticuint8v_DS1302Read_f(void) *
*Description:
从DS1302当前设定的地址读取一个字节的内容 *
*Parameter:
*
*Return:
返回读出来的值(uint8) *
******************************************************************************/
staticuint8v_DS1302Read_f(void)
{
uint8i,ReadValue;
DS1302_IO_HIGH
for(i=8;i>0;i--)
{
ReadValue>>=1;
if(DS1302_IO_READ)
{
ReadValue|=0x80;
}
else
{
ReadValue&=0x7f;
}
DS1302_SCLK_HIGH
DS1302_SCLK_LOW
}
returnReadValue;
}
/******************************************************************************
*Function:
voidv_DS1302WriteByte_f(uint8Address, uint8Content) *
*Description:
从DS1302指定的地址写入一个字节的内容 *
*Parameter:
Address:
要写入数据的地址 *
* Content:
写入数据的具体值 *
*Return:
*
******************************************************************************/
voidv_DS1302WriteByte_f(uint8Address, uint8Content)
{
DS1302_RST_LOW
DS1302_SCLK_LOW
DS1302_RST_HIGH
v_DS1302Write_f(Address);
v_DS1302Write_f(Content);
DS1302_RST_LOW
DS1302_SCLK_HIGH
}
/******************************************************************************
*Function:
uint8v_DS1302ReadByte_f(uint8Address) *
*Description:
从DS1302指定的地址读出一个字节的内容 *
*Parameter:
Address:
要读出数据的地址 *
* *
*Return:
指定地址读出的值(uint8) *
******************************************************************************/
uint8v_DS1302ReadByte_f(uint8Address)
{
uint8ReadValue;
DS1302_RST_LOW
DS1302_SCLK_LOW
DS1302_RST_HIGH
v_DS1302Write_f(Address);
ReadValue=v_DS1302Read_f();
DS1302_RST_LOW
DS1302_SCLK_HIGH
returnReadValue;
}
/******************************************************************************
*Function:
voidv_ClockInit_f(void) *
*Description:
初始化写入DS1302时钟寄存器的值(主程序中只需调用一次即可)*
*Parameter:
*
* *
*Return:
*
******************************************************************************/
voidv_ClockInit_f(void)
{
if(v_DS1302ReadByte_f(0xc1)!
=0xf0)
{
v_DS1302WriteByte_f(0x8e,0x00); //允许写操作
v_DS1302WriteByte_f(DS1302_YEAR_WRITE,0x08); //年
v_DS1302WriteByte_f(DS1302_WEEK_WRITE,0x04); //星期
v_DS1302WriteByte_f(DS1302_MONTH_WRITE,0x12); //月
v_DS1302WriteByte_f(DS1302_DAY_WRITE,0x11); //日
v_DS1302WriteByte_f(DS1302_HOUR_WRITE,0x13); //小时
v_DS1302WriteByte_f(DS1302_MINUTE_WRITE,0x06); //分钟
v_DS1302WriteByte_f(DS1302_SECOND_WRITE,0x40); //秒
v_DS1302WriteByte_f(0x90,0xa5); //充电
v_DS1302WriteByte_f(0xc0,0xf0); //判断是否初始化一次标识写入
v_DS1302WriteByte_f(0x8e,0x80); //禁止写操作
}
}
/******************************************************************************
*Function:
voidv_ClockUpdata_f(void) *
*Description:
读取时间数据,并保存在结构体CurrentTime中 *
*Parameter:
*
* *
*Return:
*
******************************************************************************/
voidv_ClockUpdata_f(void)
{
CurrentTime.Second=v_DS1302ReadByte_f(DS1302_SECOND_READ);
CurrentTime.Minute=v_DS1302ReadByte_f(DS1302_MINUTE_READ);
CurrentTime.Hour =v_DS1302ReadByte_f(DS1302_HOUR_READ);
CurrentTime.Day =v_DS1302ReadByte_f(DS1302_DAY_READ);
CurrentTime.Month =v_DS1302ReadByte_f(DS1302_MONTH_READ);
CurrentTime.Week =v_DS1302ReadByte_f(DS1302_WEEK_READ);
CurrentTime.Year =v_DS1302ReadByte_f(DS1302_YEAR_READ);
}
有了上面的这些函数我们就可以对DS1302进行操作了。
当我们想要获取当前时间时,只需要调用v_ClockUpdata_f(void)这个函数即可。
读取到的时间数据保存在CurrentTime这个结构体中。
至于如何把时间数据在数码管或者是液晶屏上显示出来我相信大家应该都会了吧^_^.
看看显示效果如何~~
(原文件名:
5.jpg)
下面再让我们看看DS18B20吧。
DS18B20是单总线的数字温度传感器。
其与单片机的接口只需要一根数据线即可。
当然连线简单意味着软件处理上可能要麻烦一点。
下面来看看它的优点:
(原文件名:
1.jpg)
看看它的靓照。
外形和我们常用的三极管没有什么两样哦。
(原文件名:
2.jpg)
DS18B20的内部存储器分为以下几部分
ROM:
存放该器件的编码。
前8位为单线系列的编码(DS18B20的编码是19H)后面48位为芯片的唯一序列号。
在出场的时候就已经设置好,用户无法更改。
最后8位是以上56位的CRC码。
(原文件名:
3.jpg)
RAM:
DS18B20的内部暂存器共9个字节。
其中第一个和第二个字节存放转换后的温度值。
第二个和第三个字节分别存放高温和低温告警值。
(可以用RAM指令将其拷贝到EEPROM中)第四个字节为配置寄存器。
第5~7个字节保留。
第9个字节为前8个字节的CRC码。
DS18B20的温度存放如上图所示。
其中S位符号位。
当温度值为负值时,S=1,反之则S=0。
我们把得到的温度数据乘上对应的分辨率即可以得到转换后的温度值。
DS18B20的通讯协议:
在对DS18B20进行读写编程时,必须严格保证读写的时序。
否则将无法读取测温结果。
根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过3个步骤:
每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令。
这样才能对DS18B20进行预定的操作。
复位要求主机将数据线下拉500us,然后释放,DS18B20收到信号后等待16~160us然后发出60~240us的存在低脉冲,主机收到此信号表示复位成功。
(原文件名:
4.jpg)
上图即DS18B20的复位时序图。
下面是读操作的时序图
(原文件名:
5.jpg)
这是写操作的时序图
(原文件名:
6.jpg)
下面让我们来看看它的驱动程序如何写吧。
sbitio_DS18B20_DQ =P2^3;
#defineDS18B20_DQ_HIGH io_DS18B20_DQ=1;
#defineDS18B20_DQ_LOW io_DS18B20_DQ=0;
#defineDS18B20_DQ_READ io_DS18B20_DQ
/*******************************************************************
*保存温度值的数组.依次存放正负标志,温度值十位,个位,和小数位 *
*******************************************************************/
uint8Temperature[4];
voidv_Delay10Us_f(uint16Count)
{
while(--Count)
{
_nop_();
}
}
/**************************************************************************
*Function:
uint8v_Ds18b20Init_f(void) *
*Description:
初始化DS18B20 *
*Parameter:
*
*