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

📄 lcd.c

📁 【液晶显示器的C语言程序设计 Freescale 8位微控制器】一书的光盘
💻 C
📖 第 1 页 / 共 2 页
字号:
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)))
			{
				for(;y != y1;)
				{
					if(err < 0)
					{
						DrawDot(x + 1,y + 1);
						x += 1;
						y += 1;
						err += (dy - dx);
					}
					else
					{
						DrawDot(x,y + 1);
						y += 1;
						err -= dx;
					}
				}
			}
			else
				if((x1 < x)&&((y1 - y) <= (x - x1)))
				{
					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)))
					{
						for(;y != y1;)
						{
							if(err < 0)
							{
								DrawDot(x - 1,y + 1);
								x -= 1;
								y += 1;
								err += (dy + dx);
							}
							else
							{
								DrawDot(x,y + 1);
								y += 1;
								err += dx;
							}
						}
					}
	}	
	else
	{
		dx = x; dy = x1;
		if(x < x1)
		{
			dx = x1;
			dy = x;
		}
		for(;dy < dx;dy++)
			DrawDot(dy,y);
	}
}
/*画坐标轴,x0(行)y0(列)为原点坐标,length为坐标长度*/
void DrawCoordinate(Uint x0,Uint y0,Uint length)
{
	DrawLines(x0,y0-4,x0,y0+length);	//横轴
	DrawLines(x0+4,y0,x0-length,y0);	//纵轴	
	DrawLines(x0,y0+length,x0-4,y0+length-4);	//横轴箭头
	DrawLines(x0,y0+length,x0+4,y0+length-4);	
	DrawLines(x0-length,y0,x0-length+4,y0+4);	//纵轴箭头
	DrawLines(x0-length,y0,x0-length+4,y0-4);	
}
//获得数组中的最大值
Uint GetMaxNum(Uint *ptr,Uint cnt)
{
	Uint i,max = 0;
	for(i = 0;i < cnt;i++)
	{
		if(max < ptr[i])
			max = ptr[i];
	}
	return max;
}
Uchar CanDraw(Uint x,Uint y,Uchar fillstyle)
{
	if(fillstyle == 0)
	{
		if((x + y) / 4 * 4 == x + y)
			return 1;	/*是偶数的话返回1,画该点*/
		else
			return 0;
	}
	else
	{
		if(((x - y) >= 0 ? (x - y) : (y - x)) / 4 * 4 == ((x - y) >= 0 ? (x - y) : (y - x)))
			return 1;	/*是偶数的话返回1,画该点*/
		else
			return 0;
	}
}
/*把屏幕某一部分涂黑:(x,y)是区域左上角坐标,(x1,y1)是区域右下角坐标,最后一个参数是填充方式*/
void BarFill(Uint x,Uint y,Uint x1,Uint y1,Uchar fillstyle)
{
	Uint i,j;
	for(i = y;i <= y1;i++)
		for(j = x;j <= x1;j++)
			if((CanDraw(j,i,fillstyle))||((i == y)||(i == y1)||(j == x1)||(j == x)))
				DrawDot(i,j);
}
/*图像显示程序:根据一个整数数组(里面有cnt个元素)显示一个柱状的显示图,
参数x,y,x1,y1代表一个矩形区域的左上角和右下角的坐标*/
void DrawBars(Uint *ptr,Uint cnt,Uint x,Uint y,Uint x1,Uint y1)
{	
	Uint k;
	Uint yitem = ((y1-y+1)/GetMaxNum(ptr,cnt));
	Uint xitem = ((x1-x+1)/cnt);
	DrawCoordinate(x,y1-6,x1-x+1);
	if(yitem == 0)
		yitem = 1;
	for(k = 0;k < cnt;k++)
	{
		if(k / 2 * 2 == k) /*k为偶数的话*/
		{
			BarFill(x+4+xitem*k,y1-yitem*ptr[k],x+xitem*(k+1),y1-10,0);
		}
		else
			BarFill(x+4+xitem*k,y1-yitem*ptr[k],x+xitem*(k+1),y1-10,1);
	}
	
}
/*屏读*/
void LcdPeek(){
	Uint cur,curtemp;
	
	data1=0x00;			/*文本区地址0行0列*/
	data2=0x00;
	command=0x24;
	WRCommandMany();
	
	data2=0x20;
	command=0xc4;
	WRCommandTwo();		/*写入“@”*/	
	
	data1=0x28;			/*文本区显示地址1行0列*/
	data2=0x00;
	command=0x24;
	WRCommandMany();
	
	data2=0x21;
	command=0xc4;
	WRCommandTwo();		/*写入“A”*/
	
	for(i=0;i<16;i++){
		cur=0x0800+i*40;
		curtemp=cur;
		
		data1=curtemp&0x00ff;
		data2=((cur&0xff00)>>8);/*图形区显示地址0行0列*/
		command=0x24;
		WRCommandMany();
	
		command=0xe0;		/*屏读指令*/
		WRCommandOne();
	
		ST6Read();			/*判断屏读状态是否正确*/
		RDData();
		command=0x0c4;
		WRCommandTwo();	
		}
	command=0x98;
	WRCommandOne();	
}
/*屏拷贝*/
void LcdCopy(void){
	Uint cur,curtemp;
	
	data1=0x00;			/*文本区地址0行0列*/
	data2=0x00;
	command=0x24;
	WRCommandMany();
		
	data2=0x03;
	command=0xc4;		/*写入“#”*/
	WRCommandTwo();
		
	data1=0x75;			/*文本区地址15行29列*/
	data2=0x02;
	command=0x24;
	WRCommandMany();
		
	data2=0x0a;
	command=0xc4;		/*写入“*”*/
	WRCommandTwo();
		
	for(i=0;i<128;i++){
		cur=0x0800+i*40;
		curtemp=cur;
		
		data1=curtemp&0x00ff;
		data2=((cur&0xff00)>>8);/*图形区显示地址0行0列*/
		command=0x24;
		WRCommandMany();
	
		command=0xe8;		/*屏拷贝指令*/
		WRCommandOne();
	
		ST6Read();			/*判断屏读状态是否正确*/	
		
		}
	command=0x98;
	WRCommandOne();	
}
/*该例程中采用的是4*4键盘。
/*0xEE,"A",0xDE,"1",0xBE,"2",0x7E,"3",
  0xED,"B",0xDD,"4",0xBD,"5",0x7D,"6",
  0xEB,"C",0xDB,"7",0xBB,"8",0x7B,"9",
  0xE7,"D",0xD7,"*",0xB7,"0",0x77,"#"
由于GP32的PTA口兼有键盘中断功能,因此将键盘的行、列共8条线连接到PTA口上,
其中行1-4连接到PTA0-3上,列1-4连接到PTA4-7上。这里提供一个键盘编程实例,
涉及如何扫描键盘获得键值,中断获取键值,键盘编码等问题。在编程时将PTA0-3定义为输出,
将PTA4-7定义为输入并具有内部上拉电阻,那么"A"键对应于PTA7~PTA0=11101110,即$EE;
"1"键对应于PTA7~PTA0=11011110,即$DE;"#"键对应于PTA7~PTA0=01110111,即$77。*/
/*键盘初始化*/
/* Key INITIALIZATION */
void KeyInit(void){
	PTA=0x00;
	DDRA=0x0f;
	PTAPUE=0xf0;
	INTKBIER=0xf0;
}
/* ReadKey */
Uchar ReadKey(void){
	Uchar temp,tempdata,key;
	Uint k;
	for(k=0;k<4;k++){			//依次扫描四行
		temp=KeyValue[k];		//使第k根行扫描线为低电平
		tempdata=PTA;			//
		tempdata|=0x0F;			//PTA4-7保留原态,令PTA0-3为1
		tempdata&=temp;
		PTA=tempdata;
		nop();
		nop();
		
		tempdata=PTA;
		tempdata&=0xF0;
		if (tempdata!=0xf0) {
			key=PTA;
			goto readkey1;
		}
	}
readkey1: return key;
}		
/*键盘中断*/
@interrupt void KeyISR(void){
	Uchar KeyValue;
	Uchar OutValue;
	Uchar k;
		
	INTKBSCR|=0x02;
	KeyValue=ReadKey();
	for(k=0;k<16;k++){
		if(KeyValue==KeyTable[k]){
			OutValue=k;
		}
	}
	switch(OutValue){
	case 0:						//"F1"显示西文字符串
		ClrGraphic();
		TextDisplay();
		break;
	case 1:						//"1"
		ClrGraphic();
		DrawDot(50,50);			//画点
		break;
	case 2:						//"2"
		ClrGraphic();
		DrawDot(10,10);			//先画点再消点
		WaitNms(2000);
		ClrDot(10,10);		
		break;
	case 3: 					//"3"
		ClrGraphic();
		DrawLines(10,5,10,100);		//10行5列为起点,5行100列为终点画线		
		break;
	case 4:						//"F2"
		ClrGraphic();
		CCDisplay(3,3);			//文本方式下显示汉字			
		break;
	case 5:						//"4"
		ClrGraphic();
		DrawCircle(50,50,30);		//50行50列为圆心,30为半径	 	
		break; 
	case 6:						//"5"
		ClrGraphic();
		DrawCoordinate(110,10,30);	//110行10列为原点,  坐标轴
		break;
	case 7:						//"6"	
		ClrGraphic();
		DrawBars(ptr,8,110,30,200,120);//左上角 右下角*/
		break;
	case 8:						//"F3"图形方式下显示汉字
		ClrGraphic();
		GCDisplay(14,6);
		break;
	case 9:						//"7"
		ClrGraphic();
		LeftScroll();			//画面左滚				
		break;
	case 10:					//"8"							
		ClrGraphic();
		UpScroll();				//画面上滚
		break;				
	case 11:					//"9"
		ClrGraphic();
		RightScroll();			//画面右滚
		break;
	case 12:					//"F4"
		LcdPeek();				//屏读
		break;
	case 13:					//"Clear"
		ClrGraphic();
		break;
	case 14:					//"0"
		ClrGraphic();
		DownScroll();			//画面下滚		
		break;
	case 15:					//"Enter"
		LcdCopy();				//屏拷贝
		break;		
	}		   	
	KeyInit();
	INTKBSCR|=0x04;	
	INTKBSCR&=~0x02;	
}		
//PLL初始化
void PLLInit(void){
	PCTL=0;				//关闭PLL,准备进行设置
    	PBWC=0x80;			//自动带宽模式
   	PCTL=1;				//R=1
    	PMSH=1;    			
   	PMSL=0x2c;			//N=012c
    	PMRS=0x80;			//L=80
    	PCTL=0x22;			//E=2,PLLON=1,启动PLL
    	while(!(PBWC&0x40));		//等待稳定输出
   	PCTL|=0x10;			//频率锁定,选PLL作为时钟源
}
/* 系统集成模块(SIM)初始化,禁止COP(看门狗)*/
void SIMInit(void) {
	CONFIG2=0x01; /* 内部总线时钟用作SCI的时钟*/
	CONFIG1=0x3d; /* 允许LVE复位信号,禁止LVI的电源,LVI工作在5V,*/
                  /* 经过32个CGMXCLK周期退出STOP模式,禁止COP模块 */ 
}

void main(void)
{  
   	sei();      		//关中断
	SIMInit();  		//SIM初始化
	PLLInit();  		//PLL初始化		
	DDRC=0x0F;
	PTCPUE=0xFF;		//上拉电阻允许
   	PTC.byte=0xff;
   	DDRC=0xFF;
   	PTB=0xff;
   	DDRB=0xff;
	BCLR(PTC,3);		//FS=0,8×8字体	
	WaitNms(1000);	
	
   	Init_LCD_Graphic();	//初始化屏幕
	ClrGraphic();		//清屏
//	CCDisplay(3,3);
	TextDisplay();		//文本显示
	GCDisplay(40,4);		
	KeyInit();		//键盘初始化
 	cli();			//开中断
   	for(;;);		//等待键盘中断,并进行处理
   	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -