📄 lcd.c
字号:
//控制器:HD61830
//设计者:李晶皎
//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; /*无符号整型数据类型的定义*/
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)
#define CLRBYTE(x) ((x).byte = 0)
Uint i,k;
const Uint count=5;
const Uint ptr[5]={15,20,25,30,35};
const unsigned char KeyValue[4]={0xfe,0xfd,0xfb,0xf7};
const unsigned char KeyTable[16]={0xee,0xde,0xbe,0x7e,
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
@tiny volatile BIT_CHAR PTC @0x02;
const int StringLength=19;
const char String[19]={"WELCOME USE HD61830"};
const Uchar CLength=11;
const Uchar CTable[352]={
0x80,0xFC,0x24,0xFC,0x64,0xB4,0x2C,0xA4,0xF4,0x04,0xF4,0x04,0xFA,0x02,0x41,0x80,
0x00,0x7F,0x04,0x3F,0x0C,0x16,0x65,0x04,0x1F,0x01,0x3F,0x01,0x7F,0x01,0x01,0x00,//摩
0x04,0x04,0xC4,0x1F,0x04,0x04,0x14,0xEC,0x07,0x04,0x04,0x04,0x04,0x04,0x05,0x02,
0x00,0x3C,0x03,0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0x02,0x42,0x42,0x7C,0x00,//托
0x00,0xFC,0x44,0x44,0x44,0xFC,0x44,0xC0,0x60,0x30,0x48,0x86,0x00,0xC0,0x30,0x0F,
0x00,0x3F,0x22,0x22,0x22,0x3F,0x00,0x3F,0x10,0x10,0x08,0x04,0x03,0x00,0x00,0x00,//罗
0x08,0x08,0x08,0x88,0x3F,0x08,0xA8,0x18,0x0C,0x0B,0x08,0x08,0x08,0xE8,0x0A,0x04,
0x01,0x06,0x04,0x7F,0x00,0x10,0x30,0x11,0x11,0x12,0x0A,0x0A,0x0A,0x7F,0x00,0x00,//拉
0x10,0x60,0x20,0xFC,0x84,0xFC,0x84,0x84,0xFC,0x84,0x80,0xFF,0x80,0x80,0x80,0x80,
0x04,0x0C,0x02,0x1F,0x10,0x1F,0x10,0x10,0x1F,0x10,0x00,0x7F,0x00,0x00,0x00,0x00,//单
0x00,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x04,0x04,0x02,0x01,
0x02,0x02,0x02,0x22,0x7F,0x00,0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,//片
0x08,0x08,0x08,0x7F,0x08,0x08,0x1C,0x2C,0x2A,0x0A,0x89,0x88,0x48,0x48,0x28,0x08,
0x00,0x1F,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x50,0x50,0x50,0x60,0x00,//机
0x04,0xC8,0x08,0x02,0xE2,0x22,0x22,0xE2,0x22,0x22,0xE2,0x02,0x02,0x02,0x02,0x02,
0x00,0x3F,0x20,0x20,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x20,0x20,0x20,0x28,0x10,//间
0x08,0x08,0xC8,0xBF,0x08,0xE8,0x28,0x18,0x0C,0xFB,0x88,0xC8,0x08,0x08,0x8A,0x64,
0x02,0x04,0x3F,0x10,0x09,0x7F,0x00,0x01,0x01,0x7F,0x08,0x08,0x07,0x0A,0x31,0x20,//接
0x08,0x08,0x08,0xBF,0x88,0x08,0x28,0x98,0x0C,0x8B,0x08,0x08,0x08,0x08,0xCA,0x04,
0x00,0x04,0x08,0x7F,0x20,0x0A,0x31,0x20,0x00,0x3F,0x04,0x04,0x04,0x04,0x7F,0x00,//控
0x24,0x2C,0x24,0xFC,0x22,0x20,0xFE,0x20,0xFC,0x24,0x24,0x24,0x24,0xE4,0xA0,0x20,
0x20,0x20,0x24,0x25,0x24,0x24,0x25,0x24,0x25,0x25,0x25,0x25,0x21,0x21,0x28,0x10//制
};
const int delay=80;
const Uint RamAddr=0;
/*数据类型定义部分*/
#define BSET(x, y) ((x).b.b ## y = 1)
#define BCLR(x, y) ((x).b.b ## y = 0)
#define CLRBYTE(x) ((x).byte = 0)
/*1 ms延迟*/
static void Wait1ms(void) {
int cnt = 0;
while (cnt <delay) cnt++;
}
/*n ms延迟*/
void WaitNms(int n){
int i;
for(i=1;i<=n;i++) Wait1ms();
}
/*产生E1信号的下降沿*/
void Toggle(void){
BSET(PTC,2); /* (BSET 2,PTC) */
BCLR(PTC,2); /* (BCLR 2,PTC) */
}
/*读状态位*/
void BFRead(void){
Uchar temp;
BSET(PTC,0); //RS=1
BSET(PTC,1); //R/W=1
DDRB=0x00;
while(1){
BSET(PTC,2); //E1=1
temp=PTB;
BCLR(PTC,2); //E2=0
if ((temp&0x80)==0x00){break;}
}
}
/*写指令代码*/
void WRCommand(unsigned char command){
BFRead();
BCLR(PTC,1);
DDRB=0xff;
PTB=command;
Toggle();
}
/*写指令的参数或数据*/
void WRData(unsigned char data){
// BFRead();
BCLR(PTC,0);
BCLR(PTC,1);
DDRB=0xff;
PTB=data;
Toggle();
}
/*读数据*/
Uchar RDData(void){
Uchar temp;
BFRead();
BCLR(PTC,0); //RS=0
DDRB=0x00;
BSET(PTC,2);
temp=PTB;
BCLR(PTC,2);
return temp;
}
/*设置显示首地址*/
void SetDispalyAddr(Uint RamAddr){
Uint RamAddrl,RamAddrh;
RamAddrl=RamAddr&0x00ff;
RamAddrh=((RamAddr&0xff00)>>8);
WRCommand(0x08); //设置显示起始地址
WRData(RamAddrl); //低字节0x00
WRCommand(0x09); //
WRData(RamAddrh); //高字节0x00
}
/* 设置光标,若是文本方式下,则row(0~15)col(1~29)列;图形方式下则row(1~128)行col(1~29)列*/
void SetCursor(Uchar row,Uchar col){
Uint cursor,tempcur,addl,addh;
cursor=RamAddr+row*30+col;
tempcur=cursor;
addl=tempcur&0x00ff;
addh=((cursor&0xff00)>>8);
WRCommand(0x0a); //设置光标指针地址
WRData(addl); //低地址
WRCommand(0x0b);
WRData(addh); //高地址
}
/*send
/*初始化HD61830B文本显示方式的初始化子程序*/
void Init_LCD_Text(void){
unsigned int i,RamLength=1024*8;//16*40
WRCommand(0x00); //设置方式
WRData(0x3c); //开显示 主方式 文本方式
WRCommand(0x01); //设置字体
WRData(0x75); //字符字体为8*6点阵
WRCommand(0x02); //设置显示域宽度
WRData(0x1D); //一行占显示存储器30字节
WRCommand(0x03); //设置帧信号
WRData(0x7f); //128扫描行
WRCommand(0x04); //设置光标形状
WRData(0x07); //底线形式
SetDispalyAddr(0); //设置显示起始地址
SetCursor(0,0); //清屏
WRCommand(0x0c);
for (i=0;i<(RamLength);i++){
WRData(0x00);}
}
/*初始化HD61830B图形显示方式的初始化子程序*/
void Init_LCD_Grap(void){
Uint RamLength=3840; //30*128==3840
WRCommand(0x00); //设置方式
WRData(0x32); //开显示 主方式 图形方式
WRCommand(0x01); //设置字体
WRData(0x77); //字符字体为8*8点阵
WRCommand(0x02); //设置显示域宽度
WRData(0x1D); //一行占显示存储器30字节
WRCommand(0x03); //设置帧信号
WRData(0x7f); //128扫描行
SetDispalyAddr(0); //设置显示起始地址
SetCursor(0,0);
WRCommand(0x0c);
for (i=0;i<RamLength;i++){
WRData(0x00);
}
}
/*在LCD上显示西文字符*/
void CGDisplay(Uchar row,Uchar col,char *str){
int i;
SetCursor(row,col);
WRCommand(0x0c);
for (i=0;i<StringLength;i++){
WRData(str[i]);}
}
/*HD61830只能在图形方式下写入汉字*/
void DisplayChina(Uchar row,Uchar col){
Uchar temprow;
temprow=row;
for(i=0;i<11;i++){
row=temprow;
for (k=0;k<16;k++)
{
SetCursor(row,col);
WRCommand(0x0c);
WRData(CTable[i*32+k]);
WRData(CTable[i*32+k+16]);
row+=1;
}
col+=2;
}
}
/*在图形方式下,绘点子程序*/
void DrawDot(int row,int col) /*行坐标以点为单位,列坐标以点为单位*/
{
SetCursor(row,col/8);
/*置位操作*/
WRCommand(0x0f);
WRData(col & 0x0007);
}
/*消点子程序*/
void ClrDot(int row,int col) /*行坐标以点为单位,列坐标以点为单位*/
{
SetCursor(row,col/8);
/*清位操作*/
WRCommand(0x0e);
WRData(col&0x0007);
}
/*画圆子程序:这里应用贝森海姆圆算法来绘制一个圆,以(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)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -