⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 18b20.c

📁 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秒关背光
#define DELAY_INPUT	5		//没按键,延时5秒返回显示温度
#define KEYCODE_UP	0x1		//加温度
#define KEYCODE_DOWN	0x2		//减温度
#define KEYCODE_FAN	0x4		//设置风速
#define KEYCODE_ONOFF 	0x8		//开关风机
#define KEYCODE_TIME	0x6		//设置时间
#define KEYCODE_PWM	0xc		//设置PWM
#define WAIT_cCurrTemp	0
#define MAX_TEMP	32
#define MIN_TEMP	15

sbit bDQ 	= 	P1^0; 		// DS1820数据线
sbit bLED_light	=	P1^1;		// LED 背光驱动,低有效
sbit bKey1	=	P1^2;		// 键盘扫描线1,高有效
sbit bKey2	=	P1^3;		// 键盘扫描线2,高有效
sbit bKey3	=	P1^4;		// 键盘输入线1,低有效
sbit bKey4	=	P1^5;		// 键盘输入线2,低有效
sbit bFAN	=	P0^5;		// 开风机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;			// 开机状态=1
uchar ucTimer;
/**************** LED显示相关变量 ********************/
//				   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;			/* 数码管位选控制 */
uchar ucLEDData[4];			/* 临时显示缓冲数组 */
uchar ucLEDFlash[5];			/* 显示缓冲数组 */
bit   bNeg;				/* 负号标志 */
uchar ucFlashType;
bit   bFlash;
uchar ucCurrSec;
uchar ucSystemStatus;
uchar ucDelaySec;			//切换延时秒数
uchar ucCloseDelaySec;			//关背光延时秒数
uchar aucCurrTime[2];
uchar aucTmpValue[2];
uchar ucFanSpeed;
char  cCurrTemp;
char  cSetTemp;
/**********************************************************************/
uchar ucLongDelay;			//长按键
uchar ucDelayKey;
uint  nDelay100uS;
char  cKEYCode;
bit   bStill;
bit   bUpdateDisOK;

/****************************** 函数声明 ******************************/
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;    				// 单片机将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;			// 在延时时间内18B20有应答证明初始化成功
		}
	}
	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); 	// 启动温度转换
 		nDelay100uS = 1100;		// 等待AD转换结束9位AD约100mS
		ET0 = 1;
		ET1 = 1;
	}
	else
	{
		return(99);
	}
	bNeg = 0;
	if((uT.T_byte[0] & 0x80) != 0)// 负数标志位为1?
	{
		uT.T = ~uT.T+1;			// 转换成正数
		bNeg = 1;			// 负数标志置位
	}
	uT.T += 8;				// 四舍五入
	uT.T >>= 4;				// 取整
	return(uT.T_byte[1]);
}

/********************* 初始化变量 **********************/
void INITVar(void)
{
	//自己添加
}

/****************************** 主函数 *********************************/
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;			// 开机DS18B20正常就开背光
		ucCloseDelaySec = 3;		// 延时3秒关背光
	}
	WriteOneChar(0xCC); 			// 跳过读序号列号的操作
	WriteOneChar(0x44); 			// 启动温度转换
	nDelay100uS = 1100;			// 等待AD转换结束9位AD约100mS

	INITVar();
	while(1)
	{
		if(nDelay100uS == 0)
		{
			cCurrTemp = ReadTemperature();
			if(ucFlashType != FLASH_PWM)
			{
				SetFanStatus();
			}
		}

		if(cKEYCode != 0)
		{
			DisposeKey();		//处理键盘数据
		}

		UpdateDis(ucSystemStatus);

		if(ucDelaySec == 0)
		{
			DisposeDelay(ucSystemStatus);//处理延时
		}

		if(ucCloseDelaySec == 0)
		{
			bLED_light = 1;		//关背光
		}

		DisposeCurrTime();
	}	
}

/***************** 定时器1中断:多任务分时处理 **************************/
void timer1() interrupt 3			//约840uS中断1次,11次约为10mS,即100Hz波的1个周期
{
	TH1 = -3;						//定时器1重装
//////////////////// 任务1:PWM输出 //////////////////////////////////
	if(bAC_Zero == 0)
	{
		if(ucCount < 100)
		ucCount += 5;				// 定时器1中断记数有效控制宽度
	}
	else
	{
		ucCount = 0;
	}
	if(ucCount <= 100 - ucPWM)
	{
		bFAN = 1;
	}
	else
	{ 
		bFAN = 0;
	}
///////////////////// 任务2:显示刷新 ////////////////////////
	ScanLED();
///////////////////// 任务3:延时 ////////////////////////////
	if(nDelay100uS)
	{
		nDelay100uS--;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -