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

📄 display.c

📁 单相复费率MSP430硬件时钟参考代码,MSP413设计方案
💻 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 + -