实验二LCD显示控制共17页文档.docx

上传人:b****8 文档编号:30029680 上传时间:2023-08-04 格式:DOCX 页数:12 大小:19.94KB
下载 相关 举报
实验二LCD显示控制共17页文档.docx_第1页
第1页 / 共12页
实验二LCD显示控制共17页文档.docx_第2页
第2页 / 共12页
实验二LCD显示控制共17页文档.docx_第3页
第3页 / 共12页
实验二LCD显示控制共17页文档.docx_第4页
第4页 / 共12页
实验二LCD显示控制共17页文档.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

实验二LCD显示控制共17页文档.docx

《实验二LCD显示控制共17页文档.docx》由会员分享,可在线阅读,更多相关《实验二LCD显示控制共17页文档.docx(12页珍藏版)》请在冰豆网上搜索。

实验二LCD显示控制共17页文档.docx

实验二LCD显示控制共17页文档

实验二LCD显示控制

一、实验目的

通过本次实验进一步熟悉MagicARM2410GPIO、UART、RTC的工作原理;

学习LCD的工作原理,并能编程控制。

二、实验要求

在实验一的基础上,研读LCD显示源代码,作适当修改,实现下列功能:

1、系统启动时,在LCD上显示下列信息:

(1)、年月日及当前时间(拓展:

能自行设置时);

(2)、个人的班级姓名学号(拓展:

汉字显示)。

2、使用实验箱上小键盘输入一个(x,y)坐标,以此坐标作为图片的顶点位置,显示一幅个人照片或图片。

3、LCD同步显示超级终端上的信息。

三、实验原理

(1)ZLG——7290

 ZLG7290的核心是一块ZLG7290B芯片,它采用I2C接口,能直接驱动8位共阴式数码管,同时可扫描管理多达64只按键,实现人机对话的功能资源十分丰富。

除具有自动消除抖动功能外,它还具有段闪烁、段点亮、段熄灭、功能键、连击键计数等强大功能,并可提供10种数字和21种字母的译码显示功能,用户可以直接向显示缓存写入显示数据,而且无需外接元件即可直接驱动数码管,还可扩展驱动电压和电流。

用户按下某个键时,ZLG7290的INT引脚会产生一个低电平的中断请求信号,读取键值后,中断信号就会自动撤销。

正常情况下,微控制器只需要判断INT引脚就可以得到键盘输入的信息。

微控制器可通过两种方式得到用户的键盘输入信息。

其一是中断方式,该方式的优点是抗干扰能力强,缺点是要占用微控制器的一个外部中断源。

其二是查询方式,即通过不断查询INT引脚来判断是否有键按下,该方式可以节省微控制器的一根I/O口线,但是代价是I2C总线处于频繁的活动状态,消耗电流多并且不利于抗干扰。

(2)LCD工作原理

LCD显示字符

《法一》其实每一字符就是一幅图像,字符的大小对应于图像的大小,字符的笔画对应于图像的内容。

那么如何把字符转换为图像呢?

简单的方法是使用“字模提取”之类的软件,它能够把任意的字符转换为一个字节型的数组,数组元素中的每一位代表LCD上的一个像素点,当为1时,表示该位置为字符的一个笔画,需要上色,而为0时,表示不是笔画,不需要上色。

例如,一个字符想要在16×16的面积上显示,即该字符的宽和高各为16个像素,因为每一个像素用一位来表示,因此用字模提取软件生成的字节型数组,一共有16×16÷8=32个字节。

在字模提取的过程中,还要注意取模的顺序,顺序不同,得到的数组就不同,一般来说是从字符的左上角开始,从左向右,从上到下取模,这样程序编写上会方便一些。

相同字体大小的中文字符和ASCII码字符的宽度还有所不同,一般ASCII码字符的宽度是中文字符宽度的一半,所以显示中文字符的程序和显示ASCII码字符的程序还略有不同。

当把一个字符取模变成一个数组后,只要对该数组中每个元素的每一位依次进行判断,对值为1的位和值为0的位进行不同的上色处理,即可完成一个字符的绘制。

《法二》如果要在程序中显示大量的中文字符,是不是要把这些字符都取模啊?

回答是肯定的,但前人已经为我们完成了这一步,做成了数据库,并且进行了编码,只要按照编码规则调用该库文件,就可以检索到相要的字符。

下面就来说说编码规则:

每个汉字是由两个字节表示的,前一个字节表示的区号,后一个字节表示的位号,那么汉字在汉字库中的位置为:

94×(区号-1)+(位号-1)。

94表示的是每个区里一共有94个汉字,减1表示的是数组是从0开始,而区号和位号是从1开始的。

具体到汉字在某一数据库中的位置,还需要乘以一个汉字字模所占的字节数,即[94×(区号-1)+(位号-1)]×一个汉字字模所占字节数。

如一个字模大小为16×16的宋体数据库,库里每个汉字所占的字节为16×16÷8=32,则每个汉字在该宋体数据库中的位置为:

[94×(区号-1)+(位号-1)]×32。

ASCII码的字符调用比汉字字符要简单,只要把它乘以字模所占字节数即可找到该字符所在字库的位置,如8×16的ASCII字库,ASCII码在该字库的位置为ASCII×16。

如果中文字符和ASCII码混合在一样,如何区分它们呢?

其实也很简单,ASCII码的最高位是0,而中文的最高位是1,因此当读取到的一个字节的最高位是0,则该字节为ASCII码,它的下一个字节与这个字节无关;当取得到的字节的最高位是1,则表示的是中文字符,并且该字节与它的下一个字节组合在一起表示完整的一个汉字。

编码规则介绍完了,那么如何打开字库呢?

我们可以利用前人已做好的字库,然后像访问一般文件一样打开它。

另一种方法是把字库变换成一个超大的数组,那么我们就可以像操作数组一样读取字库了。

voidMain(void)

unsignedcharString[]="我的名字是:

Newtton";

intlength=sizeof(String);

intk,xx;

unsignedcharqh,wh;

constunsignedchar*mould;

LCD_Init();

rLCDCON1|=1;

Brush_Background(0xffffff);

for(k=0,xx=0;k

if(String[k]&0x80)//中文字符

qh=String[k]-0xa0;//区号

wh=String[k+1]-0xa0;//位号

mould=&__HZK[((qh-1)*94+wh-1)*32];

Draw_Text16(4+xx,100,0x0f,mould);

xx+=16;

k++;

else//ASCII码字符

mould=&__ASCII[String[k]*16];

Draw_ASCII(4+xx,100,0x0,mould);

xx+=8;

while

(1)

当然第二种方法方便多了,不用对模了字符慢慢取了

LCD显示照片

首先将照片像字符那样用取模工具取模,显示的原理与字符大同小异。

【注意:

照片的大小一定要与你写的程序吻合,否则不能正常显示】

四、实验程序

//指定位置画点:

uint32GUI_Point(uint16x,uint16y,TCOLORcolor)

volatileuint16*p_buffer;

//参数过滤

if(x>=GUI_LCM_XMAX)return(0);

if(y>=GUI_LCM_YMAX)return(0);

//刷新显示

p_buffer=(uint16*)FrameBuffer;//设置填充显示缓冲区的地址

p_buffer=p_buffer+y*GUI_LCM_XMAX+x;//计算显示点对应显示缓冲区的位置

*p_buffer=color;//写入数据

return

(1);

//填充矩形框:

两个坐标确定以矩形框

voidGUI_RectangleFill(uint32x0,uint32y0,uint32x1,uint32y1,TCOLORcolor)

uint32i;

//先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1)

if(x0>x1)//若x0>x1,则x0与x1交换

i=x0;

x0=x1;

x1=i;

if(y0>y1)//若y0>y1,则y0与y1交换

i=y0;

y0=y1;

y1=i;

//判断是否只是直线

if(y0==y1)

GUI_HLine(x0,y0,x1,color);

return;

if(x0==x1)

GUI_RLine(x0,y0,y1,color);

return;

while(y0<=y1)

GUI_HLine(x0,y0,x1,color);//当前画水平线

y0++;//下一行

//指定位置显示图片(图片大小为w、h)。

intGUI_DispPic(uint16x,uint16y,

uint16w,uint16h,

uint16*buffer)

inti,j;

volatileuint16*p_buffer;

//需填充区域参数过滤

if((x>=GUI_LCM_XMAX)||

(y>=GUI_LCM_YMAX)

{return

(1);

if((x+w)>GUI_LCM_XMAX)

{return

(1);

if((y+h)>GUI_LCM_YMAX)

{return

(1);

//更新显示数据

for(i=0;i

//输出一行(w)数据

p_buffer=(uint16*)FrameBuffer;

p_buffer=p_buffer+y*GUI_LCM_XMAX+x;

for(j=0;j

*p_buffer++=*buffer++;//输出数据

//指向下一行

y++;

}//endoffor(i=0;i

return(0);

//指定位置显示字符串—字体色—背景色

voidllcd_disp_hz16(uint16x00,uint16y00,uint8*ss,TCOLORzColor,TCOLORbColor)

uint16i,j,k,x,y,xx;

uint8qm,wm;

uint32ulOffset;

uint8hzbuf[32],temp[2];

for(i=0;i

if(((uint8)(*(ss+i)))<161)

temp[0]=*(ss+i);

temp[1]='\0';

break;

else

qm=*(ss+i)-161;

wm=*(ss+i+1)-161;

ulOffset=(uint32)(qm*94+wm)*32;

for(j=0;j<32;j++)

hzbuf[j]=g_ucHZK16[ulOffset+j];

for(y=0;y<16;y++)

for(x=0;x<16;x++)

k=x%8;

if(hzbuf[y*2+x/8]&(0x80>>k))

xx=x00+x+i*8;

//PutPixel(xx,y+y00,HzColor);

//GUI_Point(uint16x,uint16y,TCOLORcolor);

GUI_Point(xx,y+y00,zColor);

GUI_Point(xx,y+y00,bColor);

i++;

///主函数

voidmain(void)

unsignedshortkey=0,key1=0;

uint16m=0;

//初始化I/O

rGPHCON=(rGPHCON&(~(0x03<<20)))|(0x01<<20);

UART_Select(0);

UART_Init();

InitI2C();

//设置中断服务程序

VICVectAddr[10]=(uint32)IRQ_Time0;

//设置中断控制器

rPRIORITY=0x00000000;//使用默认的固定的优先级

rINTMOD=0x00000000;//所有中断均为IRQ中断

rINTMSK=~(1<<10);//打开TIMER0中断允许

//定时器设置

//Fclk=200MHz,时钟分频配置为1:

2:

4,即Pclk=50MHz。

rTCFG0=250;//预分频器0设置为250,取得200KHz

rTCFG1=1;//TIMER0再取1/4分频,取得50KHz

rTCMPB0=0x0000;//设置定时器为0

rTCNTB0=25*1000;//定时0.5秒

rTCON=(1<<1);//更新定时器数据

rTCON=(1<<0)|(1<<3);//启动定时器

//IRQEnable();//使能IRQ中断(CPSR)

UART_SendStr("系统已启动!

\n");

RunBeep();

DispDesktop();

//LCD_PutStringGB24_kt(250,300,"系统已启动",BLACK,LGRAY);

llcd_disp_hz16(250,300,(uint8*)"启动",BLACK,LGRAY);

DelayNS(30);

while

(1)

DispDesktop();

UART_SendStr("当前系统时间为:

\n");

Rtc_uart();

GUI_RectangleFill(120,80,520,380,LGRAY);

llcd_disp_hz16(250,100,(uint8*)"时间",RED,LGRAY);

//LCD_PutStringGB24_kt(250,200,"系统当前时间",RED,LGRAY);

Rtc_lcd(200,200);

LCD_PutStringGB16_st(250,300,"按任意键继续!

",WHITE,BLACK);

UART_SendStr("按任意键继续!

\n");

key=0;

while(key==0)

DelayNS

(1);

key=ZLG7290_GetKey();

if((key&0xFF00)==0)

key=key&0x00FF;

Rtc_uart();

Rtc_lcd(200,200);

DelayNS(10);

Menu_pic();//主菜单

//DelayNS(50);

key=0;

while(key!

=13)

key=0;

while(key==0)

//DelayNS

(1);

key=ZLG7290_GetKey();

if((key&0xFF00)==0)

key=key&0x00FF;

if(key>0&&key<5)m=key;

if(key==16)m--;

if(key==14)m++;

if(m>4)m=1;

if(m<1)m=4;

switch(m)

case1:

GUI_RectangleFill(220,70,420,110,DGRAY);

GUI_RectangleFill(220,130,420,170,DGRAY);

GUI_RectangleFill(220,190,420,230,DGRAY);

GUI_RectangleFill(220,250,420,290,DGRAY);

LCD_PutStringGB24_kt(240,78,"颜色测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,138,"随机测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,198,"汉字测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,258,"图片测试",BLACK,DGRAY);

GUI_RectangleFill(220,70,420,110,CYAN);

LCD_PutStringGB24_kt(240,78,"颜色测试",BLACK,CYAN);

break;

case2:

GUI_RectangleFill(220,70,420,110,DGRAY);

GUI_RectangleFill(220,130,420,170,DGRAY);

GUI_RectangleFill(220,190,420,230,DGRAY);

GUI_RectangleFill(220,250,420,290,DGRAY);

LCD_PutStringGB24_kt(240,78,"颜色测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,138,"随机测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,198,"汉字测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,258,"图片测试",BLACK,DGRAY);

GUI_RectangleFill(220,130,420,170,CYAN);

LCD_PutStringGB24_kt(240,138,"随机测试",BLACK,CYAN);

break;

case3:

GUI_RectangleFill(220,70,420,110,DGRAY);

GUI_RectangleFill(220,130,420,170,DGRAY);

GUI_RectangleFill(220,190,420,230,DGRAY);

GUI_RectangleFill(220,250,420,290,DGRAY);

LCD_PutStringGB24_kt(240,78,"颜色测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,138,"随机测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,198,"汉字测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,258,"图片测试",BLACK,DGRAY);

GUI_RectangleFill(220,190,420,230,CYAN);

LCD_PutStringGB24_kt(240,198,"汉字测试",BLACK,CYAN);

break;

case4:

GUI_RectangleFill(220,70,420,110,DGRAY);

GUI_RectangleFill(220,130,420,170,DGRAY);

GUI_RectangleFill(220,190,420,230,DGRAY);

GUI_RectangleFill(220,250,420,290,DGRAY);

LCD_PutStringGB24_kt(240,78,"颜色测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,138,"随机测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,198,"汉字测试",BLACK,DGRAY);

LCD_PutStringGB24_kt(240,258,"图片测试",BLACK,DGRAY);

GUI_RectangleFill(220,250,420,290,CYAN);

LCD_PutStringGB24_kt(240,258,"图片测试",BLACK,CYAN);

break;

default:

break;

switch(m)

case1:

color_Test();break;

case2:

Rand_Test();break;

case3:

hz_Test();break;

case4:

Pic_Test();break;

default:

break;

五、思考讨论题或体会或对改进实验的建议

本实验主要要处理lcd显示的问题及ZLG-7290的工作原理,首先必须确定lcd的坐标,通过触摸屏中断来确定四个顶点坐标,其他的可以算出【注:

各LCD不太一样】

希望以上资料对你有所帮助,附励志名言3条:

1、生气,就是拿别人的过错来惩罚自己。

原谅别人,就是善待自己。

2、未必钱多乐便多,财多累己招烦恼。

清贫乐道真自在,无牵无挂乐逍遥。

3、处事不必求功,无过便是功。

为人不必感德,无怨便是德。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 材料科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1