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

📄 lcd_main.c

📁 89c51的一个小程序
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <AT89x51.H>
#include <STRING.H>
#include <INTRINS.H>

#define LCM_RW P1_7 //定义引脚
#define LCM_RS P1_6
#define LCM_E P3_4
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识

#define Key_UP            P2_0    //上调温度
#define Key_DOWN          P2_1    //下调温度
#define Key_SET           P2_2    //设定键(温度设定,长按开电源)
#define RelayOutPort      P2_6    //继电器输出
#define tjrout		  			P1_5
#define TMPort			  		P1_1	  //DS1820 DataPort
#define optin							P2_3   //光藕开入
unsigned char code LCDDis[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20,0x2d}; //0-9的ASCII码,0x20为空,0x2d为负号

unsigned char i,j,cj,cj2,rs,rs2,tjrx,k;

static unsigned char bdata StateREG;	//可位寻址的状态寄存器
sbit DS1820ON = StateREG^0;	          //DS1820是否存在
sbit SetTF = StateREG^1;              //是否是在温度设置状态
sbit KeySETDown = StateREG^2;         //是否已按过SET键标识
sbit PowTF = StateREG^3;              //电源标识
sbit KeyTF = StateREG^4;		    //键盘是否允许

//sbit KeySETDowning = StateREG^5;			//SET是否正在按下
static unsigned char bdata TLV _at_ 0x0029;         //温度变量高低位
static unsigned char bdata THV _at_ 0x0028;
static signed char TMV;       //转换后的温度值
static unsigned char KeyV,TempKeyV;      //键值
static signed char TMRomV _at_ 0x0027;    //高温限制
static signed char TMSetV _at_ 0x0026;    //温度设定值
static unsigned char KSDNum;    //SET键连按时的采集次数
static unsigned char IntNum,IntNum2,IntNum3;    //中断发生次数,IntNum用于SET长按检测,IntNum2用于设定状态时LCD闪烁
static signed char LCD_One,LCD_Two,LCD_Three;  //LCD的显示位 LCD_One为十位,LCD_Two为个位
static signed char count_One,count_Two,count_Three,count_cj2;  //LCD的显示位 LCD_One为十位,LCD_Two为个位
static signed char LCD_One_set,LCD_Two_set,LCD_Three_set;	//设置时的LCD值
static unsigned char Sign, Sign_Set; //负号标识
static unsigned char ss,ss2,ss3; //负号标识

void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
unsigned char code relays_s[] =	{"Relay Status:   "};
unsigned char code cdle_net[] = {"    WellCome!   "};
unsigned char code test_ok[] = {"  Test Over! :) "};
unsigned char code email[] = {" Press Power Key"};
unsigned char cur_temper[]={"Current Temp:   "};
unsigned char cur_count[]= {"Tjr Count :     "};
unsigned char cur_temper_set[]={"T_Set:          "};
unsigned char code null[] 		={"                "};

unsigned char BF = 0;	//定时中断标志,=1时显示当前温度值,=0显示欢迎

void main(void)
{
	void InitDS1820(void);   //定义函数
	void ROMDS1820(void);
	void TMVDS1820(void);
	void TMRDS1820(void);
	void TMWDS1820(void);
	void dtod(void);
	void TMREDS1820(void);
	void TMERDS1820(void);
	void ReadDS1820(void);
	void WriteDS1820(void);
	void Delay_510(void);
	void Delay_110(void);
	void Delay_10ms(void);
	void Delay_4s(void);
	void V2ToV(void);
	void tjr(void);

	StateREG = 0;   //初始化变量
	//SetTF = 1;	
	PowTF = 1;			//关电源
	//KeyTF = 1;
    tjrout=1;
	tjrx=0;
	cj	=0;
	cj2 =0;
	k		=0;
	THV = 0;
	TLV = 0;
	TMV = 0;
	KeyV = 0;
	TempKeyV = 0;
	KSDNum = 0;
	IntNum = 0;
	IntNum2 = 0;
	IntNum3 = 0;
	InitDS1820(); //初始化
	ROMDS1820(); 	//跳过ROM
	TMERDS1820();  //E2PRAM中温度上限值调入RAM
	InitDS1820(); //初始化
	ROMDS1820(); 	//跳过ROM
	TMRDS1820(); 	//读出温度指令
	ReadDS1820(); //读出温度值和上限值
	TMSetV = TMRomV;  //拷贝保存在DS18B20ROM里的上限值到TMSetV
	Delay400Ms(); //启动等待,等LCM讲入工作状态
	LCMInit(); //LCM初始化
	Delay5Ms(); //延时片刻(可不要)
	EA = 1;					//允许CPU中断
	ET0 = 1; 				//定时器0中断打开
	ET1 = 1;
	TMOD = 0x11;			//设定时器0为模式1,16位模式
	TH0=0xB1;
	TL0=0xDF;				//设定时值为20000us(20ms)
	TH1=0xB1;
	TL1=0xDF;				//设定时值为20000us(20ms)
	TR0 = 1;				//开始定时
  TR1 = 1;
	do
		{
			if (BF==2)
			{
				
				
				DisplayListChar(0, 1, test_ok);	//显示欢迎信息
				DisplayListChar(0, 0, null);	
				DisplayListChar(0, 2, null);
				DisplayListChar(0, 3, null);
				Delay_4s();
				//for (j=0;i<4;j++)
				//{
				for (i=0;i<16;i++)
						{
							Delay_10ms();
							Delay_10ms();									
							DisplayOneChar(j,1,null[i]);//LCD的第二行显示设置温度和继电器状态
							Delay_10ms();									
												}
				//}
				 PowTF = 1;         //电源标识关  
					EA=0;
					BF=0;
					cj=0;
					cj2=0;
					tjrout=1;
				
				}
			if (BF==0)
				{
					for (j=0;j<4; j++)
					{
					for (i=0;i<16;i++)
						{
							Delay_10ms();				
							DisplayOneChar(i,j,null[i]);//LCD的第二行显示设置温度和继电器状态
					//		DisplayOneChar(i,1,null[i]);
						//	DisplayOneChar(i,2,null[i]);
							//DisplayOneChar(i,3,null[i]);
							//Delay_10ms();
							//Delay_10ms();									
							
				}
			 		}
					DisplayListChar(0, 0, cdle_net);	//显示欢迎信息
					DisplayListChar(0, 1, email);
					DisplayListChar(0, 2, null);
					DisplayListChar(0, 2, null);
					Delay_4s();
					//PowTF = 1;
					EA=1;
					cj=0;
					cj2=0;
					tjrout=1;
									}
			if (BF==1)
				{
					for (i=0;i<16;i++)
					{	
							DisplayOneChar(i,0,cur_temper[i]);//LCD的第1行显示当前温度
						}				
					for (i=0;i<16;i++)
						{
							DisplayOneChar(i,1,cur_temper_set[i]);//LCD的第二行显示设置温度和继电器状态
						}
						//ReadDataLCM();//测试用句无意义	
					for (i=0;i<16;i++)
					{
						DisplayOneChar(i,2,cur_count[i]);
						}
					for (i=0;i<13;i++)
					{
						DisplayOneChar(i,3,relays_s[i]);
						}	
					DisplayOneChar(13,3,ss);
					DisplayOneChar(14,3,ss2);
					DisplayOneChar(15,3,ss3);
					EA=1;
							}

}
while(1);
}
//定时器1中断处理

void tjrtime1(void) interrupt 3 using 3
{
	TH1=0xB1;
	TL1=0xDF;				//设定时值为20000us(20ms)
	dtod();
	if (!optin)
	{
		rs++;
   			}
	if (BF==1)
  {
	  if(tjrx==50)
	  {
			tjrout=~tjrout;
		 	tjrx=0;
			if(cj==99)
			{	
				cj=0;
				if(cj2==9)
				{
		 			cj2=0;
		 			BF=2;
									}
		 cj2++;
					}
			cj++;
		if(rs>40)
		{
			rs2=1;
			rs=0;
						}
			else
			rs2=0;
			rs=0;
						}
			tjrx++;
							}	
		 if (rs2==1)   //根据采集到的继电器状态
					{
					ss =0x20;	//" "
					ss2=0x4f;	//"O"
					ss3=0x4e;	//"N"
					}
		  else
					{
						ss=0x4f;	//"O"
						ss2=0x46;	//"F"
						ss3=0x46;	//"F"
					}

	}
//定时器0中断外理中键扫描和处理要显示的值
void KeyAndDis_Time0(void) interrupt 1 using 2
{
	TH0=0xB1;
	TL0=0xDF;				//设定时值为20000us(20ms)

	if (!Key_UP)	KeyV = 1;
	if (!Key_DOWN)	KeyV = 2;
	if (!Key_SET)	KeyV = 3;
	//KeySETDowning = 0;  //清除
	if (KeyV != 0)      //有键按下
		{
			Delay_10ms();   //延时防抖  按下10ms再测
			if (!Key_UP)	TempKeyV = 1;
			if (!Key_DOWN)	TempKeyV = 2;
			if (!Key_SET)	TempKeyV = 3;

			if (KeyV == TempKeyV)   //两次值相等为确定接下了键
				{
					if (KeyV == 3)      //按下SET键,如在SET状态就退出,否则进入
						{
							//KeySETDowning = 1; //表明SET正在按下
							PowTF = 0;      //电源标识开
							if (!KeyTF)		//KeyTF=0,键盘允许
								if (SetTF)
									{
										SetTF = 0;    //标识位标识退出设定
										InitDS1820(); //初始化
										ROMDS1820(); 	//跳过ROM
										TMWDS1820(); 	//写温度上限指令
										WriteDS1820(); 	//写温度上限到DS18B20ROM
										WriteDS1820(); 	//写温度上限到DS18B20ROM
										WriteDS1820(); 	//写温度上限到DS18B20ROM
										InitDS1820(); //初始化
										ROMDS1820(); 	//跳过ROM
										TMREDS1820(); 	//温度上限值COPY回E2PRAM
										
										//	V2ToV();
									}
								else
									SetTF = 1;
							if (!KeySETDown) //没有第一次按下SET时,KeySETDown标识置1
								KeySETDown = 1;
							else
								KSDNum = KSDNum + 1;  //前一秒内有按过SET则开始计数
						}
					if (SetTF==1)  //在SET状态下
						{
							cur_temper_set[9]=0x3d;		//"="	显示set标志
							cur_temper_set[10]=0x73;	//"s"
							cur_temper_set[11]=0x65;	//"e"
							cur_temper_set[12]=0x74;	//"t"
							if ((KeyV == 1) && (!KeyTF))
								TMSetV = TMSetV + 1;    //上调温度
							if ((KeyV == 2) && (!KeyTF))
								TMSetV = TMSetV - 1;    //下调温度
							if (TMSetV <= -55)          //限制温度上下限
								TMSetV = -55;
							if (TMSetV >= 125)
								TMSetV = 125;
						}
					if ((!KeyTF) && (IntNum3 == 0))
						{
							KeyTF = 1; //当键盘处于可用时,锁定
							cur_temper_set[9]=0x20;		//	显示空白
							cur_temper_set[10]=0x20;
							cur_temper_set[11]=0x20;
							cur_temper_set[12]=0x20;
						}
				}

				if (KeySETDown)         //在2秒内按下了SET则计中断发生次数用于长按SET时计时用
					IntNum = IntNum + 1;  
				if (IntNum > 55)     //中断发生了55次时(大约1.2秒)75为1.5秒左右
					{
						IntNum = 0;
						KeySETDown = 0;
						if (KSDNum == 55)      //如一直长按了SET1.2秒左右
							{
								RelayOutPort = 1;  //关闭继电器输出
								PowTF = 1;         //电源标识关  
								//Delay_4s();        //延时
								IntNum = 0;
								IntNum2 = 0;
								IntNum3 = 0;
								BF = 0;			//显示欢迎信息		
								EA=0;
							}
						KSDNum = 0;
					}
		}

		KeyV = 0;
		TempKeyV = 0;   //清空变量准备下次键扫描
		if (PowTF==0)
			{
				InitDS1820();	//初始化
				ROMDS1820(); 	//跳过ROM
				TMVDS1820();  //温度转换指令
				Delay_510();
				Delay_510();  //延时等待转换完成
				InitDS1820(); //初始化
				ROMDS1820(); 	//跳过ROM
				TMRDS1820(); 	//读出温度指令
				ReadDS1820(); //读出温度值
				V2ToV();        //转换显示值
				
				if (TMV > TMSetV)   //根据采集到的温度值控制继电器
					{
						RelayOutPort = 0;
						cur_temper_set[13]=0x20;	//" "
						cur_temper_set[14]=0x4f;	//"O"
						cur_temper_set[15]=0x4e;	//"N"
					}
				else
					{
						RelayOutPort = 1;
						cur_temper_set[13]=0x4f;	//"O"
						cur_temper_set[14]=0x46;	//"F"
						cur_temper_set[15]=0x46;	//"F"
					}

				if (SetTF)	IntNum2 = IntNum2 + 1; //用于闪烁计数
				if (IntNum2 > 50 )	IntNum2 = 0;
				if (KeyTF) IntNum3 = IntNum3 + 1; //用于防止按键连按
				if (IntNum3 > 25) 
					{
						IntNum3 = 0;
						KeyTF = 0;
					}
				if ((SetTF) && (IntNum2 < 25)) goto InitEnd;  //计数在后半段时显示
				BF=1;	//让显示温度值
				EA=0;	//关中断
			}
			InitEnd:;
}



void V2ToV(void)	//数值转换
{
	TLV = TLV >> 4;			
	THV = THV << 4;			//读出的高低位数值移位
	TMV = TLV | THV;		//合并高低位放入TM为实际温度值
	Sign = 0; Sign_Set=0;
    Sign_Set = TMSetV >> 7;          //取符号
    Sign = TMV >> 7;

	if (Sign)
		{
    		LCD_One = (~TMV) / 100;							//转换百位值		
    		LCD_Two = ((~TMV) - LCD_One * 100)/10;
			LCD_Three = (~TMV) - LCD_One * 100 - LCD_Two * 10;
		}
	else
		{
			LCD_One = (TMV) / 100;							//转换百位值		
    		LCD_Two = (TMV - LCD_One * 100)/10;
			LCD_Three = TMV - LCD_One * 100 - LCD_Two * 10;
		}

	if (Sign_Set)
		{
    		LCD_One_set = (~(TMSetV-1)) / 100;          //SET状态下显示设定值
    		LCD_Two_set = ((~(TMSetV-1)) - LCD_One_set * 100)/10;
			LCD_Three_set = (~(TMSetV-1)) - LCD_One_set * 100 - LCD_Two_set * 10;
		}
	else
		{
			LCD_One_set = (TMSetV) / 100;          //SET状态下显示设定值
    		LCD_Two_set = (TMSetV - LCD_One_set * 100)/10;
			LCD_Three_set = TMSetV - LCD_One_set * 100 - LCD_Two_set * 10;
		}

//转LCD字段  温度值	
	if (LCD_One) //超过百时十位的处理

⌨️ 快捷键说明

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