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

📄 text1.c

📁 这是一段用C语言编写的使用89C51单片机和测温芯片18B20制作的测温系统的源程序。
💻 C
字号:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

uchar tplsb,tpmsb;
uint temp,tempx;
sbit DQ=P2^0;
uchar code table[1]=".";
uchar code table1[10]="0123456789";


void delay(uint t);
bit lcd1602_busy(void);
void lcd1602_wrcmd(unsigned char lcdcmd);
void lcd1602_wrdata(uchar lcddata);
void lcd1602_clear(void);
void lcd1602_init(void);
uchar keyscan(void);
void chuli(uchar key);
uchar zhuan(uchar key);


//数据口定义
#define lcd1602_bus P3			 

//引脚定义
sbit rs_1602=P2^5;	     
sbit rw_1602=P2^6;
sbit e_1602=P2^7;

/* 延时t毫秒 */
void delay(uint t)
{
	uint i;
	while(t--)
	{
		/* 对于11.0592M时钟,约延时1ms */
		for (i=0;i<125;i++)
		{}
	}
} 


/***********忙判断标志,返回一个位BF********************/
bit lcd1602_busy(void)
{
	uchar busy_flag;
	rs_1602=0;
	rw_1602=1;
	_nop_();
	e_1602=1;
	_nop_();
	lcd1602_bus=0xff;
	busy_flag=lcd1602_bus;	 //e在高电平时读 
	e_1602=0;
	return (bit)(busy_flag&0x80);    //BF=1; BUSY  返回一个位
}

/********写命令,有两个参数,一个是要写的命令控制字,
第二个是用来控制是否进行忙标志的判断。
busyflag=1;
判断: 为0 
***************/
void lcd1602_wrcmd(unsigned char lcdcmd)
{
   	while(lcd1602_busy());	   //等待空闲
	lcd1602_bus=lcdcmd;
	rs_1602=0;
	rw_1602=0;
	_nop_();
	e_1602=1;
	_nop_();
	_nop_();
	e_1602=0;      //产生一个下沿	  
}



/***************向液晶写数据******************/
void lcd1602_wrdata(uchar lcddata)
{
 while(lcd1602_busy());	      //等待空闲
 lcd1602_bus=lcddata;		  //在下沿的时候写数据
 rs_1602=1;
 rw_1602=0;
 _nop_();
 e_1602=1;
 _nop_();
 _nop_();
 e_1602=0;
 //lcd_bus=0xff;
}


/************液晶的清屏************/
void lcd1602_clear(void)
{
  lcd1602_wrcmd(0x01);	   //液晶清屏控制字	并延时>40us
  delay(100);
}

/***********1602液晶的初始化***************/
void lcd1602_init(void)
{
  lcd1602_wrcmd(0x38);	    	//功能设置-----8位数据接口,两行显示,5*7点阵字符显示
  delay(100);
  lcd1602_wrcmd(0x0e);	       //显示开关控制----显示开关开,光标开关关,闪烁开关关
  delay(100);
  lcd1602_wrcmd(0x06);	       //输入方式设置,AC自增1, S=0;
  delay(100);		   
  lcd1602_wrcmd(0x01);         //清屏
  delay(100);
}

/* 产生复位脉冲初始化DS18B20 */
void TxReset(void)
{
	uint i;
	DQ = 0;

	/* 拉低约900us */
	i = 100;
	while (i>0)	i--;	
	
	DQ = 1;				// 产生上升沿
	i = 4;
	while (i>0)	i--;
}

/* 等待应答脉冲 */
void RxWait(void)
{
	uint i;
	while(DQ);
	while(~DQ);			// 检测到应答脉冲 
	i = 4;
	while (i>0)	i--;
}

/* 读取数据的一位,满足读时隙要求 */ 
bit RdBit(void)
{
	uint i;
	bit b;
	DQ = 0;
	i++;
	DQ = 1;
	i++;i++;			// 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
	b = DQ;
	i = 8;
	while(i>0) i--;
	return (b);
}

/* 读取数据的一个字节 */
uchar RdByte(void)
{
	uchar i,j,b;
	b = 0;
	for (i=1;i<=8;i++)
	{
		j = RdBit();
		b = (j<<7)|(b>>1);
	}
	return(b);
}

/* 写数据的一个字节,满足写1和写0的时隙要求 */
void WrByte(uchar b)
{
	uint i;
	uchar j;
	bit btmp;
	for(j=1;j<=8;j++)
	{
		btmp = b&0x01;
		b = b>>1;		// 取下一位(由低位向高位)
		if (btmp)
		{
			/* 写1 */
			DQ = 0;
			i++;i++;	// 延时,使得15us以内拉高
			DQ = 1;
			i = 8;
			while(i>0) i--;	// 整个写1时隙不低于60us 
	   	}
		else
		{
			/* 写0 */
			DQ = 0;			
			i = 8;
			while(i>0) i--;	// 保持低在60us到120us之间
			DQ = 1;
			i++;
			i++;
		}
	}
}

/* 启动温度转换 */
void convert(void)
{
	TxReset();			// 产生复位脉冲,初始化DS18B20
	RxWait();			// 等待DS18B20给出应答脉冲
	delay(1);			// 延时
	WrByte(0xcc);		// skip rom 命令
	WrByte(0x44);		// convert T 命令
}

/* 读取温度值 */
void RdTemp(void)
{
	TxReset();			// 产生复位脉冲,初始化DS18B20 
	RxWait();			// 等待DS18B20给出应答脉冲
	delay(1);			// 延时
	WrByte(0xcc);		// skip rom 命令
	WrByte(0xbe);		// read scratchpad 命令
	tplsb = RdByte();	// 温度值低位字节(其中低4位为二进制的“小数”部分)
	tpmsb = RdByte();	// 高位值高位字节(其中高5位为符号位)		
}


/************键盘扫描*************/
uchar keyscan(void)
{
	uchar scancode,tmpcode;
	P1 = 0xf0;
	if ((P1&0xf0)!=0xf0)
	{
		delay(125);
		if ((P1&0xf0)!=0xf0)
		{
			scancode = 0xfe;
			while((scancode&0x10)!=0)
			{
				P1 = scancode;
				if ((P1&0xf0)!=0xf0)
				{
					tmpcode = (P1&0xf0)|0x0f;
					return((~scancode)+(~tmpcode));
				}
				else scancode = (scancode<<1)|0x01;	
			}
		}
	}
	return(0);
}

void gettemp()
{
   delay(1);		// 延时1ms
   convert();		// 启动温度转换,需要750ms
   delay(1000);	// 延时1s
   RdTemp();
   temp=(tpmsb&0x07)*16+((tplsb&0xf0)>>4);
   tempx=tplsb&0x0f;
}


/* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
   tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
   5位为符号位。真正通过数码管输出时,需要进行到十进
   制有符号实数(包括小数部分)的转换。              */
void main(void)
{
    uchar key,a[2],b[4];
	char i;
	uint d;
    delay(2);
    lcd1602_bus=0xff;
    lcd1602_init();
    lcd1602_clear();
    while(1)
	{	    
		  gettemp();
		  a[1]=temp/10;
		  temp=temp%10;
		  a[0]=temp;
		  d=tempx*625;
		  b[0]=d/1000;
		  d=d%1000;
		  b[1]=d/100;
		  d=d%100;
		  b[2]=d/10;
		  d=d%10;
		  b[3]=d;
		  lcd1602_wrcmd(0x80);
		  for(i=1;i>=0;i--)
		      lcd1602_wrdata(table1[a[i]]);
		  lcd1602_wrdata(table[0]);
		  for(i=0;i<4;i++)
		      lcd1602_wrdata(table1[b[i]]);
		
	}
}

⌨️ 快捷键说明

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