#include"msp430x16x.h"
#include"disp.h"
#define LCD_DATA_OUT P2OUT //lcd显示端口
#define LCD_DATA_IN P2IN
#define LCD_DATA_DIR P2DIR
#define LCD_PORT_SEL P2SEL
#define CS 0X01 //lcd芯片使能位
#define SID 0X02 //串行数据位
#define SCLK 0X04 //串行时钟
#define PSB 0X08 //串并模式选择位
#define RST 0x10 //复位信号位
static void sendCMD(unsigned char); //写控制指令
static void sendDAT(unsigned char); //写显示数据;也可以写一个单字节字符
static void sendBYTE(unsigned char dat);
static void menu_data_copy(MENU *data1,MENU *data2);
extern const unsigned char img0[];
static unsigned char ascII[12]={"0123456789 ."};
unsigned char lcd_buffer[64][16]={0};//图形显示缓冲区
unsigned char pt=0;//指向图形显示缓冲区的内容
//刷新标志和刷屏次数,此程序分4次刷完一屏,当且仅当内存图形缓冲区内容发生改变时才刷屏
unsigned char refresh_num=0,refresh_flag=0;
unsigned char menu_off=0;//菜单显示开关,为1时不显示菜单界面
//菜单数据,存有各张菜单的初始属性,各数据项具体含义见头文件声明
MENU menu[5]=
{
{0,0,0,0,0,0}, //待机画面(可视为无效菜单,但菜单开关仍然打开,便于随时进入菜单)
{1,1,1,1,8,1}, //第一级菜单(主菜单)
{2,2,1,1,5,9}, //第三张(第二级)菜单
{2,3,1,1,2,14},//第四张(第二级)菜单
{2,4,1,1,4,16},//第五张(第二级)菜单
};
MENU menu_track[3]={0};//菜单路径记录,便于返回,其元素个数由菜单级数决定
MENU active_menu={0,0,0,0,0};//当前活动菜单
//菜单选项标题,各张菜单统一编址,由自身属性找到自己所有的选项
unsigned char title[][16]=
{
"我的电脑 ",//第一张菜单项
"我的文档 ",
"图片 ",
"时间设置 ",
"温度测量 ",
"系统设置 ",
"其他 ",
"返回待机界面 ",
"本地磁盘C: ",//第二张菜单项
"本地磁盘D: ",
"本地磁盘E: ",
"本地磁盘F: ",
"返回上级菜单 ",
"道德经节选 ",//第三张菜单项
"论语节选 ",
"钻石队队徽 ",//第四张菜单项
"太极图 ",
"电子设计竞赛赛徽",
"返回上级菜单 "//完,选项变更需改此处
};
//*************************************************************************
//****************以下是关于LCD的底层驱动**********************************
//*************************************************************************
void sendBYTE(unsigned char dat) //串行传送一字节数据
{
char i;
LCD_DATA_DIR|=SID; //设P1.1为SID 为输出
LCD_DATA_OUT|=CS; //串行通信使能
for (i=0;i<8;i++)
{
LCD_DATA_OUT&=~SCLK; //SCLK=0
if((dat & 0x80)!=0)
LCD_DATA_OUT|=SID; //SID=1
else
LCD_DATA_OUT&=~SID; //SID=0
LCD_DATA_OUT|=SCLK; //SCLK=1;
dat = dat<<1;
}
}
//*********************发送指令*******************************************
void sendCMD(unsigned char dat) //写控制指令
{
sendBYTE(0xf8);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//**********************发送数据******************************************
void sendDAT(unsigned char dat) //写显示数据;也可以写一个单字节字符
{
sendBYTE(0xfa);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//===========================================================================
//延时函数,延时为t=n*5+16个周期
//===========================================================================
void delay(unsigned n)
{
unsigned i;
for(i=0;i<n;i++)
_NOP();
}
//===========================================================================
//液晶初始化函数
//===========================================================================
void int_lcd(void)
{
LCD_DATA_OUT&=~RST; //复位
delay(120); //等待复位完成
LCD_DATA_OUT|=RST; //撤销复位状态
sendCMD(0x30); //设定基本指令模式
sendCMD(0x01); //清屏
delay(20000); //等待清屏完成,清屏完成需1.6ms以上
sendCMD(0x10); //设置光标
sendCMD(0x0c); //打开屏幕,未打开光标
delay(50000);
}
//===========================================================================
//液晶连接端口初始化函数
//===========================================================================
void int_lcd_port(void)
{
LCD_PORT_SEL&=0xe0;
LCD_DATA_DIR|=0x1f;
LCD_DATA_OUT&=~PSB;
LCD_DATA_OUT|=RST;
}
//********************以下是显示的上层应用部分*******************************
//===========================================================================
//设置坐标函数,适用于内置字库显示时的情况,且行数line范围是0到3,列数x范围是0到7.
//===========================================================================
void set_position(unsigned char line,unsigned char x)
{
unsigned char place=0;//记录实际坐标的位置
switch(line)
{
case 0:
place=x+0x80;
break;
case 1:
place=x+0x90;
break;
case 2:
place=x+0x88;
break;
case 3:
place=x+0x98;
}
sendCMD(0x30);
sendCMD((0x80|place));//根据不同的行列数要求,设置具体位置
}
//===========================================================================
//内置字库的汉字(英文)显示函数,可显示中英文,line为起始行数,x为起始列数,
//dat存放汉字内码(或ASCII码),为了汉英统一,其数组长度需是偶数,不足以空格充数,
//n为待显汉字个数(英文字符个数的一半)。
//===========================================================================
void word_disp(unsigned char line,unsigned char x,unsigned char dat[],unsigned char n)
{
unsigned char i;
set_position(line,x);//设置起始坐标
for(i=0;i<n;i++)
{
sendDAT(dat[2*i]);//分别发送汉字内码的高低字节
sendDAT(dat[2*i+1]);
if((x+i+1)%8==0) //根据具体显示情况,决定是否调整坐标
{
line++;//满足换行条件,换行
if(line>4)
line=0;
set_position(line,0);//按自然数次序设置行数(默认顺序是0,2,1,3)
}
}
}
//============================================================================
//显示一个字符,利用内置字库
//============================================================================
void disp_asc(unsigned char line,unsigned char x,unsigned char asc)
{
set_position(line,x);
sendDAT(asc);
}
//============================================================================
//显示一个数,利用内置字库,可定点显示小数,但数据num应已事先扩大相应倍数,小数
//的位数由point定义
//============================================================================
void disp_num(unsigned char line,unsigned char x,unsigned num,unsigned char point)
{
unsigned char res[6]={0,0,0,0,0,0};//暂存num的各位,int型变量最多5位
unsigned char i=0,j;
if(point!=0)
res[point]=11;//小数点
while(num!=0)//拆解未毕,继续
{
if(i!=point)
{
res[i]=num%10;//不在小数点位置,存入拆解结果
num=num/10;
}
i++;//跳过小数点位置
}
set_position(line,x);//设置坐标,显示结果
for(j=i;j>=1;j--)
{
sendDAT(ascII[res[j-1]]);
}
}
//============================================================================
//清除字符显示,实际上就是全部显示空格
//============================================================================
void clear_ddram(void)
{
unsigned char i;
set_position(0,0);
for(i=0;i<64;i++)
{
sendDAT(' ');
}
}
//============================================================================
//清屏函数(可同时清除图形显示和字符显示)
//============================================================================
void clear_screen(void)
{
sendCMD(0x30);//基本指令动作
sendCMD(0x01);//清屏,AC归位
delay(50);//等待完成
}
//*****************************************************************************
//*****************************************************************************
//以下主要是对图形显示缓冲区操作的函数,以上是操作内置字库显示
//*****************************************************************************
//*****************************************************************************
//=========================================================================
//refresh函数,负责对图形的刷新,适用于图形的显示,每次刷新�