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

📄 display.c

📁 51单片机C语言常用模块与综合系统设计实例精讲
💻 C
字号:
#include <stdio.h>
#include <absacc.h>
#include <./Atmel/at89x52.h>
#include <string.h>
#include <intrins.h>
#include "source.h"
//#include <intrins.h>
/*输入的X为以8个点为单位,Y以一个点为单位,宽度也是以8个点为单位的,高度以一个点为单位的.*/
unsigned char zero_buf[100]={//为全0的数据,在清除某行的时候用
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
};
void clear_all(void){
	unsigned int cnt;
	for(cnt=VRAM_BASE;cnt<VRAM_LEN;cnt++){
		XBYTE[cnt]=0X00;
	}
}
/**在orgx,orgy的位置上显示宽度为8,高度为depth的图片**/
void draw_wordw8(unsigned char orgx,unsigned int orgy,unsigned char depth,unsigned char *buf){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		XBYTE[basex]=buf[row];
		basex +=SCREEN_WIDTH;
	}
}
/**在orgx,orgy的位置上显示宽度为16,高度为depth的图片**/
void draw_wordw16(unsigned char orgx,unsigned int orgy,unsigned char depth,unsigned char *buf){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		temp=row<<1;
		XBYTE[basex]=buf[temp];
		XBYTE[basex+1]=buf[temp+1];
		basex +=SCREEN_WIDTH;
	}
}
/**在orgx,orgy的位置上显示宽度为24,高度为depth的图片**/
void draw_wordw24(unsigned char orgx,unsigned int orgy,unsigned char depth,unsigned char *buf){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		temp=row<<1;
		temp +=row;//temp=3*row
		XBYTE[basex]=buf[temp];
		XBYTE[basex+1]=buf[temp+1];
		XBYTE[basex+2]=buf[temp+2];
		basex +=SCREEN_WIDTH;
	}
}
/**在orgx,orgy的位置上显示宽度为32,高度为depth的图片**/
void draw_wordw32(unsigned char orgx,unsigned int orgy,unsigned char depth,unsigned char *buf){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		temp=row<<2;
		XBYTE[basex  ]=buf[temp  ];
		XBYTE[basex+1]=buf[temp+1];
		XBYTE[basex+2]=buf[temp+2];
		XBYTE[basex+3]=buf[temp+3];
		basex +=SCREEN_WIDTH;
	}
}
/**在orgx,orgy的位置上显示宽度为48,高度为depth的图片**/
void draw_wordw48(unsigned char orgx,unsigned int orgy,unsigned char depth,unsigned char *buf){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		temp=row<<2;
		temp +=row<<1;
		XBYTE[basex  ]=buf[temp  ];
		XBYTE[basex+1]=buf[temp+1];
		XBYTE[basex+2]=buf[temp+2];
		XBYTE[basex+3]=buf[temp+3];
		XBYTE[basex+4]=buf[temp+4 ];
		XBYTE[basex+5]=buf[temp+5];
		basex +=SCREEN_WIDTH;
	}
}
/**在orgx,orgy的位置上显示宽度为24,高度为24的图片**/
void draw_wordw24x24(unsigned char orgx,unsigned int orgy,unsigned char *buf){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<3;row++){
		temp=row<<1;
		temp +=row;
		XBYTE[basex]=buf[temp];
		XBYTE[basex+1]=buf[temp+1];
		XBYTE[basex+2]=buf[temp+2];
		basex +=SCREEN_WIDTH;
	}	
}
/**在orgx,orgy点阵为24x24,区码为qh,位码为wh的汉字**/
void draw_hz24x24(unsigned char orgx,unsigned int orgy,unsigned char qh,unsigned char wh){
	union SFADD offset;
	unsigned int ladd;
	unsigned int basex;
	unsigned char i;
	if(qh<16){//汉字库的区码从15开始
		return;
	}
	offset.l=(94*(qh-16)+(wh-1));//区位码与flash的对应关系
	offset.l *=72;
	offset.l +=FLASH_ADD_HZK24X24_START;//把其转换为flash可以寻址的范围
	ladd=offset.i[1];
	ladd &=FLASH_ADD_MASK;
	ladd |=FLASH_SPACE_START;//分离出flash的低位地址
	offset.l <<=2;
	FLASHADD=offset.c[1];//分离出flash的高位地址
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;//确定图片在屏幕上的位置
	if(ladd>=(FLASH_SPACE_END-3*24)){//因为每个汉字使用72个字节,表明其跨越了flash的高位地址.
		for(i=0;i<24;i++){
			XBYTE[basex  ]=XBYTE[ladd];
			if(ladd==FLASH_SPACE_END){//高位地址跨越16K字节,高位要进一
				FLASHADD=offset.c[1]+1;//高位地址进一
				ladd=0;
			}
			else{//没有跨越16K字节地址
					ladd++;//低位地址加一
			}
			XBYTE[basex+1]=XBYTE[ladd];
			if(ladd==FLASH_SPACE_END){
				FLASHADD=offset.c[1]+1;
				ladd=0;
			}
			else{
					ladd++;
			}
			XBYTE[basex+2]=XBYTE[ladd];	
			if(ladd==FLASH_SPACE_END){
				FLASHADD=offset.c[1]+1;
				ladd=0;
			}
			else{
					ladd++;
			}						
			basex +=SCREEN_WIDTH;
		}
	}
	else{//没有跨越16K字节地址
		for(i=0;i<24;i++){
			memcpy((unsigned char *)basex,(unsigned char *)ladd,3);//字节显示
			ladd +=3;//FLASH地址加3
			basex +=SCREEN_WIDTH;//换下一行
		}
	}
}
/**在orgx,orgy点阵为24x24汉字字库扩展为48x48,区码为qh,位码为wh的汉字**/
void draw_double_hz24x24(unsigned char orgx,unsigned int orgy,unsigned char qh,unsigned char wh){
	union SFADD offset;
	unsigned char frtemp[3];
	unsigned int ladd;
	unsigned int basex;
	unsigned char i;
	if(qh<16){//汉字库的区码从15开始
		return;
	}
	offset.l=(94*(qh-16)+(wh-1));//区位码与flash的对应关系
	offset.l *=72;
	offset.l +=FLASH_ADD_HZK24X24_START;//把其转换为flash可以寻址的范围
	ladd=offset.i[1];
	ladd &=FLASH_ADD_MASK;
	ladd |=FLASH_SPACE_START;//分离出flash的低位地址
	offset.l <<=2;
	FLASHADD=offset.c[1];//分离出flash的高位地址
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;//确定图片在屏幕上的位置
	if(ladd>=(FLASH_SPACE_END-3*24)){//因为每个汉字使用72个字节,表明其跨越了flash的高位地址.
		for(i=0;i<24;i++){	
			frtemp[0]=XBYTE[ladd];//取出第一字节的数据
			if(ladd==FLASH_SPACE_END){//高位地址跨越16K字节,高位要进一
				FLASHADD=offset.c[1]+1;//高位地址进一
				ladd=0;
			}
			else{//没有跨越16K字节地址
					ladd++;//低位地址加一
			}
			frtemp[1]=XBYTE[ladd];//取出第二字节的数据
			if(ladd==FLASH_SPACE_END){
				FLASHADD=offset.c[1]+1;
				ladd=0;
			}
			else{
					ladd++;
			}
			frtemp[2]=XBYTE[ladd];//取出第三字节的数据
			if(ladd==FLASH_SPACE_END){
				FLASHADD=offset.c[1]+1;
				ladd=0;
			}
			else{
					ladd++;
			}	
			/**下面把一行长度扩展一倍同时变成二行显示**/			
			XBYTE[basex  ]=double_byte[frtemp[0]][0];
			XBYTE[basex+1]=double_byte[frtemp[0]][1];
			XBYTE[basex+2]=double_byte[frtemp[1]][0];
			XBYTE[basex+3]=double_byte[frtemp[1]][1];
			XBYTE[basex+4]=double_byte[frtemp[2]][0];
			XBYTE[basex+5]=double_byte[frtemp[2]][1];
			basex +=SCREEN_WIDTH;
			XBYTE[basex  ]=double_byte[frtemp[0]][0];
			XBYTE[basex+1]=double_byte[frtemp[0]][1];
			XBYTE[basex+2]=double_byte[frtemp[1]][0];
			XBYTE[basex+3]=double_byte[frtemp[1]][1];
			XBYTE[basex+4]=double_byte[frtemp[2]][0];
			XBYTE[basex+5]=double_byte[frtemp[2]][1];
			basex +=SCREEN_WIDTH;
		}
	}
	else{
		for(i=0;i<24;i++){
			frtemp[0]=XBYTE[ladd];ladd++;
			frtemp[1]=XBYTE[ladd];ladd++;
			frtemp[2]=XBYTE[ladd];ladd++;
			/**下面把一行长度扩展一倍同时变成二行显示**/	
			XBYTE[basex  ]=double_byte[frtemp[0]][0];
			XBYTE[basex+1]=double_byte[frtemp[0]][1];
			XBYTE[basex+2]=double_byte[frtemp[1]][0];
			XBYTE[basex+3]=double_byte[frtemp[1]][1];
			XBYTE[basex+4]=double_byte[frtemp[2]][0];
			XBYTE[basex+5]=double_byte[frtemp[2]][1];
			basex +=SCREEN_WIDTH;
			XBYTE[basex  ]=double_byte[frtemp[0]][0];
			XBYTE[basex+1]=double_byte[frtemp[0]][1];
			XBYTE[basex+2]=double_byte[frtemp[1]][0];
			XBYTE[basex+3]=double_byte[frtemp[1]][1];
			XBYTE[basex+4]=double_byte[frtemp[2]][0];
			XBYTE[basex+5]=double_byte[frtemp[2]][1];
			basex +=SCREEN_WIDTH;
		}
	}
}
/***在屏幕上显示大数字的图片,其为112x170,每个数字被安排在没4K字节的起始空间,所以不存在跨越16K边界的问题**/
void draw_storey(unsigned char orgx,unsigned int orgy,unsigned char num){//this is 112x170
	unsigned char row;
	unsigned int basex;
	unsigned int ladd;
	union SFADD offset;
	basex=0x8000+SCREEN_WIDTH*orgy+orgx;
	//draw picture from flash. 4kbyte per picture 
	offset.l=num;
	offset.l <<=12;//乘以4K,因为每个大数字图片占用4K字节的空间
	offset.l +=FLASH_ADD_STORY_START;
	ladd=offset.i[1];
	ladd &=FLASH_ADD_MASK;
	ladd |=FLASH_SPACE_START;//分离出flash的低位地址
	offset.l <<=2;
	FLASHADD=offset.c[1];//分离出flash的高位地址
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;//确定图片在屏幕上的位置
	for(row=0;row<STOREY_HEIGHT;row++){
		memcpy((unsigned char *)basex,(unsigned char *)ladd,STOREY_WIDTH);
		ladd +=STOREY_WIDTH;
		basex +=SCREEN_WIDTH;
	}	
}
/**画向下的箭头图片为96x97点阵**/
void draw_downarrow(unsigned char orgx,unsigned int orgy){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	unsigned char *buf;
	buf=downarrow;//12x97
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	/**箭头图片是存储在单片机的程序空间,可以直接寻址**/
	for(row=0;row<ARROW_HEIGHT;row++){
		temp=row*ARROW_WIDTH;
		memcpy((unsigned char *)basex,(unsigned char *)buf+temp,ARROW_WIDTH);
		basex +=SCREEN_WIDTH;
	}
}
/**画向上的箭头图片为96x97点阵,是把向下的箭头图片上下颠倒一下就可以了**/
void draw_uparrow(unsigned char orgx,unsigned int orgy){
	unsigned char row;
	unsigned int temp;
	unsigned int basex;
	unsigned char *buf;
	unsigned int top_num;
	top_num=ARROW_WIDTH*(ARROW_HEIGHT-1);
	buf=downarrow;//12x97
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<ARROW_HEIGHT;row++){//ARROW_HEIGHT=97
		temp=top_num-row*ARROW_WIDTH;
		memcpy((unsigned char *)basex,(unsigned char *)buf+temp,ARROW_WIDTH);
		basex +=SCREEN_WIDTH;
	}
}
/*画24x48的ASSCII字符,因为此字符不在汉字字库中,	存储的形式只有位码*/
void draw_asc24x48(unsigned char orgx,unsigned int orgy,unsigned char wh){
	union SFADD offset;
	unsigned int ladd;
	unsigned int basex;
	unsigned char i;
	offset.l=wh;
	offset.l *=144;//每个字符是144个字节
	offset.l +=FLASH_ADD_ASC48X48_START;
	ladd=offset.i[1];
	ladd &=0x3fff;
	ladd |=FLASH_SPACE_START;
	offset.l <<=2;
	FLASHADD=offset.c[1];
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(i=0;i<48;i++){
		XBYTE[basex  ]=XBYTE[ladd];ladd++;
		XBYTE[basex+1]=XBYTE[ladd];ladd++;
		XBYTE[basex+2]=XBYTE[ladd];ladd++;
		basex +=SCREEN_WIDTH;
	}
}
void draw_asc16x24(unsigned char orgx,unsigned int orgy,unsigned char wh){
	union SFADD offset;
	unsigned int ladd;
	unsigned int basex;
	unsigned char i;
	offset.l=wh+32;//英文的区位码减32为ASCII的数值。
	offset.l *=48;//perword is 48 bytes.
	offset.l +=FLASH_ADD_ASC16X24_START;
	ladd=offset.i[1];
	ladd &=FLASH_ADD_MASK;
	ladd |=FLASH_SPACE_START;
	offset.l <<=2;
	FLASHADD=offset.c[1];
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(i=0;i<24;i++){
		XBYTE[basex  ]=XBYTE[ladd];ladd++;
		XBYTE[basex+1]=XBYTE[ladd];ladd++;
		basex +=SCREEN_WIDTH;
	}
}
/**显示从串口传输过来的信息**/
void show_elvinfo(struct NOTICE *info){
	unsigned char orgtemp,ad_len,cnt,temp,hzqh,hzwh;
	unsigned int cur_y;
	ad_len=info->len;/*表示显示汉字的长度*/
	ad_len >>=1;//由于一个汉字要一个区码和一个位码表示,所以整个要显示的汉字数为文字长度除2
	orgtemp=POS_NOTICE_ORGX;
	cur_y=POS_NOTICE_SINGEL_LINE_ORGY;
	for(cnt=0;cnt<ad_len;cnt++){// draw_hz24x24
		temp=cnt<<1;//第一个区码,第二个是位码
		hzqh=info->buf[temp];
		if(hzqh<HZK24X24_QH_START){//IT IS OUT OF HZK24X24
			if(hzqh==3){//是英文和数值区域。
				if((orgtemp+QW_ASSCII_SPACE)<SCREEN_WIDTH){//是空格
					draw_asc24x48(orgtemp,cur_y,info->buf[temp+1]);
					orgtemp +=QW_ASSCII_SPACE;
				}
			}
			else if(hzqh==10){//是控制字符
				hzwh=info->buf[temp+1];
				if((hzwh&0xf0)==0x20){//是空格空格
					hzwh &=0x0f;
					hzwh +=1;
					orgtemp +=QW_ASSCII_SPACE*hzwh;
				}
				else if(hzwh==0x0a){//是回车
					cur_y +=POS_NOTICE_LINE_HIGH;//换到下一行
					orgtemp=0;
				}
			}
		}
		else{//是汉字
			if((orgtemp+QW_HZ_SPACE)<SCREEN_WIDTH){
				draw_double_hz24x24(orgtemp,cur_y,hzqh,info->buf[temp+1]);//写汉字
				orgtemp +=QW_HZ_SPACE;//显示位置到下一个汉字
			}
		}
	}
}
/*在orgx,orgy处清除宽度为8高度为depth的区域*/
void clr_wordw8(unsigned char orgx,unsigned int orgy,unsigned char depth){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		XBYTE[basex]=0;;
		basex +=SCREEN_WIDTH;
	}
}
/*在orgx,orgy处清除宽度为16高度为depth的区域*/
void clr_wordw16(unsigned char orgx,unsigned int orgy,unsigned char depth){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		memcpy((unsigned char *)basex,(unsigned char *)zero_buf,2);
		basex +=SCREEN_WIDTH;
	}
}
/*在orgx,orgy处清除宽度为24高度为depth的区域*/
void clr_wordw24(unsigned char orgx,unsigned int orgy,unsigned char depth){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		memcpy((unsigned char *)basex,(unsigned char *)zero_buf,3);
		basex +=SCREEN_WIDTH;
	}
}
/*在orgx,orgy处清除宽度为32高度为depth的区域*/
void clr_wordw32(unsigned char orgx,unsigned int orgy,unsigned char depth){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=0;row<depth;row++){
		memcpy((unsigned char *)basex,(unsigned char *)zero_buf,4);
		basex +=SCREEN_WIDTH;
	}
}
/*在orgx,orgy处清除宽度为width高度为depth的区域,是通用的清除函数*/
void clr_area(unsigned char org_x,unsigned int org_y,unsigned char width,unsigned char height){
	unsigned char row;
	unsigned char column;
	unsigned int tempa,tempb;
	for(row=0;row<height;row++){
		tempa=VRAM_BASE+SCREEN_WIDTH*(org_y+row)+org_x;
		tempb=width*row;
		for(column=0;column<width;column++){
			XBYTE[tempa+column]=0x00;
		}
	}
}
/*在orgx,orgy处清除箭头*/
void clr_arrow(unsigned char orgx,unsigned int orgy){
	unsigned char row;
	unsigned int basex;
	basex=VRAM_BASE+SCREEN_WIDTH*orgy+orgx;
	for(row=ARROW_HEIGHT;row>0;row--){
		memcpy((unsigned char *)basex,(unsigned char *)zero_buf,ARROW_WIDTH);
		basex +=SCREEN_WIDTH;
	}
}
/*清除显示信息的区域*/
void clr_notice(void){
	unsigned int j,basex;
	basex=VRAM_BASE+SCREEN_WIDTH*POS_NOTICE_TOP+POS_NOTICE_ORGX;
	for(j=POS_NOTICE_TOP;j<SCREEN_HIGHT;j++){
		memcpy((unsigned char *)basex,(unsigned char *)zero_buf,SCREEN_WIDTH-POS_NOTICE_ORGX);
		basex +=SCREEN_WIDTH;
	}
}

⌨️ 快捷键说明

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