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

📄 lcd.c

📁 基于单片机的多费率电能表源程序
💻 C
字号:
#define LCD_GLOBALS
#include "includes.h"

const INT8U DigitToSeg[]={0xeb,0x60,0xc7,0xe5,0x6c,0xad,0xaf,0xe0,0xef,0xed,0xff};	// 0 1 2 3 4 5  6  7 8 9 全显
const INT8U AssistantCharacter1[]={0x00,0x09,0x29,0x19,0x0d,0x40,0xff};
const INT8U AssistantCharacter2[]={0x00,0x01,0x02,0x80,0x40,0x04,0x24,0x05,0x25,0x06,0x26,0xff};
const INT8U DisplayAddressRelocate[]={5,4,3,2,1,0,6,7};
const INT8U BitMap[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

const INT8U TotalDisplayData[]={0xaa,0xaa,0xaa};
const struct DisplayDataStruct DisplayControlTable[]=
{
/*	第一项:数据地址;
	第二项:辅助符号编码
		辅助符号部分1编号:
			0000:空白;		/0x00
			0001:电量+KWH		/0x09
			0010:谷电量+KWH	/0x29
			0011:峰电量+kwh	/0x19
			0100:反向电量+KWH	/0x0d
			0101:局号			/0x40
			0110:液晶自检		/0xff
		辅助符号部分2编号:
			   0000:空白		/0x00
			   0001:总			/0x01
			   0010:平			/0x02
			   0011:日期		/0x80
			   0100:时间		/0x40
			   0101:上月		/0x04
			   0110:上上月		/0x24
 			   0111:上月总		/0x05
			   1000:上上月总	/0x25
			   1001:上月平		/0x06
               1010:上上月平	/0x26

	第三项:小数点编号;
	第四项:b4~b7:位置和b0~b3:长度;
	第五项:其他属性
			b7~b6:寻址方式:
				00:0为RAM数据;
				01:上月电能数据EEPROM地址寻址
				10:上上月电能数据EEPROM地址寻址
			b5:1:进行数据显示使能判断;0:不进行数据显示使能判断
			b4:1:显示存在模式选择;0:没有模式选择
			b3~b0:显示控制使能位编码
*/
	{(INT16U)&CurrentTime.Day,					0x30,0x33,0x03,0x28},	//当前日期
	{(INT16U)&CurrentTime.Second,				0x40,0x44,0x03,0x29},	//当前时间
	{(INT16U)&EnergyData.ActiveTotalEnergy[0],	0x11,0x12,0x04,0x10},	//当前总电量
	{(INT16U)&EnergyData.ActiveRate1Energy[0],	0x03,0x12,0x04,0x10},	//当前峰电量
	{(INT16U)&EnergyData.ActiveRate2Energy[0],	0x21,0x12,0x04,0x3B},	//当前平电量
	{(INT16U)&EnergyData.ActiveRate3Energy[0],	0x02,0x12,0x04,0x10},	//当前谷电量
	{(INT16U)&UserNumber[3],					0x05,0x00,0x03,0x2D},	//电表局编号高位
	{(INT16U)&UserNumber[0], 					0x05,0x00,0x03,0x2D},	//电表局编号低位
	{(INT16U)TotalDisplayData,					0xb6,0x00,0X03,0x2E},	//电表自检	
	{(INT16U)ACTIVE_ENERGY0,					0x71,0X12,0X04,0X70},	//上月正向有功总电能	
	{(INT16U)ACTIVE_ENERGY0,					0x53,0x12,0X04,0X71},	//上月峰时段正向有功电量	
	{(INT16U)ACTIVE_ENERGY0,					0x91,0x12,0X04,0X72},	//上月平时段正向有功电量     
	{(INT16U)ACTIVE_ENERGY0,					0x52,0x12,0X04,0X73},	//上月谷时段正向有功电量					
	{(INT16U)ACTIVE_ENERGY0,					0x81,0x12,0X04,0xb4},	//上上月正向 	有功总电能		
	{(INT16U)ACTIVE_ENERGY0,					0x63,0x12,0X04,0xb5},	//上上月峰时段正向有功电量	
	{(INT16U)ACTIVE_ENERGY0,					0xa1,0x12,0X04,0xb6},	//上上月平时段正向有功电量				
	{(INT16U)ACTIVE_ENERGY0,					0x62,0x12,0X04,0xb7}	//上上月谷时段正向有功电量
};

void LcdInit(void)	
{	
	INT8U i;	
	HB_LPCR	= CST_LPCR_INI;	//0xe9	
	HB_LCR	=	CST_LCR_INI;//0xfe
	HB_LCR2	=	CST_LCR2_INI;//0x67
	HB_CKSTPR2|=	0x01;	//open lcd control model
	for(i=0;i<LCDRAMLENGTH;i++)
	{
		*(LcdRamFirstAddress+i)=0xff;
	}
}
//5.12.14.26已经调过
void DisplayInit(void)
{
	//显示控制初始化	
	DisplayCircleInterval=(DisplaySelect[0]&0x0f)+(DisplaySelect[0]>>4)*10;	
	DisplayCircleTmr=DisplayCircleInterval;	
	if(DisplaySelect[2]&0x80)
		DisplayState=1;
	else
		DisplayState=0;
	DisplayPnt=0xff;
	PaginationSign=0;
}
//lcd驱动程序
void ClearDisplayData(void)
{
	INT8U i;
	for (i=0; i<LCDRAMLENGTH; i++)
		DisplayDataBuf[i]=0x00;//清显示缓存
}
//由于小数点的位置根据不同的需要位置变化不大,故采用编码的方式
void DisplayDecimalDot(INT8U DecimalDotType)
{
	switch(DecimalDotType)
	{
		case 0:
			break;
		case 1:
			DisplayDataBuf[2]|=0x10;
			break;
		case 2:
			DisplayDataBuf[1]|=0x10;
			break;
		case 3:
			DisplayDataBuf[4]|=0x10;
			DisplayDataBuf[2]|=0x10;
			break;
		case 4:
			DisplayDataBuf[4]|=0x10;
			DisplayDataBuf[2]|=0x10;
			DisplayDataBuf[6]|=0x80;
			DisplayDataBuf[7]|=0x08;
			break;
		default:
			break;		
	};
}
#define	DISPLAYSTATE()   \
{\
	if(_Communicate_)\
		DisplayDataBuf[6]|=0x02;\
	switch(TimeSliceInfo.CurrentRateID)\
	{\
		case 2:\
			FENG_LED_ON;\
			PING_LED_OFF;\
			GU_LED_OFF;\
			break;\
		case 3:\
			FENG_LED_OFF;\
			PING_LED_ON;\
			GU_LED_OFF;\
			break;\
		case 4:\
			FENG_LED_OFF;\
			PING_LED_OFF;\
			GU_LED_ON;\
			break;\
		default:\
			FENG_LED_OFF;\
			PING_LED_OFF;\
			GU_LED_OFF;\
			break;	\
	}\
}
//显示数据编辑
void DisplayDataEdit(void)
{
	INT8U *DataPnt;
	INT8U TempVar;
	INT8U i;
	DisplayCircleTmr++;
	if(DisplayCircleTmr>=DisplayCircleInterval)
	{
		DisplayCircleTmr=0;
		if(PaginationSign==0)//当前不是显示分页模式的第二页
		{	
		/*寻找下一个要显示的数据项*/		
			for(i=0;i<MAXDATANUM;i++)
			{
				DisplayPnt++;
				if(DisplayPnt>=MAXDATANUM)
					DisplayPnt=0;
				if(DisplayControlTable[DisplayPnt].OtherProperty&0x20)	//需要判断数据显示使能
				{
					TempVar=DisplayControlTable[DisplayPnt].OtherProperty&0x0f;
					if(DisplaySelect[1+(TempVar>>3)]&BitMap[TempVar&0x07])
						break;						
				}
				else
				{
					break;
				}
			}//到这里已经找到了要显示的项			
		}
		/*以下控制分页模式中页的切换*/
		if(DisplayState)
		{		
			if(DisplayControlTable[DisplayPnt].OtherProperty&0x10)
			{
				if(PaginationSign==0)
					PaginationSign=1;
				else
					PaginationSign=0;
			}
		}				
	}
	
	switch(DisplayControlTable[DisplayPnt].OtherProperty&0xc0)	//编辑数据
	{		
		case 0x00://数据在RAM中
			DataPnt=(INT8U *)DisplayControlTable[DisplayPnt].DataAddress;
			break;		
		case 0x40://上月电能数据
			TempVar=ACTIVE_ENERGY_ID0+(EnergyData.EnergyPointer+12)%13;
			if(!ReadEepromData(TempVar,&TempBufOfMain[18]))
			{
				if(!ReadEepromData(TempVar,&TempBufOfMain[18]))
				{
					for(i=0;i<12;i++)
						TempBufOfMain[18+i]=0;	
				}
			}
			TempVar=(DisplayControlTable[DisplayPnt].OtherProperty&0x0f);
			if(TempVar==0)
			{
				BcdAdd(&TempBufOfMain[18],&TempBufOfMain[22],TempBufOfMain,4);
				BcdAdd(TempBufOfMain,&TempBufOfMain[26],&TempBufOfMain[14],4);	
			}			
			DataPnt=&TempBufOfMain[14]+(TempVar<<2);
			break;
		case 0x80://上上月电能数据
			TempVar=ACTIVE_ENERGY_ID0+(EnergyData.EnergyPointer+11)%13;
			if(!ReadEepromData(TempVar,&TempBufOfMain[18]))
			{
				if(!ReadEepromData(TempVar,&TempBufOfMain[18]))
				{
					for(i=0;i<12;i++)
						TempBufOfMain[18+i]=0;	
				}
			}
			TempVar=(DisplayControlTable[DisplayPnt].OtherProperty&0x0f)-4;
			if(TempVar==0)
			{
				BcdAdd(&TempBufOfMain[18],&TempBufOfMain[22],TempBufOfMain,4);
				BcdAdd(TempBufOfMain,&TempBufOfMain[26],&TempBufOfMain[14],4);	
			}			
			DataPnt=&TempBufOfMain[14]+(TempVar<<2);
			break;
		default:
			break;		
	}
	TempVar=DisplayControlTable[DisplayPnt].PositionAndLength&0x0f;
	if(DisplayState)
	{
		if(DisplayControlTable[DisplayPnt].OtherProperty&0x10)
		{
			if(PaginationSign)
			{
				DataPnt++;
				TempVar--;
				BcdToDigital(DataPnt,TempBufOfMain,TempVar,0);
				DisplayDigit((INT8U)((DisplayControlTable[DisplayPnt].PositionAndLength>>4)),(INT8U)(TempVar<<1),TempBufOfMain,0);	
			}
			else
			{
				BcdToDigital(DataPnt,TempBufOfMain,1,0);
				DisplayDigit((INT8U)((DisplayControlTable[DisplayPnt].PositionAndLength>>4)),2,TempBufOfMain,0);
				DisplayDataBuf[2]=DigitToSeg[0];
			}
		}
		else
		{
			BcdToDigital(DataPnt,TempBufOfMain,TempVar,0);
			DisplayDigit((INT8U)((DisplayControlTable[DisplayPnt].PositionAndLength>>4)),(TempVar<<1),TempBufOfMain,0);
			
		}
	}
	else
	{
		if(DisplayControlTable[DisplayPnt].OtherProperty&0x10)
		{
			TempVar;
			BcdToDigital(DataPnt,TempBufOfMain,TempVar,0);
			DisplayDigit((INT8U)((DisplayControlTable[DisplayPnt].PositionAndLength>>4)),(INT8U)((TempVar-1)<<1),&TempBufOfMain[1],0);	
		}
		else
		{
			BcdToDigital(DataPnt,TempBufOfMain,TempVar,0);
			DisplayDigit((INT8U)((DisplayControlTable[DisplayPnt].PositionAndLength>>4)),(TempVar<<1),TempBufOfMain,0);
		
		}
	}	
	//显示辅助符号
	DisplayDataBuf[6]=AssistantCharacter1[DisplayControlTable[DisplayPnt].AssistantCharacter&0x0f];
	DisplayDataBuf[7]=AssistantCharacter2[DisplayControlTable[DisplayPnt].AssistantCharacter>>4];
	//显示小数点
	if(DisplayState)
	{
		if(PaginationSign==0)
			DisplayDecimalDot(DisplayControlTable[DisplayPnt].Decimal>>4);
	}		
	else
	{
		DisplayDecimalDot(DisplayControlTable[DisplayPnt].Decimal&0x0f);			
	}
	//显示状态
	DISPLAYSTATE();	
	//显示通讯状态标志	
		
}
void DisplayDigit(INT8U pos,INT8U length,INT8U * adr,INT8U sign)
{
	INT8U i;
	INT8U *Pnt;	
	if(sign)
	{
		Pnt=adr+length-1;
		while((*Pnt==0)&&(length>2))
		{
			Pnt--;
			length--;	
		}			
	}
	for(i=0;i<length;i++)
	{	
		DisplayDataBuf[pos+i]=DigitToSeg[*adr];
		adr++;
	}		
}
void LcdDisplayData(void)
{
	INT8U i;
	for(i=0;i<LCDRAMLENGTH;i++)
		*(LcdRamFirstAddress+DisplayAddressRelocate[i])=DisplayDataBuf[i];		
}
void Display(void)
{
	INT8U *DataPnt;
	INT8U i;	
	ClearDisplayData();	
	DisplayDataEdit();
	LcdDisplayData();		
}

⌨️ 快捷键说明

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