?? ds1820.c
字號:
//文件名:DS18B20.c
#define uchar unsigned char
#define uint unsigned int
#define XF_MCU 1 //定義用哪一種單片機,1時,用于PIC; 0時,用于MSP430;
#if XF_MCU==0
#include <msp430x14x.h>
#include "DS1820.h"
#else
#include <pic.h>
#include "DS1820.h"
uchar pa_out;
uchar pb_out;
uchar pc_out;
uchar pd_out;
uchar pe_out;
#endif
const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
'8','9'};
unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};
//定義
unsigned char Error = 0;
float Temper=0.0; //真正有效溫度值
int temperature=0; //讀取兩字節溫度數據
unsigned char symbol = 1 ; //溫度正負符號
//----------------------------------
//功能:us 級別延時
// n=10,則延時10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
{
while(n--){};
}
//-----------------------------------
//功能:寫18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ0;
_NOP();_NOP(); //延時5us
_NOP();_NOP();_NOP();
if((n&0X01)==0X01) //DQ=1
DQ1;
else
DQ0; //DQ=0
n=n>>1; //下一位
DelayNus(6); //延時50us 以上
DQ1;
}
}
//------------------------------------
//功能:讀取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++)
{
temp=temp>>1; //移向下一位
DQ0;
_NOP(); //延時1us
DQ1;
_NOP();_NOP(); //延時5us
_NOP();
DQIO_IN; //DQ口設為輸入
if((DS_IN&DS_IT)==0) //DQ是否等于0
{
temp=temp&0x7F; //讀入DQ為0
}
else
{
temp=temp|0x80; //讀入DQ為1
}
DelayNus(5); //延時40us
DQIO_OUT; //DQ口設為輸出
DQ1; //DQ輸出1
}
return temp; //返回一個數據
}
//-----------------------------------
//復位說明:復位要求主CPU將數據線下拉500us,然后釋放,
//當DS18B20收到信號后等待16~60us左右,后發出60~240微秒的存在低脈沖,
//主CPU收到此信號表示復位成功。
//初始化DS18B20
void Init (void)
{
DQ0;
DelayNus(50); //延時500us
DQ1;
DelayNus(12); //延時16~60us
DQIO_IN; //設DQ為輸入
if((DS_IN&DS_IT)==DS_IT) //1000 0000b=1f,DQ是否為1
{
Error =1; //失敗1
DQIO_OUT; //設DQ為輸輸出
}
else
{
Error = 0; //初始化成功
DQIO_OUT; //設DQ為輸輸出
DQ1;
}
}
//----------------------------------
//指令描述:跳過ROM命令,指定代碼為CCH,忽略64位ROM地址,直接向DS1820發溫度變換
//命令,適用于單片機工作.
void Skip(void)
{
Write_18B20(0xcc);
}
//----------------------------------
//指令描述:溫度轉換命令,指定代碼為44H.啟動DS1820進行溫度轉換,12位轉換時最長
//為750ms(9位為93.75ms).結果存入內部9字節RAM中.
void Convert (void)
{
Write_18B20(0x44);
}
//----------------------------------
//指令描述:讀暫存器,指定代碼為BEH.讀內部RAM中9字節的內容.
void ReadDo (void)
{
Write_18B20(0xbe);
}
//----------------------------------
//讀取溫度值
void ReadTemp (void)
{
char temp_low, temp_high; //溫度值
temp_low = Read_18B20(); //讀低位
temp_high = Read_18B20(); //讀高位
if((temp_high|positive)==positive)
symbol=1; //測到的溫度為正
else
symbol=0; //測到的溫度為負
temperature=(temp_high&0x0f);//屏蔽高4位
temperature<<=8; //將temp_high部分數據移到temperature高8位
temperature|=temp_low; //將高低兩字節內部合并成一個16位數據
if(symbol==0) //是否為負溫度
{ temperature = (~temperature)+1; //將其取反后加1
}
Temper=temperature*0.0625; //計算真實溫度值
}
//----------------------------------
//MCU對DS18B20進行溫度轉換時,其操作必須滿足以下過程:
// 1- 每一次讀寫之前都要對DS18B20進行復位.
// 2- 完成復位后發送一條ROM命令到DS18B20.
// 3- 最后發送一條RAM命令到DS18B20.
// 以上系列動作是根據DS18B20的通訊協議所得.
//讀取溫度
void GetTemp(void)
{
Init(); //DS1820初始化
Skip(); //跳過64位ROM(ROM命令)
Convert(); //轉換(RAM命令)
DelayNus(60000); //60000x5us=0.3s
DelayNus(60000); //0.3s
DelayNus(60000); //0.3s
Init(); //DS1820初始化
Skip(); //跳過64位ROM
ReadDo(); //讀暫存器
ReadTemp(); //讀取溫度值
}
//END--------------------------------------------------------------
//另外,由于MSP430F14與44的DCO時鐘有所不同,各位如要引用DS18B20程序時請加于注意操作時序。
//引用時可能出現過復位不成功或讀到全為FF...
//這些大部分都是由于程序上的時序不能滿足DS18B20所至。
//以下關于14與4系列的DCO默認時鐘:
//4系列默認時鐘 ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = 32xACLK = 1048576Hz時鐘周期為0.95us
//14系列默認時鐘 ACLK= n/a, MCLK= SMCLK= default DCO ~800k 時鐘周期為1.25us
//MC430F14 DS18B20實驗主程序
void main(void)
{
#if XF_MCU==0
WDTCTL=WDTPW+WDTHOLD; //停止WDT
mcuinit(); //MSP430F14初始化
#else
LCM141_DIR_OUT;
#endif
while(1)
{
GetTemp(); //讀取溫度
display_number(Temper); //數據變換
;
}
}
//將溫度值轉換成可顯示十進制值
//取數范圍整數3位,小數點后3位.
void display_number(float f_data)
{ unsigned long value;
float n;
n=f_data *1000;
value = (unsigned long int)n;
temp_display[1] = digit[value/100000]; //100位
value = value%100000;
temp_display[2] = digit[value/10000]; //10位
value = value%10000;
temp_display[3] = digit[value/1000]; //1位
value = value%1000;
temp_display[5] = digit[value/100]; //0.1位
value = value%100;
temp_display[6] = digit[value/10]; //0.01位
value = value%10;
temp_display[7] = digit[value/1]; //0.001位
}
//--------------------------------------------------------------------
//---------------------------------------------------------------------
//MSP430F14初始化
void mcuinit(void)
{
DQIO_OUT; //設為輸出
DQ1; //輸出高電平;
}
//---------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -