?? ds18b20aa.c
字號(hào):
//*************DS18B20數(shù)字溫度計(jì)*******************//
//*MCU: AT892051 //
//*MCU-crystal: 12M //
//*Version: 01 //
//*Last Updata: 2007-6-9 //
//*Author: zhaojun //
//*Description: //
//DS18B20的讀寫程序,數(shù)據(jù)腳P3.4 //
//溫度傳感器18B20匯編程序,采用器件默認(rèn)的12位轉(zhuǎn)化 //
//最大轉(zhuǎn)化時(shí)間750微秒,顯示溫度-55到+125度,顯示精度 //
//為0.1度,顯示采用4位LED共陽顯示測(cè)溫值 //
//P1口為段碼輸入,P0~P3為位選 //
//***************WAVE-E6000/T**********************//
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
#define Disdata P1 // 段碼入口
sbit DQ=P3^4; // 溫度輸入口
uint temp; // variable of temperature 定義一個(gè)變量
uchar flag1; // 定義一個(gè)標(biāo)志,標(biāo)志溫度是負(fù)還是正,1為負(fù),0為正
sbit DIN=P1^7; // 小數(shù)點(diǎn)控制
#define discan P3 //掃描口
uchar h; // 定義變量
//位選位定義
sbit DEC=P3^0; // 小數(shù)
sbit POS=P3^1; // 個(gè)位
sbit TEN=P3^2; // 十位
sbit HUN=P3^3; // 百位,符號(hào)位
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共陽數(shù)碼管段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "滅" "-"
unsigned char code table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//帶小數(shù)點(diǎn)的編碼
//共陽數(shù)碼管帶小數(shù)點(diǎn)段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
uchar data temp_data[2]={0x00,0x00};//讀出溫度暫放
uchar data Dis_play[5]={0x00,0x00,0x00,0x00,0x00};//顯示單元數(shù)據(jù),共4個(gè)數(shù)據(jù)和一個(gè)運(yùn)算暫用
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//小數(shù)部分對(duì)應(yīng)十進(jìn)制 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列掃描控制字
/***************************************/
/* 延時(shí)子程序 */
/***************************************/
void delay(uint i) //delay
{
while(i--);
}
/************************************************/
/* 初始化ds18b2子函數(shù)* */
/************************************************/
Init_DS18B20(void)
{
uchar x=0;
DQ = 1; //DQ復(fù)位
delay(8); //稍做延時(shí)
DQ = 0; //單片機(jī)將DQ拉低
delay(80); //精確延時(shí) 大于 480us
DQ = 1; //拉高總線
delay(14);
x=DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
delay(20);
}
/*************************************************/
/* 讀字節(jié)子函數(shù) */
/*************************************************/
ReadOneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號(hào)
dat>>=1; // 數(shù)據(jù)右移一位
DQ = 1; // 給脈沖信號(hào)
if(DQ) // DQ為1
dat|=0x80; // 讀出數(shù)據(jù)
delay(4); // 延時(shí)
}
return(dat);
}
/*************************************************/
/* 寫字節(jié)子函數(shù) */
/*************************************************/
WriteOneChar(unsigned char dat)
{
uchar i = 0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01; //寫入一位數(shù)據(jù)
delay(5);
DQ = 1;
dat>>=1; //右移一位數(shù)據(jù)
}
}
/*************************************************/
/* DS18B20寫命令函數(shù) */
/*************************************************/
/*void tmpwritebyte(uchar dat) // write a byte to ds18b20
{ // 給溫度傳感器寫一個(gè)字節(jié)
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //寫入 1
{
DQ=0;
i++;i++;
DQ=1;
i=8;while(i>0)i--; // 適當(dāng)延時(shí)
}
else //寫入 0
{
DQ=0;
i=8;while(i>0)i--; // 適當(dāng)延時(shí)
DQ=1;
i++;i++;
}
}
}*/
/******************************************/
/* 發(fā)送溫度轉(zhuǎn)換命令 */
/******************************************/
void tmpchange(void) // DS18B20 begin change
{
Init_DS18B20(); // 初始化DS18B20
delay(200); // 延時(shí)
WriteOneChar(0xcc); // 跳過序列號(hào)命令
WriteOneChar(0x44); // 發(fā)送溫度轉(zhuǎn)換命令
}
/******************************************/
/* 讀出溫度函數(shù) */
/******************************************/
uint tmp() //get the temperature
{
// float tt;
Init_DS18B20(); // 初始化ds18b2子函數(shù)
delay(1);
WriteOneChar(0xcc); // 跳過ROM命令
WriteOneChar(0xbe); // 發(fā)送讀取數(shù)據(jù)命令
temp_data[0]=ReadOneChar(); // 連續(xù)讀兩個(gè)字節(jié)數(shù)據(jù)
temp_data[1]=ReadOneChar();
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 兩字節(jié)合成一個(gè)整型變量。
// tt=temp*0.0625; // 得到真實(shí)十進(jìn)制溫度值,因?yàn)镈S18B20
// 可以精確到0.0625度,所以讀回?cái)?shù)據(jù)的最低位代表的是
// 0.0625度。
// temp=tt*10+0.5; // 放大十倍,這樣做的目的將小數(shù)點(diǎn)后第一位
// 也轉(zhuǎn)換為可顯示數(shù)字,同時(shí)進(jìn)行一個(gè)四舍五入操作。
return temp; // 返回溫度值
}
/******************************************/
/* 讀出序列號(hào)函數(shù) */
/******************************************/
/*void readrom() // read the serial 讀取溫度傳感器的序列號(hào)
{ // 本程序中沒有用到此函數(shù)
uchar sn1,sn2;
Init_DS18B20(); // DS18B20初始化
delay(1);
WriteOneChar(0x33); // Read ROM
sn1=ReadOneChar(); // 8位系列編碼
sn2=ReadOneChar(); // 8位CRC碼
}*/
/******************************************/
/* 溫度數(shù)據(jù)顯示處理函數(shù) */
/******************************************/
void tem_deal(uint tem)
{
/*************溫度數(shù)據(jù)處理*****************/
if(tem>6348) // 溫度值正負(fù)判斷
{tem=65536-tem;flag1=1;} // 負(fù)溫度求補(bǔ)碼,標(biāo)志位置1
Dis_play[4]=tem&0x0f; // 取小數(shù)部分的值
Dis_play[0]=ditab[Dis_play[4]]; // 存入小數(shù)部分顯示值
Dis_play[4]=tem>>4; // 取中間八位,即整數(shù)部分的值
Dis_play[3]=Dis_play[4]/100; // 取百位數(shù)據(jù)暫存
Dis_play[1]=Dis_play[4]%100; // 取后兩位數(shù)據(jù)暫存
Dis_play[2]=Dis_play[1]/10; // 取十位數(shù)據(jù)暫存
Dis_play[1]=Dis_play[1]%10; // 取個(gè)位數(shù)據(jù)暫存
if(!Dis_play[3]) // 最高位為0都不顯示
{
Dis_play[3]=0x0a; // 先判斷百位是否為0
if(!Dis_play[2])
{
Dis_play[2]=0x0a; // 再判斷十位是否為0
}
}
if(flag1)
{
Dis_play[3]=0x0b; // 為負(fù)數(shù)時(shí),最高位顯示 "-"
}
}
/******************溫度數(shù)據(jù)顯示********************/
void display()
{
char k;
for(k=0;k<4;k++) //4位LED掃描控制
{
Disdata=table[Dis_play[k]]; //數(shù)據(jù)顯示
if (k==1){DIN=0;} //小數(shù)點(diǎn)顯示
discan=scan_con[k]; //位選
delay(90); //延時(shí)
discan=0xff;
}
}
/******************************************/
/* 主函數(shù) */
/******************************************/
void main()
{
Disdata=0xff; //端口初始化
P3=0xff;
//開機(jī)顯示"888.8";這段程序可以不要.
for(h=0; h<4; h++)
{
Dis_play[h]=8;
}
for(h=0; h<50; h++)
{
display(); //顯示數(shù)據(jù)
delay(1000); //延時(shí)
}
//溫度顯示
do
{
tmpchange(); //溫度轉(zhuǎn)換
tem_deal(tmp()); //顯示溫度值
display();
}
while(1);
}
//*****************結(jié)束**********************//
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -