📄 display.c
字号:
#include "msp430x41x.h"
#include "string.h"
#include "general.h"
//#define BEIJING_STIPULATION
// LCD轮显指示位定义
// 刷新显示部分:
// bit00.用户号
// bit01.显示器自检
// bit02.表号
// bit03.时间日期
// bit04.当前信息显示选择
// bit05.上上月信息显示选择
// bit06.上月信息显示选择
// bit07.本月信息显示选择
// bit08.时段显示
// bit09.12个月电量显示
// bit10.
// bit11....
// bit12.编程状态
// bit13.低电显示
// bit14.通信状态
// bit15.进入翻页状态
///////////////////////////////////////////
// bit00.正向总用电量
// bit01.峰时段正向用电量
// bit02.平时段正向用电量
// bit03.谷时段正向用电量
// bit04.尖时段正向用电量
// bit05.反向总用电量
// bit06.峰时段反向用电量
// bit07.平时段反向用电量
// bit08.谷时段反向用电量
// bit09.尖时段反向用电量
// --------------------------
#define DISP_CNT 12
unsigned char LcdInterval;
unsigned short LcdDisplayChoose;
unsigned char LcdDispPwrChoose[4];
unsigned char DisplayPointer;
unsigned char DispDeviceOrUserNumFlag;
unsigned char TurnDisplayPower;
unsigned char LcdMonthIndex;
unsigned char LcdDispTemp;
unsigned char LcdDispPageUpOrDown;
unsigned char CoverFlag=0;
#define DISP_CODE_C (BIT0|BIT2|BIT4|BIT7)
#define DISP_CODE_d (BIT1|BIT2|BIT5|BIT6|BIT7)
#define DISP_CODE_P (BIT0|BIT1|BIT4|BIT2|BIT5)
#define DISP_CODE__ (BIT1)
//为防止出现乱码,把不是BCD码的都显示0
const unsigned char bcddigit[16]=
{
(BIT0|BIT2|BIT4|BIT5|BIT6|BIT7), /* 0 */
( BIT5|BIT6 ), /* 1 */
(BIT7|BIT5| BIT1| BIT2|BIT4), /* 2 */
( BIT1| BIT4|BIT5|BIT6|BIT7), /* 3 */
( BIT0|BIT1| BIT5|BIT6 ), /* 4 */
( BIT0|BIT1|BIT4|BIT6| BIT7), /* 5 */
(BIT0|BIT1|BIT2|BIT4|BIT6| BIT7), /* 6 */
( BIT4|BIT5|BIT6), /* 7 */
(BIT1|BIT2|BIT0|BIT4|BIT5|BIT6|BIT7), /* 8 */
( BIT6|BIT7|BIT4|BIT5|BIT0|BIT1), /* 9 */
(BIT0|BIT2|BIT3|BIT4|BIT5|BIT6|BIT7), /* 10 */
(BIT3|BIT5|BIT6), /* 11 */
(BIT1|BIT7|BIT5|BIT3|BIT2|BIT4), /* 12 */
(BIT1|BIT2|BIT5|BIT6|BIT7), /* D */
(BIT1|BIT2|BIT4|BIT0|BIT7), /* E */
(BIT1|BIT2|BIT4|BIT0), /* F */
};
const unsigned char textinfo_zfpgj[5]={BIT0,BIT2,BIT3,BIT4,BIT1};//总,峰,平,谷,尖
const unsigned char textinfo_zf_xiang[2]={LCD_OF_ZHENGXIANG,LCD_OF_FANXIANG};//正,反向
unsigned char GetPreviousMonthIndex(unsigned char item)
{
unsigned char temp;
E2promRead(ADDRESS_OF_SETTLEMENT_RECODE_MON,&temp,1);
// 比较本月是否等于上次结算月(16进制)
#ifdef _HARDWARE_RTC
if(temp==SystemTime_MonthHex)
#else
if(temp==g_time[SPACE_OF_MONTH])
#endif
{
item--;
}
#ifdef _HARDWARE_RTC
return((SystemTime_MonthHex+11*item)%12);
#else
return((g_time[SPACE_OF_MONTH]+11*item)%12);
#endif
}
void LcdDisplayReload(void)
{
DisplayPointer=0;
DispDeviceOrUserNumFlag=0;
LcdInterval=0;
LcdDispTemp=0;
E2promRead(ADDRESS_OF_DISPLAY_CHOOSE,(unsigned char *)&LcdDisplayChoose,2);
E2promRead(ADDRESS_OF_DISPLAY_CHOOSE+2,LcdDispPwrChoose,4);
}
void ResetLcdDisplay(void)
{
LcdDisplayReload();
LcdDispPageUpOrDown=0;
LcdDisplayChoose&=~(0x8200);
}
void DisplayPointerNext(void)
{
DisplayPointer=(DisplayPointer+1)%DISP_CNT;
}
void LcdDisplay6Bcd(unsigned char *data)
{
unsigned char ii=2,jj=0,temp;
while(ii<8)
{
temp=data[jj]>>4;
LCDMEM[ii]|=bcddigit[temp];
ii++;
temp=data[jj]&0x0F;
LCDMEM[ii]|=bcddigit[temp];
ii++;
jj++;
}
}
// LCD全显
void DisplayLcdTest(void)
{
memset(LCDMEM,0xFF,10);
}
void ExchangeData(unsigned char *data2)
{
unsigned char data1[3];
data1[0]=data2[2];
data1[1]=data2[1];
data1[2]=data2[0];
LcdDisplay6Bcd(data1);
}
void DisplayDeviceOrUserNum(unsigned char addr)
{
unsigned char data[3];
if(!DispDeviceOrUserNumFlag)
{
LCDMEM[1]|=BIT5|BIT6|BIT0|BIT1|BIT2;
}
else
{
LCDMEM[1]|=BIT0|BIT2|BIT7;
}
E2promRead((addr-DispDeviceOrUserNumFlag*3),data,3);
ExchangeData(data);
DispDeviceOrUserNumFlag=(DispDeviceOrUserNumFlag+1)%2;
}
// 显示表号
void DisplayDeviceNum(void)
{
DisplayDeviceOrUserNum(ADDRESS_OF_DEVICE_NUMBER+3);
LCDMEM[LCD_ADDRESS_OF_DEVICE_NUM]|=LCD_OF_DEVICE_NUM;
}
// 显示用户号
void DisplayUserNum(void)
{
DisplayDeviceOrUserNum(ADDRESS_OF_USER_CODE+3);
LCDMEM[LCD_ADDRESS_OF_USER_NUM]|=LCD_OF_USER_NUM;
}
// 显示日期、时间数据
void DisplayDateTimeData(unsigned char *dt)
{
ExchangeData(dt);
LCDMEM[LCD_ADDRESS_OF_MAOHAO0]|=LCD_OF_MAOHAO0;
LCDMEM[LCD_ADDRESS_OF_MAOHAO1]|=LCD_OF_MAOHAO1;
LCDMEM[LCD_ADDRESS_OF_MAOHAO2]|=LCD_OF_MAOHAO2;
}
// 显示日期、时间
void DisplayDateTime(void)
{
#ifndef _HARDWARE_RTC
unsigned char time_bcd[7];
#endif
#ifndef _HARDWARE_RTC
GetSystemTimeBcd(time_bcd);
#endif
if(!DispDeviceOrUserNumFlag)
{
#ifdef _HARDWARE_RTC
DisplayDateTimeData(&g_time[SPACE_OF_DAY]);
#else
DisplayDateTimeData(&time_bcd[SPACE_OF_DAY]);
#endif
LCDMEM[LCD_ADDRESS_OF_DATE_TIME]|=LCD_OF_DATE;
}
else
{
unsigned char pwr_attr;
pwr_attr=(unsigned char)GetPowerAttribute();
LCDMEM[LCD_ADDRESS_OF_ZHENGFAN_XIANG]|=textinfo_zf_xiang[pwr_attr>>2]|LCD_OF_TIME;
LCDMEM[LCD_ADDRESS_OF_ZFPGJ]|=textinfo_zfpgj[(pwr_attr&0x03)+1];
#ifdef _HARDWARE_RTC
DisplayDateTimeData(&g_time[SPACE_OF_SECOND]);
#else
DisplayDateTimeData(&time_bcd[SPACE_OF_SECOND]);
#endif
//LCDMEM[LCD_ADDRESS_OF_DATE_TIME]|=LCD_OF_TIME;
if(!LcdInterval) TurnDisplayPower=0;
}
DispDeviceOrUserNumFlag=(DispDeviceOrUserNumFlag+1)%2;
}
// 电量数据显示
void DisplayPowerData(unsigned short addr)
{
unsigned long totle,pulsetemp;
E2promRead(addr+TurnDisplayPower*4,(unsigned char *)&totle,4);
if((DisplayPointer==4)||(DisplayPointer==7))
{
if(TurnDisplayPower==0)
{
pulsetemp=PowerScalar[8];
}
else
{
pulsetemp=PowerScalar[TurnDisplayPower-1];
}
pulsetemp=(unsigned char)Hex2Bcd((unsigned long)pulsetemp);
totle=__bcd_add_long(totle,(unsigned long)pulsetemp);
}
totle>>=4;
LCDMEM[9]|=BIT6;//kWh
#if 0
if(((LcdMonthIndex>=10)||(LcdMonthIndex<=2))&&(TurnDisplayPower==3))
{
LCDMEM[LCD_ADDRESS_OF_DONG]|=LCD_OF_DONG;
}
#endif
LCDMEM[LCD_ADDRESS_OF_ZFPGJ]|=textinfo_zfpgj[TurnDisplayPower%COUNT_OF_DISPLAY_POWER]|LCD_OF_DIANLIANG;
//LCDMEM[LCD_ADDRESS_OF_ZHENGFAN_XIANG]|=textinfo_zf_xiang[(unsigned char)(TurnDisplayPower/5)];
LCDMEM[LCD_ADDRESS_OF_DOT1]|=LCD_OF_DOT1;
ExchangeData((unsigned char *)&totle);
TurnDisplayPower=(TurnDisplayPower+1)%COUNT_OF_DISPLAY_POWER;
}
// 电量显示
void DisplayPowerScalar(unsigned short addr)
{
while(TurnDisplayPower<COUNT_OF_DISPLAY_POWER)
{
if(LcdDispPwrChoose[DisplayPointer-4]&(1<<TurnDisplayPower))
{
DisplayPowerData(addr);
break;
}
TurnDisplayPower=(TurnDisplayPower+1)%COUNT_OF_DISPLAY_POWER;
if((TurnDisplayPower==0)&&(!(LcdDispPageUpOrDown&USERKEY_VIEW)))
{
DisplayPointer|=0x80;
break;
}
}
}
void DisplaySpecialMonthPwrScal(void)
{
DisplayPowerScalar(ADDRESS_OF_MONTH_LOG+40*LcdMonthIndex);
}
// 显示当前电量
void DisplayTotlePweScal(void)
{
DisplayPowerScalar(ADDRESS_OF_TOTAL_POWER_PLUS);
}
// 显示当月电量
void DisplayCurrentMonthPwrScal(void)
{
LCDMEM[LCD_ADDRESS_OF_BEN]|=LCD_OF_BEN;
LCDMEM[LCD_ADDRESS_OF_YUE]|=LCD_OF_YUE;
DisplayPowerScalar(ADDRESS_OF_MONTH_CURRENT);
}
// 显示上N月
void DispPreviousMonthNum(unsigned char item)
{
LcdMonthIndex=GetPreviousMonthIndex(item);
LCDMEM[LCD_ADDRESS_OF_SHANG]|=LCD_OF_SHANG1;
LCDMEM[1]=bcddigit[item];
LCDMEM[LCD_ADDRESS_OF_YUE]|=LCD_OF_YUE;
}
// 显示上月电量
void DisplayLastMonthPwrScal(void)
{
DispPreviousMonthNum(1);
DisplaySpecialMonthPwrScal();
}
// 显示上上月电量
void DisplayBeforeLastMonthPwrScal(void)
{
DispPreviousMonthNum(2);
DisplaySpecialMonthPwrScal();
}
// 12个月的电量显示
void DisplayEveryMonthPwrScal(void)
{
if(LcdDispPageUpOrDown==USERKEY_SELECT)
{
LcdDispTemp++;
}
DispPreviousMonthNum(LcdDispTemp);
DisplayPowerData(ADDRESS_OF_MONTH_LOG+(LcdMonthIndex)*40);
}
// 时段显示
void DisplayPeriodOfTime(void)
{
unsigned char time_data[3],period_cnt;
ReadPeriodOfTimeCount(&period_cnt);
E2promRead(ADDRESS_OF_TIME_SECT+TurnDisplayPower*3,&time_data[0],3);
LCDMEM[LCD_ADDRESS_OF_ZFPGJ]|=textinfo_zfpgj[time_data[0]];
time_data[0]=0;
DisplayDateTimeData(&time_data[0]);
LCDMEM[1]|=bcddigit[++TurnDisplayPower];
TurnDisplayPower%=period_cnt;
LCDMEM[8]|=BIT6;
}
// 显示结算日
void DisplayBalanceTime(void)
{
unsigned char temp2,i;
unsigned short temp3;
const unsigned char _DispAddr[]=
{
ADDRESS_OF_SETTLEMENT_HOUR,
ADDRESS_OF_DEVICE_CONSTANT
};
const unsigned char _DispAddr1[]=
{
DISP_CODE_d,
DISP_CODE_C
};
const unsigned char _DispAddr2[]=
{
DISP_CODE__,
DISP_CODE_P
};
temp2=DisplayPointer-9;
E2promRead(_DispAddr[temp2],(unsigned char *)&temp3,2);
for(i=0;i<4;i++)
{
LCDMEM[7-i]|=(temp3>>(i*4))&0x0F;
}
LCDMEM[2]|=_DispAddr1[temp2];
LCDMEM[3]|=_DispAddr2[temp2];
if(temp2)
{
LCDMEM[LCD_ADDRESS_OF_MAOHAO2]|=LCD_OF_MAOHAO2;
LCDMEM[LCD_ADDRESS_OF_MAOHAO1]|=LCD_OF_MAOHAO1;
}
}
const PROC_FUNC DisplayProc[]={
DisplayLcdTest,
DisplayDeviceNum,
DisplayUserNum,
DisplayDateTime,
DisplayTotlePweScal,
DisplayBeforeLastMonthPwrScal,
DisplayLastMonthPwrScal,
DisplayCurrentMonthPwrScal,
DisplayPeriodOfTime,
DisplayBalanceTime,
DisplayBalanceTime,
DisplayEveryMonthPwrScal
};
void DisplayProcess(void)
{
while(DisplayPointer<DISP_CNT)
{
// 清空先前所有显示
MemSetTo0((unsigned char *)&LCDMEM[0],10);
// 判断显示选择位
if(LcdDisplayChoose&(1<<DisplayPointer))
{
if(DisplayPointer<4) TurnDisplayPower=1;
// 如果有选择项,则执行相应的函数
(DisplayProc[DisplayPointer])();
if(DisplayPointer&0x80)
{
DisplayPointer&=~(0x80);
goto STILL_LOOP;
}
break;
}
STILL_LOOP:
DisplayPointerNext();
}
}
void DisplayRefresh(void)
{
if(DisplayPointer==3)
{
DispDeviceOrUserNumFlag--;
DisplayProcess();
if((TurnDisplayPower==0)&&(!(LcdDisplayChoose&0x8000)))
{
DisplayPointerNext();
}
}
if(!(LcdDisplayChoose&0x8000))
{
if(LcdDisplayChoose&0x0FFF)
{
if(!LcdInterval)
{
E2promRead(ADDRESS_OF_DISPLAY_INTERVAL,&LcdInterval,1);
LcdInterval=(unsigned char)Bcd2Hex((unsigned long)LcdInterval);
if(DisplayPointer<3)
{
if(DispDeviceOrUserNumFlag==0)
DisplayPointerNext();
}
if(LcdInterval)
DisplayProcess();
else
DisplayLcdTest();
if(TurnDisplayPower==0)
{
DisplayPointerNext();
}
}
LcdInterval--;
}
}
LCDMEM[LCD_ADDRESS_OF_TONGXIN]&=~(LCD_OF_TONXIN);
// 低电显示
if(BreakOrLowPowerFlag&LOW_PWR_TST)
{
LCDMEM[LCD_ADDRESS_OF_LOWPWR]|=LCD_OF_LOWPWR;
}
// 掉电显示
if(BreakOrLowPowerFlag)
{
LCDMEM[LCD_ADDRESS_OF_BRKPWR]|=LCD_OF_BRKPWR;
}
//编程状态显示
if(LcdDisplayChoose&0x1000)
{
LCDMEM[LCD_ADDRESS_OF_PROGRAM]|=LCD_OF_PROGRAM;
}
// 开盖报警
if(!(STA_UP_IN&STA_UP))
{
if(!(CoverFlag&BIT0))
{
_bcd_short_add1_and_write_e2prom_(ADDRESS_OF_OPEN_COVER_CNT);
_save_time_to_e2prom_(ADDRESS_OF_OPEN_COVER_TIME);
CoverFlag|=BIT0;
}
LCDMEM[LCD_ADDRESS_OF_COVER]|=LCD_OF_COVER;
}
else
{
CoverFlag=0;
}
}
//上翻页键做页浏览
void LcdSelectPage(void)
{
if(!(LcdDisplayChoose&0x8000))
{
LcdDisplayReload();
memset(&LcdDispPwrChoose[0],0xFF,4);
LcdDisplayChoose=0x8FFF;
DisplayPointer=DISP_CNT-1;
}
TurnDisplayPower=0;
DispDeviceOrUserNumFlag=0;
if(LcdDispTemp>=12)
LcdDispTemp=0;
if(!LcdDispTemp) DisplayPointerNext();
DisplayProcess();
}
//下翻页键做页选择
void LcdViewPage(void)
{
//为避免干扰产生的中断,所以此判断很重要
if(LcdDisplayChoose&0x8000)
{
DisplayProcess();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -