下面是ds18b20的程序,ds18b20是dallas公司的1-wire温度传感器,本来程序并没有什么复杂的,但是由于1-wire最总线时序的要求非常严格,我去年调试的时候居然花了1个星期才搞定。我把代码贴在这里,供大家参考。不过还是提醒下,如果你用的mcu主频与我的不一样,则要小心调整里面的延迟等函数,使得满足1-wire的时序(我用的是11.0592MHZ)
//FileName:ds18b20.h
#ifndef __LZP_DS18B20_H_
#define __LZP_DS18B20_H_
#include "reg52.h"
sfr P4=0xe8;
sbit SPK=P4^0;
//命令定义
#define CONVERT 0x44
#define RDSCRATCH 0xbe
#define WRSCRATCH 0x4e
#define CPSCRATCH 0x48
#define RECALLE2 0xb8
#define RDPWR 0xb4
//ROM Function Command
#define RDROM 0x33
#define MATCHROM 0x55
#define SKIPROM 0xcc
#define SCROM 0xf0
#define ALARROM 0xec
sbit DS18B20_DQ=P4^1;
void write_command(unsigned char cmd);
unsigned char read_byte(void);
unsigned char reset_pulse(void);
void convert(void);
void get_temperature_data(unsigned char *temp);
void ds18b20_config();
void read_ds18b20_id(unsigned char *id);
#endif
//FileName:ds18b20.c
///////////////////////////////////////////////////////////
//DS18B20基于DAllas公司的1-wire总线
//关于1-wire总线协议的具体内容,请参看ds18b20的datasheet
//另外www.maxim-ic.com.cn上有很多技术白皮书可以参考
//google上可以找到更多资料
//////////////////////////////////////////////////////////
#include "ds18b20.h"
#include "delay.h"
#include "intrins.h"
//初始化
unsigned char reset_pulse(void)
{
unsigned char flag=0;
DS18B20_DQ=1;
_nop_();
DS18B20_DQ=0;
//拉低约600us(必须在480us--960us之间)
delay_us(40);
DS18B20_DQ=1;
//delay_us(2);
delay_us(12);
//检测DS18B20应答
// while(DS18B20_DQ);
//while(!DS18B20_DQ);
//delay_us(1);
if(DS18B20_DQ)
flag=0;
else
flag=1;
//DS18B20_DQ=1;
return flag;
}
/*从ds18b20读一个字节
* ds18b20返回的数据是LSB的,即最低位先发,最高位最后发
*/
unsigned char read_byte(void)
{
unsigned char i,j,tmp;
tmp=0;
//DS18B20_DQ=1;
for(i=0;i<8;i++)
{
tmp>>=1;
//j=read_bit();
DS18B20_DQ=1;
_nop_();
_nop_();
DS18B20_DQ=0;//产生一个下降沿,开始一个读time slot(时隙)
//根据ds18b20的1-wire协议要求,必须延时至少1us
_nop_();
_nop_();
// _nop_();
//释放总线
DS18B20_DQ=1;
//根据ds18b20的1-wire协议要求,必须延时至少15us
//这样读到的数据才有效
// delay_us(2);
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(DS18B20_DQ)
tmp|=0x80;
delay_us(10);
}
return tmp;
}
void write_command(unsigned char cmd)
{
unsigned char i;
for(i=0;i<8;i++)
{
DS18B20_DQ=1;
if(cmd&0x01)//write 1 time slot
{
DS18B20_DQ=0;//产生下降沿,开始一个write 1 time slot
//_nop_();
DS18B20_DQ=1;//释放总线
//delay_40us(1);
delay_us(5);//delay at least 60us
}
else{//write 0 time slot
DS18B20_DQ=0;//产生下降沿,开始一个write 0 time slot
// delay_40us(1);
delay_us(5);//保持最少60us
DS18B20_DQ=1;
}
cmd>>=1;
// _nop_();
}
DS18B20_DQ=1;
}
//启动一次温度测量
void convert(void)
{
reset_pulse();
//delay_ms(1);
write_command(SKIPROM);
write_command(CONVERT);
delay_ms(10);
//while(!read_bit());
//while(!DS18B20_DQ);//wait for convert complete
}
void get_temperature_data(unsigned char *temp)
{
reset_pulse();
// delay_ms(1);
write_command(SKIPROM);
write_command(RDSCRATCH);
temp[0]=read_byte();//低字节
temp[1]=read_byte();//高字节kqqe
reset_pulse();//终止继续传输后续字节
}
void ds18b20_config(void)
{
reset_pulse();
// delay_ms(1);
write_command(SKIPROM);
write_command(WRSCRATCH);
write_command(0x19);
write_command(0x1a);
write_command(0x7f);
reset_pulse();
write_command(SKIPROM);
write_command(0x48);
reset_pulse();
write_command(SKIPROM);
write_command(0xb8);
}
void read_ds18b20_id(unsigned char *id)
{
unsigned char i;
reset_pulse();
write_command(0x33);
for(i=0;i<8;i++)
{
id=read_byte();
}
}
//FileName:delay.h
#ifndef __LZP_DELAY_H_
#define __LZP_DELAY_H_
//sfr RCAP2L = 0xCA;
//sfr RCAP2H = 0xCB;
#define TRUE 1
#define FALSE 0
//设置波特率
#define OSC_FREQ 11059200L
#define BAUD_115200 256 - (OSC_FREQ/192L)/115200L // 255
#define BAUD_57600 256 - (OSC_FREQ/192L)/57600L // 254
#define BAUD_38400 256 - (OSC_FREQ/192L)/38400L // 253
#define BAUD_28800 256 - (OSC_FREQ/192L)/28800L // 252
#define BAUD_19200 256 - (OSC_FREQ/192L)/19200L // 250
#define BAUD_14400 256 - (OSC_FREQ/192L)/14400L // 248
#define BAUD_9600 256 - (OSC_FREQ/192L)/9600L // 244
// Timer2
#define RCAP2_50us 65536L - OSC_FREQ/80000L
#define RCAP2_1ms 65536L - OSC_FREQ/4000L
void delay_ms(unsigned int num);
void delay_40us(unsigned char num);
void delay_us(unsigned char num);
#endif
//FileName:delay.c
#include "delay.h"
#include "reg52.h"
void delay_ms(unsigned int num)
{
RCAP2H = (RCAP2_1ms>>8);
RCAP2L=(RCAP2_1ms&0x00ff);
TH2=(RCAP2_1ms>>8);;
TL2=(RCAP2_1ms&0x00ff);;
ET2 = 0; // Disable timer2 interrupt
T2CON = 0x04; // 16-bit auto-reload, clear TF2, start timer
while (num--)
{
while (!TF2);
TF2 = FALSE;
}
TR2 = FALSE;
}
void delay_40us(unsigned char num)
{
RCAP2H=(RCAP2_50us>>8);
RCAP2L=(RCAP2_50us&0x00ff);
TH2=(RCAP2_50us>>8);
TL2=(RCAP2_50us&0x00ff);
ET2=0;
T2CON=0x04;
while(num--)
{
while(!TF2)
TF2=FALSE;
}
TR2=FALSE;
}
void delay_us(unsigned char num)
{
unsigned char i;
for (i=0;i<num;i++)
{
}
}
文章评论(0条评论)
登录后参与讨论