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

📄 shuiwenkongzhi.c

📁 水温控制系统。。。通过单片机控制水温。。电子设计大赛训练题目。。。通过编译可以使用
💻 C
字号:
#include<reg51.h>

#define uchar unsigned char
#define uint unsigned int 

sbit tempra=P1^0;		//继电器控制端口
sbit DS=P1^7;			//DS18B20数据输出

void mdelay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

/*~~~~~~~~~~~~液晶显示定义~~~~~~~~~~~~~~~~*/
sbit E=P2^4;
sbit RS=P2^6;
sbit RW=P2^5;
const uchar NoDisp=0;
const uchar NoCur=1;
const uchar CurNoFlash=2;
const uchar CurFlash=3;

/*~~~~~~~~~~~~液晶显示驱动~~~~~~~~~~~~~~~~*/
void WaitIdle()
{
	
	RS=0;
	RW=1;			  
	E=1;
	mdelay(5);
	while((P0&0x80)==0x80)//控制字最高位为'1' 才能允许读写操作
	{
		 E=0;   		  //这两句protues仿真必须加;仿真器仿真也通过。
		 E=1;  
	};
	E=0;
}

void LcdWcn(uchar c)	//无忙时检测 向液晶写入命令
{
	RS=0;
	RW=0;
	P0=c;
	mdelay(5);
	E=1;
	mdelay(5);
	E=0;
}

void LcdWc(uchar c)		//有忙时检测 向液晶写入命令		
{
	WaitIdle();
	LcdWcn(c);
}

void LcdWd(uchar c)		//有忙时检测 向液晶写入数据
{
	WaitIdle();
	RS=1;
	RW=0;
	P0=c;
	mdelay(5);
	E=1;
	mdelay(5);
	mdelay(5);
	E=0;
}

void ClrLcd()			//显示清屏
{
	LcdWc(0x01);
}

void RstLcd()			//初始化
{
	E=0;
	LcdWc(0x38);		//显示模式设置 16*2
	LcdWc(0x0f);		//开显示 开光标 光标闪烁
	LcdWc(0x06);		//读或写一个字节侯 光标加1 指针加1
	LcdWc(0x01);		//显示清屏
}

void SetCur(uchar Para)				
{
	mdelay(2);
	switch(Para)
	{								//光标模式设置
		case 0:LcdWc(0x08);break;	// NoDisp
		case 1:LcdWc(0x0c);break;	// NoCur
		case 2:LcdWc(0x0e);break;	// CurNoFlash
		case 3:LcdWc(0x0f);break;	// CurFlash
		default:break;
	}
}

void LcdPos(uchar xPos,uchar yPos)
{
	uchar tmp;
	xPos&=0x0f;			//列定位 最大为16列
	yPos&=0x01;			//行定位 最大为2行
	if(yPos==0)
		tmp=xPos;
	else
		tmp=xPos+0x40;	//第二行第一列的地址为 0x80+0x40
	tmp|=0x80;			//第一行第一列的地址为 0x80
	LcdWc(tmp);
}

void WriteChar(uchar c,uchar xPos,uchar yPos) 
{						//在指定位置写入一个字符
	LcdPos(xPos,yPos);
	LcdWd(c);
}

void WriteString(uchar *s,uchar xPos,uchar yPos)
{						//在指定位置写入一个字符串
	uchar i;
	if(*s==0)
		return;
	for(i=0;;i++)
	{
		if(*(s+i)==0)
			break;
		WriteChar(*(s+i),xPos,yPos);
		xPos++;
		if(xPos>=15)
			break;	
	}
}
/*~~~~~~~~~~~~~~~~~~18B20驱动~~~~~~~~~~~~~~~~~~~*/
void dsreset(void)      // DS18B20初始化
{
	uint i;               
	DS=0;				// 首先拉低,要求480us
	i=103;
	while(i>0)i--;
	DS=1;				// 上升沿,要求15~60us
	i=4;
	while(i>0)i--;
}
void rxwait()			//等待应答脉冲
{
	uint i;
	while(DS);
	while(~DS);
	i=8;while(i>0)i--;
}
bit tmpreadbit(void)    //读一位
{
   uint i;
   bit dat;
   DS=0;
   i++;          		//1us延时
   DS=1;				//15us内,主机必须停止将DS引脚置低
   i++;i++;   			//15us延时
   dat=DS;
   i=8;while(i>0)i--;	//读时隙不低于60us延时
   return (dat);
}
uchar tmpread(void)   	// 读一个字节
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();
    dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);          //将一个字节数据返回
}
void tmpwritebyte(uchar dat)   //写一个字节到DS18B20里
{                           
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)     //写1部分
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {
      DS=0;       //写0部分
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }
  }
}
void tmpchange(void)  	//发送温度转换命令
{
  dsreset();			//初始化DS18B20
  rxwait();      		//等待应答脉冲       
  mdelay(1);            //延时
  tmpwritebyte(0xcc);   // 跳过序列号命令
  tmpwritebyte(0x44);   //发送温度转换命令
}
uint tmp()              //获得温度
{
  float tt;
  uchar a,b;
  uint temp; 
  dsreset();
  rxwait();				//等待应答脉冲
  mdelay(1);
  tmpwritebyte(0xcc);   
  tmpwritebyte(0xbe);   //发送读取数据命令
  a=tmpread();          //连续读两个字节数据
  b=tmpread();
  temp=b;
  temp<<=8;            //出厂默认设置为12位分辨率
  temp=temp|a;         //两字节合成一个整型变量。
  tt=temp*0.0625;      //得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。
  temp=tt*1000+0.5;    //放大百倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
  return temp;     	   //返回温度值
}

void main()
{
	uchar xPos0,yPos0,xPos1,yPos1,i;
	uchar * s0;
	uint temp;
	uchar A1,A2,A3,A4,A5;
	RstLcd();
	ClrLcd();
	SetCur(NoCur);

	xPos0=0;yPos0=0;
	s0="Temperature is:";
	WriteString(s0,xPos0,yPos0);
	xPos1=2;yPos1=1;			//显示小数点 温度单位
	WriteChar('.',xPos1,yPos1);
	xPos1=6;yPos1=1;
	WriteChar(0xdf,xPos1,yPos1);
	xPos1=7;yPos1=1;
	WriteChar(0x43,xPos1,yPos1);	
	while(1)
	{
		for(i=0;i<=5;i++)
		{	
			tmpchange();
			temp=tmp();
			A1=temp/10000;
		   	A2=temp%10000/1000;
		   	A3=temp%1000/100;
			A4=temp%100/10;
			A5=temp%10;
			if(i>1)
			{
				xPos1=0;yPos1=1;
				WriteChar(0x30+A1,xPos1,yPos1);
				xPos1=1;yPos1=1;
				WriteChar(0x30+A2,xPos1,yPos1);
				xPos1=3;yPos1=1;
				WriteChar(0x30+A3,xPos1,yPos1);
				xPos1=4;yPos1=1;
				WriteChar(0x30+A4,xPos1,yPos1);
				xPos1=5;yPos1=1;
				WriteChar(0x30+A5,xPos1,yPos1);
			}
			if(temp<30000)
				tempra = 0;		//继电器打开 加热
			if(temp>30000)
				tempra = 1;		//继电器关闭 冷却
			
			mdelay(300);
		}
	}
}

⌨️ 快捷键说明

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