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

📄 lcd.c

📁 【液晶显示器的C语言程序设计 Freescale 8位微控制器】一书的光盘
💻 C
📖 第 1 页 / 共 2 页
字号:
//控制器: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 + -