📄 lcd.c
字号:
/* This file is designed for the LCD display.*/
/* It is designed by Lijingjiao*/
#include "gp32.h"
/* Authorize interrupts*/
#define cli() _asm("cli\n")
/* disable interrupts*/
#define sei() _asm("sei\n")
#define nop() _asm("nop\n")
/*数据类型定义部分*/
typedef unsigned int Uint; /*无符号整型数据类型的定义*/
typedef unsigned char Uchar; /*无符号整型数据类型的定义*/
typedef struct bits {
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
} BITS;
typedef union bit_char {
unsigned char byte;
BITS b;
} BIT_CHAR;
#define BIT0 (unsigned char)0x01
#define BIT1 (unsigned char)0x02
#define BIT2 (unsigned char)0x04
#define BIT3 (unsigned char)0x08
#define BIT4 (unsigned char)0x10
#define BIT5 (unsigned char)0x20
#define BIT6 (unsigned char)0x40
#define BIT7 (unsigned char)0x80
#define BSET(x, y) ((x).b.b ## y = 1)
#define BCLR(x, y) ((x).b.b ## y = 0)
@tiny volatile BIT_CHAR PTC @0x02;
Uchar command,data;
Uchar temp;
Uint i,k;
Uint data1,data2;
const Uint start=0x0800;
const Uchar KeyValue[]={0xfe,0xfd,0xfb,0xf7};/*逐行扫描*/
const Uchar KeyTable[16]={0xEE,0xDE,0xBE,0x7E,
0xED,0xDD,0xBD,0x7D,
0xEB,0xDB,0xBB,0x7B,
0xE7,0xD7,0xB7,0x77,
};
const Uint ELength=21;
const Uchar ETable[21]={0x37,0x25,0x2c,0x23,0x2f,0x2d,0x25,0X00,0x34,0x2f,0X00,//"WELCOME TO "
0x35,0x33,0x25,0x00,0x34,0x16,0x19,0x16,0x13,0x23};//"USE T6963C"
const Uint CCLength=352;
const Uchar EXPRT1[22]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa8,0xaa};
const Uchar EXPRT2[22]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d,0x8f,0x91,0x93,0x95,0x97,0x99,0x9b,0x9d,0x9f,0xa1,0xa3,0xa5,0xa7,0xa9,0xab};
const Uchar CCTable[352]={
0x01,0x3F,0x24,0x3F,0x26,0x2D,0x34,0x25,0x2F,0x20,0x2F,0x20,0x5F,0x40,0x82,0x01,
0x00,0xFE,0x20,0xFC,0x30,0x68,0xA6,0x20,0xF8,0x80,0xFC,0x80,0xFE,0x80,0x80,0x00,//摩
0x20,0x20,0x23,0xF8,0x20,0x20,0x28,0x37,0xE0,0x20,0x20,0x20,0x20,0x20,0xA0,0x40,
0x00,0x3C,0xC0,0x40,0x40,0x40,0x40,0xFE,0x40,0x40,0x40,0x40,0x42,0x42,0x3E,0x00,//托
0x00,0x3F,0x22,0x22,0x22,0x3F,0x22,0x03,0x06,0x0C,0x12,0x61,0x00,0x03,0x0C,0xF0,
0x00,0xFC,0x44,0x44,0x44,0xFC,0x00,0xFC,0x08,0x08,0x10,0x20,0xC0,0x00,0x00,0x00,//罗
0x10,0x10,0x10,0x11,0xFC,0x10,0x15,0x18,0x30,0xD0,0x10,0x10,0x10,0x17,0x50,0x20,
0x80,0x60,0x20,0xFE,0x00,0x08,0x0C,0x88,0x88,0x48,0x50,0x50,0x50,0xFE,0x00,0x00,//拉
0x08,0x06,0x04,0x3F,0x21,0x3F,0x21,0x21,0x3F,0x21,0x01,0xFF,0x01,0x01,0x01,0x01,
0x20,0x30,0x40,0xF8,0x08,0xF8,0x08,0x08,0xF8,0x08,0x00,0xFE,0x00,0x00,0x00,0x00,//单
0x00,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x20,0x20,0x40,0x80,
0x40,0x40,0x40,0x44,0xFE,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,//片
0x10,0x10,0x10,0xFE,0x10,0x10,0x38,0x34,0x54,0x50,0x91,0x11,0x12,0x12,0x14,0x10,
0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x0A,0x0A,0x0A,0x06,0x00,//机
0x20,0x13,0x10,0x40,0x47,0x44,0x44,0x47,0x44,0x44,0x47,0x40,0x40,0x40,0x40,0x40,
0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x04,0x04,0x14,0x08,//间
0x10,0x10,0x13,0xFD,0x10,0x17,0x14,0x18,0x30,0xDF,0x11,0x13,0x10,0x10,0x51,0x26,
0x40,0x20,0xFC,0x08,0x90,0xFE,0x00,0x80,0x80,0xFE,0x10,0x10,0xE0,0x50,0x8C,0x04,//接
0x10,0x10,0x10,0xFD,0x11,0x10,0x14,0x19,0x30,0xD1,0x10,0x10,0x10,0x10,0x53,0x20,
0x00,0x20,0x10,0xFE,0x04,0x50,0x8C,0x04,0x00,0xFC,0x20,0x20,0x20,0x20,0xFE,0x00,//控
0x24,0x34,0x24,0x3F,0x44,0x04,0x7F,0x04,0x3F,0x24,0x24,0x24,0x24,0x27,0x05,0x04,
0x04,0x04,0x24,0xA4,0x24,0x24,0xA4,0x24,0xA4,0xA4,0xA4,0xA4,0x84,0x84,0x14,0x08,//制
};
const Uint ptr[]={10,12,20,35,40,15,18,50};
/*延迟1ms*/
static void Wait1ms(void) {
int cnt = 0;
while (cnt <80) cnt++;
}
/*延迟n ms. */
void WaitNms(int n){
int i;
for(i=1;i<=n;i++) Wait1ms();
}
/*读状态位0和1 */
void ST01Read(void){
PTB=0x00;
DDRB=0x00; //设置PTB口为输入方向
while(1){
BSET(PTC,2); //C/D=1
BCLR(PTC,1); ///RD=0
temp=PTB; //将PTB口数据送给变量temp
BSET(PTC,1); ///RD=1
if ((temp&0x03)==0x03) break; /*判断指令、数据读写状态是否准备好*/
}
}
/*读状态位3 */
void ST3Read(void){
PTB=0x00;
DDRB=0x00; //设置PTB口为输入方向
while(1){
BSET(PTC,2); //C/D=1
BCLR(PTC,1); // /RD=0
temp=PTB;
BSET(PTC,1); // /RD=1
if ((temp&8)!=0) {break;} //判断数据自动写状态是否准备好
}
}
/*读状态位6*/
void ST6Read(void){
PTB=0x00;
DDRB=0x00; //设置PTB口为输入方向
while(1){
BSET(PTC,2); //C/D=1
BCLR(PTC,1); // /RD=0
temp=PTB;
BSET(PTC,1); // /RD=1
if ((temp&0x40)==0) {break;} // 判断屏读或屏拷贝出错状态
}
}
/*写数据*/
void WRData(Uchar data){
DDRB=0xff; //设置PTB口为输出方向
BCLR(PTC,2); // C/D=0
BCLR(PTC,0); // /WR=0
PTB=data;
BSET(PTC,0); // /WR=1
}
/*读数据*/
void RDData(void){
ST01Read(); //读状态位0和1
BCLR(PTC,2); // C/D=0
BCLR(PTC,1); // RD=0
data2=PTB; // 读取数据
BSET(PTC,1); // RD=1
}
/*写命令*/
void WRCommand(Uchar command){
DDRB=0xff; //设置PTB口为输出方向
BCLR(PTC,0); // /WR=0
PTB=command; //将命令送PTB口
BSET(PTC,0); // /WR=1
}
/*无参数指令*/
void WRCommandOne(void){
ST01Read(); //读状态位0和1
WRCommand(command); /*写命令*/
}
/*单参数指令*/
void WRCommandTwo(void){
ST01Read();
WRData(data2); /*写数据*/
ST01Read();
WRCommand(command); /*写命令*/
}
/*双参数指令*/
void WRCommandMany(void){
ST01Read();
WRData(data1); /*写数据*/
ST01Read();
WRData(data2); /*写数据*/
ST01Read();
WRCommand(command); /*写命令*/
}
/*初始化T6963 LCD 显示.*/
void Init_LCD_Graphic(void){
/*设置文本显示首地址*/
data1=0x00;
data2=0x00;
command=0x40;
WRCommandMany();
/*设置文本显示区宽度*/
data1=0x28; /*40字节*/
data2=0x00;
command=0x41;
WRCommandMany();
/*设置图形显示区首地址*/
data1=0x00;
data2=0x08; /*首地址0x0800*/
command=0x42;
WRCommandMany();
/*设置图形显示区宽度*/
data1=0x28; /*40字节*/
data2=0x00;
command=0x43;
WRCommandMany();
/*设置显示方式*/
command=0x80; /*启用内部字符发生器,显示方式是文本与图形逻辑或*/
WRCommandOne();
/*设置显示状态*/
command=0x9f; /*启用光标闪烁、光标显示、文本显示、图形显示*/
WRCommandOne();
}
/*清显示RAM*/
void ClrGraphic(void){
/*设置显示地址*/
data1=0x00; /*低字节*/
data2=0x00; /*高字节*/
command=0x24;
WRCommandMany();
/*进入自动写方式*/
command=0xb0;
WRCommandOne();
/*清8KRAM*/
data1=0x00;
for(i=0;i<0x2000;i++){
ST3Read();
WRData(data1);
}
/*退出自动写方式*/
command=0xb2;
WRCommandOne();
}
void TextDisplay(void){
/*设置显示地址*/
data1=84; //在第3行第4列显示文本字符
data2=0x00;
command=0x24;
WRCommandMany();
/*进入自动写方式*/
command=0xb0;
WRCommandOne();
/*“WELCOME”*/
for (k=0;k<ELength;k++){
ST3Read();
data1=ETable[k];
WRData(data1);
}
/*退出自动写方式*/
command=0xb2;
WRCommandOne();
}
/*建立CGRAM*/
void SETCGRAM(void){
/*设置CGRAM偏移地址*/
data1=0x03; /*首地址为0x1c00*/
data2=0x00;
command=0x22;
WRCommandMany();
/*设置显示地址*/
data1=0x00;
data2=0x1c; /*0x1c00*/
command=0x24;
WRCommandMany();
/*进入自动写方式*/
command=0xb0;
WRCommandOne();
/*写“摩托罗拉单片机间接控制”*/
for (k=0;k<CCLength;k++){
ST3Read();
data1=CCTable[k];
WRData(data1);
}
/*退出自动写方式*/
command=0xb2;
WRCommandOne();
}
/*文本方式下显示汉字*/
void CCDisplay(Uchar row,Uchar col){
Uint cursor,tempaddress;
SETCGRAM();
cursor=row*40+col;
tempaddress=cursor;
/*设置显示地址*/
data1=tempaddress&0x00ff;
data2=cursor&0xff00;
command=0x24;
WRCommandMany();
command=0xb0; /*进入自动写方式*/
WRCommandOne();
for (k=0;k<22;k++){
ST3Read();
data1=EXPRT1[k];
WRData(data1);
}
command=0xb2; /*退出自动写方式*/
WRCommandOne();
row+=1;
cursor=row*40+col;
tempaddress=cursor;
/*设置显示地址*/
data1=tempaddress&0x00ff;
data2=cursor&0xff00;
command=0x24;
WRCommandMany();
/*进入自动写方式*/
command=0xb0;
WRCommandOne();
for (k=0;k<22;k++){
ST3Read();
data1=EXPRT2[k];
WRData(data1);
}
/*退出自动写方式*/
command=0xb2;
WRCommandOne();
}
/*在图形方式下显示汉字*/
void GCDisplay(Uint row,Uint col){ //row(0~127)col(0~29)
Uint cursor,tempaddress;
Uint temprow,tempcol;
for(i=0;i<11;i++) /*11个汉字*/
{
tempcol=col+i*2;
for(k=0;k<16;k++)
{
temprow=row+k;
cursor=0x0800+temprow*40+tempcol;
tempaddress=cursor;
data1=tempaddress&0x00ff; /*设置显示地址*/
data2=(cursor&0xff00)>>8;
command=0x24;
WRCommandMany();
data2=CCTable[i*32+k];
command=0xc0; /*设置一次写数据,地址加一*/
WRCommandTwo();
data2=CCTable[i*32+k+16];
WRCommandTwo();
}
WaitNms(50);
}
WaitNms(50);
}
void LeftScroll(void)
{
Uint Num,cursor0,tempaddr;
while(1){
for(Num=0;Num<40;Num++) {
cursor0=start+Num;/*设置文本显示首地址*/
tempaddr=cursor0;
data1=tempaddr&0x00ff;
data2=cursor0&0xff00;
command=0x40;
WRCommandMany();
TextDisplay(); //""
WaitNms(500);
}
}
}
/*滚动显示-向右*/
void RightScroll(void)
{
Uint Num,cursor0,tempaddr;
while(1){
for(Num=0;Num<30;Num++) {
cursor0=start-Num;/*修改文本或图形显示区首地址*/
tempaddr=cursor0;
data1=tempaddr&0x00ff;
data2=cursor0&0xff00;
command=0x40;
WRCommandMany();
GCDisplay(1,3);
TextDisplay(); //""
CCDisplay(1,3);
WaitNms(500);
}
}
}
/*滚动显示—向上*/
void UpScroll(void)
{
Uint Num,cursor0,tempaddr;
while(1){
for(Num=0;Num<16;Num++) {
cursor0=start+Num*40;/*设置文本显示区首地址*/
tempaddr=cursor0;
data1=tempaddr&0x00ff;
data2=cursor0&0xff00;
command=0x40;
WRCommandMany();
TextDisplay(); //""
WaitNms(50);
}
}
}
/*滚动显示—向下*/
void DownScroll(void)
{
Uint Num,cursor0,tempaddr;
while(1){
for(Num=0;Num<16;Num++){
cursor0=start-Num*40; /*设置文本显示首地址*/
tempaddr=cursor0;
data1=tempaddr&0x00ff;
data2=cursor0&0xff00;
command=0x40;
WRCommandMany();
TextDisplay(); //""
WaitNms(500);
}
}
}
/*在图形方式下,绘点子程序*/
void DrawDot(int row,int col) /*行坐标以点为单位,列坐标以点为单位*/
{
int cursor;
/*设置显示地址*/
cursor=0x0800+row*0x28+col/8;
data1=cursor&0x00ff;
data2=((cursor&0xff00)>>8);
command=0x24;
WRCommandMany();
/*位操作*/
command=0xf8|(7-(col&0x07));
WRCommandOne();
}
/*消点子程序*/
void ClrDot(int row,int col) /*行坐标以点为单位,列坐标以点为单位*/
{
int cursor;
cursor =0x0800+row*0x28+col/8;
data1=cursor&0x00ff;
data2=((cursor&0xff00)>>8);
command==0x24;
WRCommandMany();
/*位操作*/
command=0xf0|(7-(col&0x07));
WRCommandOne();
}
/*画圆子程序:这里应用贝森海姆圆算法来绘制一个圆,以(x,y)为圆心以r为半径画一个圆*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -