?? 18b20.c
字號:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define DELAY_CLOSEDIS 5 //沒按鍵,延時5秒關(guān)背光
#define DELAY_INPUT 5 //沒按鍵,延時5秒返回顯示溫度
#define KEYCODE_UP 0x1 //加溫度
#define KEYCODE_DOWN 0x2 //減溫度
#define KEYCODE_FAN 0x4 //設(shè)置風(fēng)速
#define KEYCODE_ONOFF 0x8 //開關(guān)風(fēng)機(jī)
#define KEYCODE_TIME 0x6 //設(shè)置時間
#define KEYCODE_PWM 0xc //設(shè)置PWM
#define WAIT_cCurrTemp 0
#define MAX_TEMP 32
#define MIN_TEMP 15
sbit bDQ = P1^0; // DS1820數(shù)據(jù)線
sbit bLED_light = P1^1; // LED 背光驅(qū)動,低有效
sbit bKey1 = P1^2; // 鍵盤掃描線1,高有效
sbit bKey2 = P1^3; // 鍵盤掃描線2,高有效
sbit bKey3 = P1^4; // 鍵盤輸入線1,低有效
sbit bKey4 = P1^5; // 鍵盤輸入線2,低有效
sbit bFAN = P0^5; // 開風(fēng)機(jī)PWM, 低有效
sbit bAC_Zero = P3^2; // 過零脈沖輸入口
//uchar ucCount1; // 記錄過零脈沖寬度
uchar ucCount; // 可控占空比0-95%寬度=10mS-ucCount1
uchar ucPWM; // 輸出占空比
uchar bdata ucLED;
sbit bFAN_AUTO = ucLED^3;
sbit bFAN_LOW = ucLED^2;
sbit bFAN_MIN = ucLED^1;
sbit bFAN_HIGH = ucLED^0;
bit bPowerON = 0; // 開機(jī)狀態(tài)=1
uchar ucTimer;
/**************** LED顯示相關(guān)變量 ********************/
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, C, 度
const uchar code aucLEDNUMCODE[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F,0x39,0x63};
const uchar code aucLEDcs[]={0x17,0x1b,0x1d,0x1e,0x0f}; /* LED位選 */
uchar ucScanIndex; /* 數(shù)碼管位選控制 */
uchar ucLEDData[4]; /* 臨時顯示緩沖數(shù)組 */
uchar ucLEDFlash[5]; /* 顯示緩沖數(shù)組 */
bit bNeg; /* 負(fù)號標(biāo)志 */
uchar ucFlashType;
bit bFlash;
uchar ucCurrSec;
uchar ucSystemStatus;
uchar ucDelaySec; //切換延時秒數(shù)
uchar ucCloseDelaySec; //關(guān)背光延時秒數(shù)
uchar aucCurrTime[2];
uchar aucTmpValue[2];
uchar ucFanSpeed;
char cCurrTemp;
char cSetTemp;
/**********************************************************************/
uchar ucLongDelay; //長按鍵
uchar ucDelayKey;
uint nDelay100uS;
char cKEYCode;
bit bStill;
bit bUpdateDisOK;
/****************************** 函數(shù)聲明 ******************************/
void DisplayValue(char *Value);
void SetFanStatus(void);
void DisposeKey(void);
void ScanLED(void);
uchar SCANKEY(void);
void DisplayTemp(char Temp);
void Key(uchar k);
void DisposeCurrTime(void);
void DisposeDelay(uchar LType);
void UpdateDis(uchar status);
/**********************************************************************/
bit Init_DS18B20(void)
{
bit sysOK = 0;
bDQ = 0; // 單片機(jī)將DQ拉低
nDelay100uS = 6;
while(nDelay100uS != 0); // 精確延時 大于 500us
bDQ = 1; // 拉高總線
nDelay100uS = 4;
while(bDQ && nDelay100uS); // 稍做延時后 如果bDQ=0則初始化成功 bDQ=1則初始化失敗
if(nDelay100uS != 0)
{
nDelay100uS = 4;
while(~bDQ && nDelay100uS);
if(nDelay100uS != 0)
{
sysOK = 1; // 在延時時間內(nèi)18B20有應(yīng)答證明初始化成功
}
}
return(sysOK);
}
/**********************************************************************/
char ReadOneChar(void)
{
uchar i;
uchar j;
uchar dat = 0;
for (i=8; i>0; i--)
{
bDQ = 0; // 給脈沖信號
bDQ = 0;
dat >>= 1;
bDQ = 1; // 給脈沖信號
if(bDQ)
{
dat |= 0x80;
}
j = 8;
while(j--)
{
}
}
return(dat);
}
/**********************************************************************/
void WriteOneChar(uchar dat)
{
uchar i, j;
for (i = 8; i > 0; i--)
{
bDQ = 0;
bDQ = 0;
bDQ = dat & 0x01;
j = 8;
while(j--)
{
}
bDQ = 1;
dat >>= 1;
}
}
/**********************************************************************/
char ReadTemperature(void)
{
bit f;
union UniTEMP
{
uint T;
uchar T_byte[2];
}idata uT;
f=Init_DS18B20();
if(f != 0) // 18B20初始化成功?
{
ET0 = 0;
ET1 = 0;
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0xBE); // 讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
uT.T_byte[1] = ReadOneChar();
uT.T_byte[0] = ReadOneChar();
ET0 = 1;
ET1 = 1;
}
else
{
return(99);
}
f = Init_DS18B20();
if(f != 0)
{
ET0 = 0;
ET1 = 0;
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
nDelay100uS = 1100; // 等待AD轉(zhuǎn)換結(jié)束9位AD約100mS
ET0 = 1;
ET1 = 1;
}
else
{
return(99);
}
bNeg = 0;
if((uT.T_byte[0] & 0x80) != 0)// 負(fù)數(shù)標(biāo)志位為1?
{
uT.T = ~uT.T+1; // 轉(zhuǎn)換成正數(shù)
bNeg = 1; // 負(fù)數(shù)標(biāo)志置位
}
uT.T += 8; // 四舍五入
uT.T >>= 4; // 取整
return(uT.T_byte[1]);
}
/********************* 初始化變量 **********************/
void INITVar(void)
{
//自己添加
}
/****************************** 主函數(shù) *********************************/
void main()
{
TMOD = 0x11;
TH0 = -30; // 定時器0
TL0 =39; // 定時中斷
TR0 = 1;
ET0 = 1;
TH1 = -3; // 定時器1
TL1 = 0; // 定時中斷
TR1 = 1;
ET1 = 1;
EA = 1;
Init_DS18B20();
if(Init_DS18B20())
{
bLED_light = 0; // 開機(jī)DS18B20正常就開背光
ucCloseDelaySec = 3; // 延時3秒關(guān)背光
}
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
nDelay100uS = 1100; // 等待AD轉(zhuǎn)換結(jié)束9位AD約100mS
INITVar();
while(1)
{
if(nDelay100uS == 0)
{
cCurrTemp = ReadTemperature();
if(ucFlashType != FLASH_PWM)
{
SetFanStatus();
}
}
if(cKEYCode != 0)
{
DisposeKey(); //處理鍵盤數(shù)據(jù)
}
UpdateDis(ucSystemStatus);
if(ucDelaySec == 0)
{
DisposeDelay(ucSystemStatus);//處理延時
}
if(ucCloseDelaySec == 0)
{
bLED_light = 1; //關(guān)背光
}
DisposeCurrTime();
}
}
/***************** 定時器1中斷:多任務(wù)分時處理 **************************/
void timer1() interrupt 3 //約840uS中斷1次,11次約為10mS,即100Hz波的1個周期
{
TH1 = -3; //定時器1重裝
//////////////////// 任務(wù)1:PWM輸出 //////////////////////////////////
if(bAC_Zero == 0)
{
if(ucCount < 100)
ucCount += 5; // 定時器1中斷記數(shù)有效控制寬度
}
else
{
ucCount = 0;
}
if(ucCount <= 100 - ucPWM)
{
bFAN = 1;
}
else
{
bFAN = 0;
}
///////////////////// 任務(wù)2:顯示刷新 ////////////////////////
ScanLED();
///////////////////// 任務(wù)3:延時 ////////////////////////////
if(nDelay100uS)
{
nDelay100uS--;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -