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

📄 l8279.c

📁 一个锅炉温度控制程序
💻 C
字号:
/*
  L8279.c
  键盘和显示器   键盘和显示器 
	


  王占成
  zcwang@mail.ustc.edu.cn
  ustcwzc@sina.com.cn
  13856067473
*/


/*

  键盘部分

*/

/*********************************************************/
/***包含头文件***/
#include <absacc.h>
#include "watchdog.h"
#include "L8279.h"
#include "Pid.h"
#include "Xdata.h"
#include <reg52.h>
#include <math.h>
#include <string.h>


idata BYTE LEDStatus;
idata BYTE KeyCode;

code BYTE NumInTable[10] = {
	Num0,
	Num1,
	Num2,
	Num3,
	Num4,
	Num5,
	Num6,
	Num7,
	Num8,
	Num9
};
 
/*********************************************************/
/***函数定义***/

/*********************************************************/
/***键盘扫描程序***/
void ScanKey()
{
	idata BYTE FIFOStatus;
	FIFOStatus = CMD8279;
	if(FIFOStatus&0x0F) {			/*FIFO RAM中有键被按下*/
		CMD8279 = 0x40;				/*读FIFO RAM*/
		KeyCode = DATA8279;
		NewLEDStatus = TRUE;
	}
	else {
		NewLEDStatus = FALSE;
	}
	KeyFunction();
	return;
}

/*********************************************************/
/***按健选择键***/
void KeyFunction()
{
	if(NewLEDStatus == TRUE){
		switch(KeyCode) {
		case K_Sys:
			//DispT();
			OnSysDown();
			break;
		case K_Enter:
			//DispP();
			OnEnterDown();
			break;
		case K_Cancel:
			//DispI();
			OnCancelDown();
			break;
		case K_Led0:
			//DispD();
			OnLed0Down();
			break;
		case K_Led1:
			//DispSetP();
			OnLed1Down();
			break;
		case K_Led2:
			//DispP();
			OnLed2Down();
			break;
		case K_Led3:
			//DispF();
			OnLed3Down();
			break;
		case K_NULL:
			//DispT();
			DispT();
			break;
		}
		NewLEDStatus = FALSE;
	}
	return;
}

/*********************************************************/
/***功能选择键***/
void OnSysDown()	
{
	
	switch (LEDStatus) {
	case S_NULL:			/*前面正在显示温度*/
		DispP();				
		break;
	case S_P:				/*前面显示字符P*/
		DispI();
		break;
	case S_I:				/*前面显示字符I*/
		DispD();
		break;
	case S_D:				/*前面显示字符D*/
		DispSetP();
		break;
	case S_SP:				/*前面显示字符SP*/
		DispT();
		break;
	default:
		break;
	}
	return;
}

/*********************************************************/
/***确定键***/
void OnEnterDown()					/*确定键处理函数*/
{
	switch(LEDStatus){
	case S_NULL:                    /***==前边显示温度则显示到计时==**/
		DispF();
		break;

	case S_P:						/*要设定P*/
		DispPVal();					/*显示当前的P值*/
		break;
	case S_I:						/*要设定I*/
		DispIVal();					/*显示当前的I值*/
		break;
	case S_D:						/*要设定D*/
		DispDVal();					/*显示当前的D值*/
		break;
	case S_SP:						/*要设定SetPoint*/
		DispSetPVal();				/*显示当前的SetPoint值*/
		break;
	case S_P_Val:			
		LEDDataToRAM();				/*将LED显示的值存入内存*/
		DispT();
		break;
	case S_I_Val:			
		LEDDataToRAM();			
		DispT();
		break;
	case S_D_Val:				
		LEDDataToRAM();			
		DispT();
		break;
	case S_SP_Val:				
		LEDDataToRAM();			
		DispF();
		break;
	case S_F:
		DispFVal();
		break;
	case S_F_Val:
		LEDDataToRAM();
		DispT();
		break;
	default:
		break;						/*其它情况不响应*/
	}	
	return;
}


/*********************************************************/
/***取消键***/
void OnCancelDown()					/*取消键处理函数*/
{
	DispT();						/*取消任何改动,重新显示温度*/
	return;
}

/*********************************************************/
/***0号LED键***/
void OnLed3Down()					/*循环改动一个LED的显示值*/
{
	idata BYTE Num;
	idata BYTE i;
	idata BYTE LEDRamStatus;
	CMD8279 = 0x60;
	LEDRamStatus = DATA8279;

	if(LEDRamStatus != 0x00){
		if(	(LEDStatus == S_P_Val) || 
			(LEDStatus == S_I_Val) || 
			(LEDStatus == S_P_Val) || 
			(LEDStatus == S_SP_Val)||
			(LEDStatus == S_F_Val))  {
			for(i=0;i<10;i++){
				if(LEDRamStatus == NumInTable[i]){
					Num = i;
					break;
				}
			}
		
			Num++;								/*下一位数字*/
			if((Num>=0)&&(Num<=9))
				WriteLed(0,NumInTable[Num]);
			else 
				WriteLed(0,NumInTable[0]);
		}						/*将第1个LED的显示内容更新*/
	}
	return;
}

/*********************************************************/
/***1号LED键***/
void OnLed2Down()						/*循环改动一个LED的显示值*/
{
	idata BYTE Num;
	idata BYTE i;
	idata BYTE LEDRamStatus;
	CMD8279 = 0x61;
	LEDRamStatus = DATA8279;

	if(LEDRamStatus != 0x00){
		if(	(LEDStatus == S_P_Val) || 
			(LEDStatus == S_I_Val) || 
			(LEDStatus == S_P_Val) || 
			(LEDStatus == S_SP_Val)||
			(LEDStatus == S_F_Val) )  {
			for(i=0;i<10;i++){
				if(LEDRamStatus == NumInTable[i]){
					Num = i;
					break;
				}
			}
		
			Num++;								/*下一位数字*/
			if((Num>=0)&&(Num<=9))
				WriteLed(1,NumInTable[Num]);
			else 
				WriteLed(1,NumInTable[0]);
		}						/*将第1个LED的显示内容更新*/
	}
	return;
}

/*********************************************************/
/***2号LED键***/
void OnLed1Down()						/*循环改动一个LED的显示值*/
{
	idata BYTE Num;
	idata BYTE i;
	idata BYTE LEDRamStatus;
	CMD8279 = 0x62;
	LEDRamStatus = DATA8279;

	if(LEDRamStatus != 0x00){
		if(	(LEDStatus == S_P_Val) || 
			(LEDStatus == S_I_Val) || 
			(LEDStatus == S_P_Val) || 
			(LEDStatus == S_SP_Val)||
			(LEDStatus == S_F_Val))  {
			for(i=0;i<10;i++){
				if(LEDRamStatus == NumInTable[i]){
					Num = i;
					break;
				}
			}
		
			Num++;								/*下一位数字*/
			if((Num>=0)&&(Num<=9))
				WriteLed(2,NumInTable[Num]);
			else 
				WriteLed(2,NumInTable[0]);
		}						/*将第1个LED的显示内容更新*/
	}
	return;
}

/*********************************************************/
/***3号LED键***/
void OnLed0Down()						/*循环改动一个LED的显示值*/
{
	idata BYTE Num;
	idata BYTE i;
	idata BYTE LEDRamStatus;
	CMD8279 = 0x63;
	LEDRamStatus = DATA8279;

	if(LEDRamStatus != 0x00){
		if(	(LEDStatus == S_P_Val) || 
			(LEDStatus == S_I_Val) || 
			(LEDStatus == S_P_Val) || 
			(LEDStatus == S_SP_Val)||
			(LEDStatus == S_F_Val) )  {
			for(i=0;i<10;i++){
				if(LEDRamStatus == NumInTable[i]){
					Num = i;
					break;
				}
			}
		
			Num++;								/*下一位数字*/
			if((Num>=0)&&(Num<=9))
				WriteLed(3,NumInTable[Num]);
			else 
				WriteLed(3,NumInTable[0]);
		}						/*将第1个LED的显示内容更新*/
	}
	return;
}

/*********************************************************/
/***内部数据更新函数***/
void LEDDataToRAM()
{
	idata BYTE i,j;
	idata BYTE Ledram[4];
	idata BYTE dat[4];
	UINT result;
	CMD8279 = 0x70;
	for(i=0;i<4;i++){
		Ledram[i] = DATA8279;
	}

	for(i=0;i<4;i++){
		for(j=0;j<10;j++) {
			if(Ledram[i] == NumInTable[j])
				dat[i] = j;
		}
	}

	result = dat[3]*1000 + dat[2]*100 + dat[1]*10 + dat[0];
	
	switch(LEDStatus){
	case S_P_Val:
		p = result;
		break;
	case S_I_Val:
		I = result;
		break;
	case S_D_Val:
		D = result;
		break;
	case S_SP_Val:
		SP2 = (result<=10)?10:result;
		break;
	case S_F_Val:
		SP1toSP2Time = result;
		AlarmFlag = 0;   /***改变输入时间,不报警***/  
		if(SP1toSP2Time == 0){
			Rk = SP2;
		    TR1 = 0;	/**输入时间为0关闭定时器1 **/
		}
		else {
		       TR1 = 1;   
		      /***===+++++重新设定时,Rk初始值为当前温度+++++===***/
              Rk=Yk;                
		      SP_temp=Yk;
              /******===+++++++++++===**********/  
			if (SP2 >= Rk){
				SPOneStepValSign = 1;
				SPOneStepVal = (SP2-Rk)/(SP1toSP2Time*6.0);
			}
			else {
				SPOneStepValSign = 0;
				SPOneStepVal = (Rk-SP2)/(SP1toSP2Time*6.0);
			}
		}
		break;
	default:
		break;
	}
	return;
}

/*

  显示部分

*/

/******************************************************/
/***初始化8279***/
void Init_8279()     
{
	CMD8279 = 0x11;  /*键盘设置为译码扫描,双键锁定方式*/
					 /*显示8个字符,右入口*/

	CMD8279 = 0x34;  /*分频数为20*/
	
	Clear_8279();		
	return;
}

/******************************************************/
/***清8279FIFO RAM和显示RAM***/
void Clear_8279() reentrant
{
	idata BYTE CmdStatus;  /*8279控制寄存器状态*/
	CMD8279 = 0xD3;  /*清显示器和键盘*/
	CmdStatus = CMD8279;
	while((CmdStatus&0x80)) {
		CmdStatus = CMD8279;
	}				 /*等待清零结束*/
	return;
}

void Disp_A_Number(UINT times) reentrant
{
	idata BYTE i;
	idata BYTE dispchar[4];

	if(times > 9999){
		return;
	}

	dispchar[3] = NumInTable[times/1000];
	
	times = times%1000;
	dispchar[2] = NumInTable[times/100];
	
	times = times%100;
	dispchar[1] = NumInTable[times/10];

	dispchar[0] = NumInTable[times%10];

	Clear_8279();
	CMD8279 = 0x90;
	for(i=0;i<4;i++) {
		DATA8279 = dispchar[i];
	}
	return;
}

/******************************************************/
/***显示温度***/
void DispT() reentrant   
{
	Disp_A_Number(Yk);
	LEDStatus = S_NULL;
	TFlag = TRUE;
	return;
}

/******************************************************/
/***显示字符P***/
void DispP()
{
	Clear_8279();
	CMD8279 = 0x80;
	DATA8279 = CharP;
	LEDStatus = S_P;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示参数P的值***/
void DispPVal()
{
	Clear_8279();
	Disp_A_Number(p);
	LEDStatus = S_P_Val;	
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示字符I***/
void DispI()
{
	Clear_8279();
	CMD8279 = 0x80;
	DATA8279 = CharI;	
	LEDStatus = S_I;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示参数I的值***/
void DispIVal()
{
	Clear_8279();
	Disp_A_Number(I);
	LEDStatus = S_I_Val;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示字符D***/
void DispD()
{
	Clear_8279();
	CMD8279 = 0x80;
	DATA8279 = CharD;
	LEDStatus = S_D;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示参数D的值***/
void DispDVal()
{
	Clear_8279();
	Disp_A_Number(D);
	LEDStatus = S_D_Val;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示字符SP***/
void DispSetP()
{
	Clear_8279();
	CMD8279 = 0x90;
	DATA8279 = CharP;
	DATA8279 = CharS;	
	LEDStatus = S_SP;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示设定值***/
void DispSetPVal()
{ 		
	Clear_8279();
	Disp_A_Number(SP2);       /********++++++++++++***************/
	LEDStatus = S_SP_Val;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示字符F***/
void DispF()
{
	Clear_8279();
	CMD8279 = 0x90;
	DATA8279 = CharF;	
	LEDStatus = S_F;
	TFlag = FALSE;
	return;
}

/******************************************************/
/***显示F值***/
void DispFVal()
{
	Clear_8279();
	Disp_A_Number(SP1toSP2Time);
	LEDStatus = S_F_Val;
	TFlag = FALSE;
	return;
}

/********************************************************/
/***单独更新第i个LED的内容***/
void WriteLed(BYTE i,BYTE dat)
{
	i = i & 0x0F;
	i = i | 0x80;
	CMD8279 = i;
	DATA8279 = dat;
	return;
}

⌨️ 快捷键说明

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