?? 18b20control.c
字號(hào):
#include <iom16v.h>
#include <macros.h>
#include "DS18B20.h"
//#include "7279.h"
int value=0;
/***************************************
檢查DS1820是否存在;
如果存在返回1;否則返回0
***************************************/
unsigned char DS18B20_reset(void)
{
unsigned char bus_flag;
PORTB|=(1<<5);
PORTB&=~(1<<5); // 設(shè)置1-wire總線為低電平(占領(lǐng)總線)...
/* 現(xiàn)在延遲480us~960us, 與硬件密切相關(guān),但應(yīng)盡可能選小值(480us),
把抖動(dòng)留給系統(tǒng)(比如在延遲期間發(fā)生中斷導(dǎo)致延遲變長)。
*/
delay(327); // 490us
CLI(); // 下面這段時(shí)間要求比較嚴(yán)格,為保險(xiǎn)起見,關(guān)中斷
PORTB|=(1<<5);; // 設(shè)置1-wire總線為高電平(釋放總線)
/* 這個(gè)浮點(diǎn)數(shù)是由編譯器計(jì)算好的,而不是由你的MCU在運(yùn)行時(shí)臨時(shí)計(jì)算的,
所以不會(huì)占用用戶MCU的時(shí)間,不必?fù)?dān)心(看看前面的宏你就可以確定了)
*/
//delay_nus(12); // 最佳時(shí)間: 60us+7.5us!(忙延時(shí),只是一種策略)
// 探測總線上是否有器件
DDRB&=~(1<<5);
delay(40);
if(DQ_status()) bus_flag=0; // 復(fù)位單總線但沒有發(fā)現(xiàn)有器件在線
else bus_flag=1; // 復(fù)位單總線并發(fā)現(xiàn)有器件在線
SEI(); // 退出臨界代碼區(qū)(開中斷)
/* 保證Master釋放總線的時(shí)間(不是說總線處于高電平的時(shí)間)不小于
480us即可,這一時(shí)間從讀總線狀態(tài)之前就開始了,所以這里把這個(gè)
時(shí)間計(jì)算在內(nèi)。在Master釋放總線的前半段,也是被動(dòng)器件聲明它
們在線之時(shí)。
*/
DDRB|=(1<<5);
NOP();
PORTB|=(1<<5);;
delay(150); // 490-67.5us
return(bus_flag);
}
/***************************************
從DS18B20讀取1字節(jié)數(shù)據(jù)
***************************************/
unsigned char DS18B20_read(void)
{
unsigned char i,Read_Byte=0;
for(i=0;i<8;i++)
{
CLI();
PORTB&=~(1<<5); // 設(shè)置1-wire總線為低電平(拉低總線以同步)
//delay_nus(2);
PORTB|=(1<<5);; // 設(shè)置1-wire總線為高電平(釋放總線)
//delay_nus(4); // 4us
DDRB&=~(1<<5);
Read_Byte>>=1; //右移一位
if(PINB&(1<<5)) Read_Byte|=0x80; // 讀取總線電平,先收低位再收高位
SEI(); // 恢復(fù)系統(tǒng)中斷
delay(50); // 必須大于60us
SEI();
DDRB|=(1<<5);
NOP();
}
return(Read_Byte);
}
/***************************************
寫命令到DS18B20
***************************************/
void DS18B20_write(unsigned char cmd)
{
unsigned char Write_Temp,j;
for(j=0;j<=7;j++)
{
CLI();
PORTB&=~(1<<5); // 設(shè)置1-wire總線為低電平
//delay_nus(2);
if(cmd&0x01) PORTB|=(1<<5); // 并串轉(zhuǎn)換,先低位后高位
else PORTB&=~(1<<5);
cmd>>=1;
delay(40);
PORTB|=(1<<5);;
SEI();
//delay_nus(2);
}
}
void Write_Init(void)
{
DS18B20_reset();
DS18B20_write(0xcc);
DS18B20_write(0x4E);
DS18B20_write(0x10);
DS18B20_write(0x80);
DS18B20_write(0x7F);
}
void convert_T(void)
{
//if(DS18B20_reset()==1) // 如果復(fù)位成功
//{
DS18B20_reset();
DS18B20_write(0xcc); // 跳過多器件識(shí)別
DS18B20_write(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
//PORTA|=(1<<1);
//delay(400);
//}
}
int Read_T(void)
{
//if(DS18B20_reset()==1) { // 如果復(fù)位成功
DS18B20_reset();
DS18B20_write(0xcc); // 跳過多器件識(shí)別
DS18B20_write(0xbe); // 讀暫存器
value = (int)DS18B20_read(); // 低字節(jié)
value += (int)((DS18B20_read())<<8); // 高字節(jié)
//}
return(value);
}
/****內(nèi)部CRC較驗(yàn)****/
unsigned char CRCcheck(unsigned char *ValuePoint,unsigned char len)
{
unsigned char bit0,cbit,r,temp,i,j,byte;
temp=0;
for(j=0;j<len;j++)
{
byte=ValuePoint[j];
for(i=0;i<8;i++)
{
cbit=temp&0x01;
bit0=byte&0x01;
temp=temp>>1;
r=cbit^bit0;
if(r==1)
temp=temp^0x8c;
byte=byte>>1;
}
}
return temp;
}
/***************************
將十六進(jìn)制轉(zhuǎn)ASCII碼,并顯示
***************************/
/*void asc2con(unsigned char *p,unsigned char len)
{
unsigned char i,temp;
for(i=0;i<len;i++)
{
temp=p[len-1-i]&0xf0;
temp=temp>>4;
LCD_write_string(0,1,table[temp]);
temp=p[len-1-i]&0x0f;
LCD_write_string(1,1,table[temp]);
}
}*/
/************************************
匹配DS18B0
*************************************/
void DS18B20_match(unsigned char *p)
{
unsigned char i;
DS18B20_reset();
DS18B20_write(0x55);
for(i=0;i<8;i++)
DS18B20_write(p[i]);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -