📄 lcd.c
字号:
//控制器:HD61202或ks0108
//设计者:李晶皎
//MCU:MC68HC908GP32
#include "gp32.h"
/*开中断*/
#define cli() _asm("cli\n")
/*关中断*/
#define sei() _asm("sei\n")
#define nop() _asm("nop\n")
/*数据类型定义部分*/
typedef unsigned int Uint; /*无符号整型数据类型的定义*/
typedef unsigned char Uchar; /*无符号整型数据类型的定义*/
Uint i,j,k,l,m;
Uchar command,data;
Uchar PAGE,COL;
Uchar PAGENUM,COLNUM,CLMNUM;
const Uchar KeyValue[4]={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 cnt=8;
const Uint ptr[8]={10,15,20,25,30,35,40,45}; /*柱状图数组*/
const Uchar CLMADD=0x40; /*第1单元的起始地址*/
const Uchar PAGEADD=0xb8; /*第1页的起始地址*/
Uchar CCTable[32]; /*8字节*4字*/
const char CTable[88]={
0x00, 0x7F, 0x20, 0x80, 0x20, 0x7F, 0x00, 0x00,//W
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00,//e
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x00,//l
0x00, 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, 0x00,//c
0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,//o
0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, 0x00,//m
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00,//e
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x00,//U
0x00, 0x58, 0x54, 0x54, 0x54, 0x64, 0x00, 0x00,//s
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00//e
};
const char CTable1[48]={
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x00,//Q
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00,//H
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x00, 0x00,//2
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00,//0
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00,//0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,0x00//1
};
const char table1[128]={
0x14,0x24,0x44,0x84,0x64,0x1C,0x20,0x18,0x0F,0xE8,0x08,0x08,0x28,0x18,0x08,0x00,
0x20,0x10,0x4C,0x43,0x43,0x2C,0x20,0x10,0x0C,0x03,0x06,0x18,0x30,0x60,0x20,0x00, //欢
0x40,0x41,0xCE,0x04,0x00,0xFC,0x04,0x02,0x02,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,
0x40,0x20,0x1F,0x20,0x40,0x47,0x42,0x41,0x40,0x5F,0x40,0x42,0x44,0x43,0x40,0x00, //迎
0x40,0x20,0xF0,0x1C,0x07,0xF2,0x94,0x94,0x94,0xFF,0x94,0x94,0x94,0xF4,0x04,0x00,
0x00,0x00,0x7F,0x00,0x40,0x41,0x22,0x14,0x0C,0x13,0x10,0x30,0x20,0x61,0x20,0x00, //使
0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,
0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x42,0x82,0x7F,0x00,0x00 //用
};
const char table2[128]={
0x10,0x61,0x06,0xE0,0x18,0x84,0xE4,0x1C,0x84,0x65,0xBE,0x24,0xA4,0x64,0x04,0x00,
0x04,0x04,0xFF,0x00,0x01,0x00,0xFF,0x41,0x21,0x12,0x0C,0x1B,0x61,0xC0,0x40,0x00,//液
0x00,0x00,0x00,0x00,0x7E,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x7E,0x00,0x00,0x00,0x00,
0x00,0x7F,0x25,0x25,0x25,0x25,0x7F,0x00,0x00,0x7F,0x25,0x25,0x25,0x25,0x7F,0x00,//晶
0x10,0xD0,0xFF,0x50,0x90,0x04,0xF4,0x54,0x5F,0x54,0x54,0x5F,0xF4,0x04,0x00,0x00,
0x03,0x00,0xFF,0x00,0x00,0x84,0x85,0x45,0x35,0x0F,0x15,0x25,0x65,0xC4,0x44,0x00,//模
0x10,0x10,0xFF,0x10,0x10,0x00,0x08,0x08,0xFF,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,
0x08,0x18,0x0F,0x04,0x85,0x41,0x31,0x0D,0x03,0x05,0x09,0x11,0x31,0x61,0x21,0x00//块
};
/*1毫秒延迟*/
static void Wait1ms(void) {
int cnt = 0;
while (cnt <40) cnt++;
}
/*n毫秒延迟*/
void WaitNms(int n){
int i;
for(i=1;i<=n;i++) Wait1ms();
}
/*判断是否为忙?*/
void Busy(void)
{
Uchar temp;
PTC&=0xFE; //D/I=0
PTC|=0x02; //R/W=1
PTB=0xff;
while(1){
DDRB=0x00;
PTC|=0x04; //E=1
temp=PTB; //读状态字
PTC&=0xFB; //E=0
if ((temp&0x80)==0)
break; //判断忙标志是否为0
}
}
/*左区写指令代码*/
void WRCommandL(void){
PTC&=0xEF; //CSA=0
PTC|=0x08; //CAB=1
Busy();
DDRB=0xff;
PTC&=0xFD; //R/W=0
PTB=command; //写指令代码
PTC|=0x04; //E=1
PTC&=0xFB; //E=0
}
/*右区写指令代码*/
void WRCommandR(void){
PTC|=0x10; //CSA=1
PTC&=0xF7; //CSB=0
Busy();
DDRB=0xff;
PTC&=0xFD; //R/W=0
PTB=command; //写指令代码
PTC|=0x04; //E=1
PTC&=0xFB; //E=0
}
/*左区写数据*/
void WRDataL(void){
PTC&=0xEF; //CSA=0
PTC|=0x08; //CAB=1
Busy();
DDRB=0xff;
PTC|=0x01; //D/I=1
PTC&=0xFD; //R/W=0
PTB=data; //写数据
PTC|=0x04; //E=1
PTC&=0xFB; //E=0
}
/*右区写数据*/
void WRDataR(void){
PTC|=0x10; //CSA=1
PTC&=0xF7; //CSB=0
Busy();
DDRB=0xff;
PTC|=0x01; //D/I=1
PTC&=0xFD; //R/W=0
PTB=data; //写数据
PTC|=0x04; //E=1
PTC&=0xFB; //E=0
}
/*读左区显示数据*/
Uchar RDDataL(void){
PTC&=0xEF; //CSA=0
PTC|=0x08; //CAB=1
Busy();
PTC|=0x01; //D/I=1
PTC|=0x02; //R/W=1
DDRB=0x00;
PTC|=0x04; //E=1
data=PTB; //读数据
PTC&=0xFB; //E=0
return(data);
}
/*读右区显示数据*/
Uchar RDDataR(void){
PTC|=0x10; //CSA=1
PTC&=0xF7; //CSB=0
Busy();
PTC|=0x01; //D/I=1
PTC|=0x02; //R/W=1
DDRB=0X00;
PTC|=0x04; //E=1
data=PTB; //读数据
PTC&=0xFB; //E=0
return(data);
}
/*左区显示字符*/
void DisCharL(char *TTable)
{
COLNUM=CLMADD|COL;
command=COLNUM;
WRCommandL();
for(m=0;m<6;m++) //6*8点阵
{
data=TTable[l*8+m];
WRDataL();
WaitNms(2);
}
}
/*右区显示字符*/
void DisCharR(char *TTable)
{
COLNUM=CLMADD|COL;
command=COLNUM;
WRCommandR();
for(m=0;m<6;m++) //6*8点阵
{
data=TTable[l*8+m];
WRDataR();
WaitNms(2);
}
}
/*左区显示中文*/
void DisplayL(void)
{
command=PAGEADD|PAGENUM;
WRCommandL();
command=CLMADD|CLMNUM;
WRCommandL();
for (k=0;k<16;k++){
data=CCTable[k];
WRDataL();
}
PAGENUM+=1;
command=PAGEADD|PAGENUM;
WRCommandL();
command=CLMADD|CLMNUM;
WRCommandL();
for (k=16;k<32;k++){
data=CCTable[k];
WRDataL();
}
PAGENUM-=1;
}
/*右区显示中文*/
void DisplayR(void){
command=PAGEADD|PAGENUM;
WRCommandR();
command=CLMADD|CLMNUM;
WRCommandR();
for (k=0;k<16;k++){
data=CCTable[k];
WRDataR();
}
command=CLMADD|CLMNUM;
WRCommandR();
PAGENUM+=1;
command=PAGEADD|PAGENUM;
WRCommandR();
for (;k<32;k++){
data=CCTable[k];
WRDataR();
}
PAGENUM-=1;
}
/*在图形方式下,绘点子程序。该程序在第row(0-63)行、第col(0-127)列绘点,行、列坐标均以点为单位*/
void DrawDot(int row,int col)
{
Uint pagelr,temprow,data0;
Uint bitset=0x01;
temprow=row;
PAGENUM=row/8; //页面地址
pagelr=PAGEADD|PAGENUM;
data=(bitset<<(temprow%8));
if (col<64)
{
command=pagelr; //写入页面地址
WRCommandL();
command=CLMADD|col; //写入列地址
WRCommandL();
data0=RDDataL(); //空读
data0=RDDataL(); //读取该处的初始数据
command=CLMADD|col;
WRCommandL();
data|=data0;
WRDataL();
}
else
{
col-=64;
command=pagelr; //写入页面地址
WRCommandR();
command=CLMADD|col;
WRCommandR();
data0=RDDataR(); //空读
command=CLMADD|col;
WRCommandR();
data0=RDDataR(); //读该单元的原有数据
data|=data0;
command=CLMADD|col;
WRCommandR();
WRDataR();
}
}
/*消点子程序*/
void ClrDot(int row,int col) /*行坐标以点为单位,列坐标以点为单位*/
{
Uint pagelr,temprow,data0;
Uint bitclr=0x01;
temprow=row;
PAGENUM=row/8; //页面地址
pagelr=PAGEADD|PAGENUM;
data=(~(bitclr<<(temprow%8)));
if (col<64)
{
command=pagelr;
WRCommandL();
command=CLMADD|col;
WRCommandL();
data0=RDDataL(); //空读
data0=RDDataL(); //读取该处的初始数据
data&=data0;
command=CLMADD|col;
WRCommandL();
WRDataL();
}
else
{
command=pagelr;
WRCommandR();
col-=64;
command=CLMADD|col;
WRCommandR();
data0=RDDataR(); //空读
data0=RDDataR(); //读取该处的初始数据
data&=data0;
command=CLMADD|col;
WRCommandR();
WRDataR();
}
}
/*画圆子程序:这里应用贝森海姆圆算法来绘制一个圆,以(x,y)为圆心以r为半径画一个圆*/
void DrawCircle(int x,int y,int r)
{
int x1,y1,x2,y2,a,b,delta1,delta2;
x1 = 0; y1 = r;
x2 = r; y2 = 0;
for(;x1 <= x2;)
{ a = x1; b = y1;
delta1 = (a + 1) * (a + 1) + b * b - r * r - b;
if(delta1 >= 0)
{ x1 += 1;
y1 -= 1;
}
else
{x1 += 1;
}
a = y2; b = x2;
delta2 = (a + 1) * (a + 1) + b * b - r * r - b;
if (delta2 >= 0)
{ x2 -= 1;
y2 += 1;
}
else
{y2 += 1;
}
DrawDot(x1 + x,y1 + y);
DrawDot(x1 + x,-1 * y1 + y);
DrawDot(-1 * x1 + x,y1 + y);
DrawDot(-1 * x1 + x,-1 * y1 + y);
DrawDot(x2 + x,y2 + y);
DrawDot(x2 + x,-1 * y2 + y);
DrawDot(-1 * x2 + x,y2 + y);
DrawDot(-1 * x2 + x,-1 * y2 + y);
}
}
/*画线子程序:为了回避复杂的浮点运算,采用了整数数字微分的方法*/
/*以(x行,y列)为起点,以(x1行,y1列)为终点画一条直线*/
void DrawLines(int x,int y,int x1,int y1)
{
int dx,dy,err = 0;
if(y != y1)
{
if(y1 < y) /*这个判断语句保证了y1>=y这个前提*/
{
dx = y1; dy = x1;
y1 = y; x1 = x;
y = dx; x = dy;
}
dy = y1 - y;
dx = x1 - x;
if((x1 >= x)&&((y1 - y) <= (x1 - x)))
{
for(;x != x1;)
{
if(err < 0)
{
DrawDot(x + 1,y);
x += 1;
err += dy;
}
else
{
DrawDot(x + 1,y + 1);
x += 1;
y += 1;
err += (dy - dx);
}
}
}
else
if((x1 >= x)&&((y1 - y) > (x1 - x)))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -