基于TFTLCD显示屏的MSP430单片机实验.docx
- 文档编号:7562427
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:28
- 大小:382.06KB
基于TFTLCD显示屏的MSP430单片机实验.docx
《基于TFTLCD显示屏的MSP430单片机实验.docx》由会员分享,可在线阅读,更多相关《基于TFTLCD显示屏的MSP430单片机实验.docx(28页珍藏版)》请在冰豆网上搜索。
基于TFTLCD显示屏的MSP430单片机实验
太空大战小游戏
——基于TFT_LCD显示屏的MSP430单片机实验
SJTUME5120209353
一、实验硬件
1、概述
本次课程设计是在MSP430单片机液晶屏字符显示功能的基础上,编程设计游戏。
程序的设计基于《F6638实验指导手册》中,“TFT-LCD实验--字符显示”的程序点亮TFT-LCD屏幕,编写游戏程序,与IO控制结合,实现游戏的可视化和游戏操作。
由于CodeComposerStudiov5.5.0难以对该程序样例实现编译,采用的开发工具为CodeComposerStudiov6.0。
MSP430系列单片机是由美国TI公司生产的新一代16位单片机,因以其集成密度高、运算速度快、外设接口丰富等优势受到越来越多的产品开发人员的青睐,是当前使用最多的单片机之一。
在很多具体应用中,甚至只利用一片MSP430单片机,就可以完成一个系统的全部功能。
下面给出实验中使用的MSP430F66单片机的封装图和功能框图。
图1-MSP430F6638封装图
图2-MSP430F6638功能框图
2、应用模块
A.LCD模块
本次编写的程序所用的主要模块为LCD模块,在功能框图中显示为LCD_B。
硬件电路设计如下所示。
其中U21(TPS75105DSKR)是LCD屏背光控制芯片,由LCD_BL_EN引脚控制使能端。
图3-MSP430F6638LCD硬件设计电路
PINNO.
FUNCTIONDESCRIPTIONSSYMBOL(模块引脚定义以及各个引脚的功能)
NO.
Symbol
Description
1,2
GND
地
3,4
VCC
电源(2.8-3.4V)
5
NC1
空脚
6
NC2
空脚
7
NC3
空脚
8
RESET
复位
9
A0
LCD寄存器选择段
10
SDA
LCD数据传输线
11
SCK1
LCDCLK时钟线
12
LCD_CS
LCD片选
13
SCK
SD卡CLK时钟线
14
MISO
SD卡主输入,从输出
15
MOSI
SD卡从输入,主输出
16
CS_SD
SD卡片选
17,18
LED+
背光正极
19,20
LED-
背光负极
LCD的全称是LiquidCrystalDisplay,即液晶显示器,因功耗低而备受工程师青睐,大规模应用于电子设备中。
而MSP430单片机中的TFT-LCD则是指薄膜晶体管,Thin-FilmTransistor。
薄膜晶体管液晶显示器(TFT-LCD)具有重量轻、平板化、低功耗、无辐射、显示品质优良等特点,其应用领域正在逐步扩大,已经从音像制品、笔记本电脑等显示器发展到台式计算机、工程工作站(EWS)用监视器。
对液晶显示器的要求也正在向高分辨率、高彩色化发展。
MSP430F6638所采用的TFT-LCD液晶屏的工作参数如下:
X320点TFT透射式点阵液晶显示模块
驱动duty:
1/240Duty
2.4“(COG式)
可视角度:
12时
ILI9328LCD驱动程序或同等能力
逻辑电压:
2.8V
数据接口:
80的系统8/9/16/18bit总线接口
触摸面板
白色背光
B.TM1638
在我们所制作的游戏中有一部分用到了矩阵键盘的一个按键,矩阵键盘隶属于TM1638电路,TM1638是带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU数字接口、数据锁存器、LED高压驱动、键盘扫描等电路。
其对于矩阵键盘的读取如下图所示:
图4-TM1638键盘读取电路
其中A-F分别对应KS1-KS6。
一旦有按键按下,TM1638中相关的寄存器的值就会改变(按键按下时相应字节由0变1)。
二、实验程序
1、程序实现效果
在TFT-LCD屏上进行飞机大战小游戏。
规则如下:
1、击中敌机得一分,敌机触及底线扣除一点生命值,生命值为零时游戏结束。
2、随机出现红黄蓝三种奖励,红色奖励增加攻击范围,蓝色奖励增加移动速度,黄色奖励增加一点生命值。
3、随得分增长游戏难度提升,逐步增加敌机出现频率及移动速度,共15关。
4、按“1”键可施放大招,消灭屏幕上所有敌机,冷却30秒后可再次施放。
2、程序封装模块
1、图形产生与移动
基于示例程序“SPI_LCD_TFT”中所含头文件,利用其中各函数进行绘图。
在绘制各图形时选取其上一点为相对参考点,然后用相对于它的坐标画出整个图形。
需要移动图形时通过参量“sp”控制其移动距离,移动参考点,并在新的位置画出图形,同时将原来位置图形用背景色描一遍以擦除。
在移动我方战机时,程序为先擦除左右两边原来图形,再显示即时位置图形,这样可以防止擦除行为影响到新图形。
如绘制敌机的函数为:
voidDrawenemy(x,y,c)
{
LCD_TFT_FillRectangle(x,y-4,x+2,y-1,c);
LCD_TFT_FillRectangle(x,y+1,x+2,y+4,c);
LCD_TFT_FillRectangle(x+2,y-5,x+6,y+5,c);
LCD_TFT_DrawLine(x+2,y-9,x+2,y+9,c);
LCD_TFT_DrawLine(x+2,y-9,x+6,y-5,c);
LCD_TFT_DrawLine(x+2,y+9,x+6,y+5,c);
LCD_TFT_DrawLine(x+6,y-3,x+9,y,c);
LCD_TFT_DrawLine(x+6,y+3,x+9,y,c);
}
2、我方战机的控制
参考按键消抖示例程序“msp430f6638_Key_debounce”,在按键时将战机参考点分别向左或向右移动sp个单元。
如向左移动主要语句为:
if(Is_sw1_pressed()==1)//iskey1pressed
{//yes
s=s-sp;
}
voidmovebird()
{
Drawbird(s-sp,BLACK);
LCD_TFT_DrawLine(205,s-sp,1,s-sp,BLACK);
Drawbird(s+sp,BLACK);
LCD_TFT_DrawLine(205,s+sp,1,s+sp,BLACK);
Drawbird(s,YELLOW);
}
3、敌机与奖励的产生及移动
两次利用随机数函数rand()。
对于某种颜色的敌机,第一次产生一个0到1000随机数,将其与某数(sp0)比较以决定是否产生该颜色敌机,改变sp0值即可改变敌机出现频率;第二次产生一个14到305的随机数以决定敌机出现的位置参考点y坐标。
奖励的产生同样如此。
敌机和奖励的移动速度可由两个参量改变,即时间间隔sp1及移动距离sp2。
如敌机向下移动的函数为:
voidmoveenemy(i)
{
if(enemy[i]==1)
{
if(ttt[i] { ttt[i]++; } else { t[i]=t[i]+sp2; Drawenemy(t[i]-sp2,r[i],BLACK); if(r[i]<500) { Drawenemy(t[i],r[i],enemycolor[i]); } ttt[i]=1; } } } 4、击落敌机与获得奖励 通过比较敌机与我方战机的相对位置来判断是否击落,击落后将及时位置图形描为背景色,并将各参数重置,由数组enemy[7]来标志某颜色敌机是否存在于画面,若不存在则允许产生。 奖励的获得同上,其中加速效果通过改变sp达到,增加攻击范围效果通过addweapon()函数在画面上呈现,同时通过改变在判断击落时所用的参量range来达到改变攻击范围的效果。 详见程序附页。 5、关卡升级 通过一系列参量数组以及判断是否升级,然后通过增加sp0与sp2的值分别增加敌机出现频率及敌机移动速度完成关卡升级。 以下为关卡升级内容的主要函数,其中各个细节因关系到游戏难度,所以都是由我们多次测试所得到的。 voidlevelup(i) { if(level[i]==0) { sp0=sp0+30; if(i==1||i==3||i==5||i==7||i==9||i==10||i==11||i==12||i==13||i==14) { sp2=sp2+3; buffspeed++; } if(i==12||i==13||i==14) { sp2=sp2+2; } if(i==3||i==7||i==9||i==12||i==13||i==14) { possibuff[2]=possibuff[2]+70; } level[i]=1; } } 6、施放大招 参考关于矩阵键盘的样例程序“MatrixKeyboard_DigitalTube”,利用内置函数判断“1”键是否按下,尔后通过循环语句执行函数kill(i)中部分指令来消灭所有敌机,同时通过drawdazhao()函数在画面上呈现。 尔后借用简单的循环语句完成大招冷却时间倒计时。 详见程序中dazhao()函数。 附页(实验程序代码) #include"Hardware_Profile.h"//处理器"硬件配置文件" #include //产生随机数所需头文件 #include #include //#include //按键消抖所需函数 voiddelay_ms(unsignedintduration); unsignedcharIs_sw1_pressed(void); unsignedcharIs_sw2_pressed(void); voidOsccon_Initial(void);//晶振初始化函数: 配置相关晶振参数 voidDrawbird(x,c); voidmovebird(); voidDrawenemy(x,y,c); voidDrawbuff(x,y,c); voidproduceenemy(i); voidproducebuff(i); voidmoveenemy(i); voidmovebuff(i); voidkill(i); voidgetbuff(i); voidaddweapon(); voidlevelup(i); voidlevup(); voidprintlife(); voidprintscore(); voidprintlevel(); //#include"TM1638.c" voiddazhao(); voiddrawdazhao(); voidinit_port(void); ints=160; intr[10]={10,10,10,10,10,10,10,10}; intpossible=0; intenemy[7]={0,0,0,0,0}; intbuff[3]={0,0,0}; inty=0; intt[10]={1,1,1,1,1,1,1,1}; intsp0=35; intsp1=3; intsp2=5; intsp=5; intbuffspeed=4; intttt[10]={1,1,1,1,1,1,1,1}; intscore=0; intlife=5; intrange=8; intenemycolor[7]={RED,BLUE,WHITE,GRAY,OLIVE,BROWN,MAGENTA}; intbuffcolor[3]={RED,BLUE,YELLOW}; intweapon=1; intlevel[15]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; intlev=0; intpossibuff[3]={18,21,70}; intupscore[15]={10,20,50,80,130,180,250,350,500,700,900,1100,1300,1500}; intdazhaot=0; intdazhaohao=1; u8*printlev[10]={"0","1","2","3","4","5","6","7","8","9"}; intmain(void) { mClose_WDT;//关闭看门狗 mDisable_GIE;//关闭中断 Osccon_Initial();//晶振初始化函数: 定义相关晶振参数 mEnable_GIE;//开启总中断//good放在初始化最后面//enableinterrupt Init_LCD_TFT_ILI9325();//"彩屏LCD_TFT_ILI9325"初使化: 所有相关资源的初始化 volatileunsignedinti;//按键消抖初始化 volatileunsignedintcount=0; WDTCTL=WDTPW+WDTHOLD;//StopWDT init_port(); init_TM1638();//dazhao LCD_TFT_Clear(BLACK); while (1) { levup(y); levelup(lev); if(life<=0) { LCD_TFT_ShowString(110,125,"GAMEOVER",FONT1608,BLACK,RED); } printlife(); printscore(); printlevel(); intm; for(m=0;m<=6;m++) { produceenemy(m); } for(m=0;m<=2;m++) { producebuff(m); } addweapon(); movebird(); for(m=0;m<=6;m++) { moveenemy(m); kill(m); } for(m=0;m<=2;m++) { movebuff(m); getbuff(m); } dazhao(); if(Is_sw1_pressed()==1)//iskey1pressed {//yes s=s-sp; } else if(Is_sw2_pressed()==1)//iskey2pressed {//yes s=s+sp; } P4DIR&=~(BIT2+BIT3);//settingIOforinput } } voidproduceenemy(i) { if(enemy[i]==0)//enemy1 { r[i]=600; possible=rand()%1000; if(possible { r[i]=rand()%320; if(r[i]<305&&r[i]>14) { Drawenemy(t[i],r[i],enemycolor[i]); enemy[i]=1; } else { r[i]=600; } } } } voidproducebuff(i) { if(buff[i]==0)//enemy1 { r[i+7]=600; possible=rand()%2000; if(possible<=possibuff[i]) { r[i+7]=rand()%320; if(r[i+7]<305&&r[i+7]>14) { Drawbuff(t[i+7],r[i+7],buffcolor[i]); buff[i]=1; } else { r[i+7]=600; } } } } voidmoveenemy(i) { if(enemy[i]==1) { if(ttt[i] { ttt[i]++; } else { t[i]=t[i]+sp2; Drawenemy(t[i]-sp2,r[i],BLACK); if(r[i]<500) { Drawenemy(t[i],r[i],enemycolor[i]); } ttt[i]=1; } } } voidmovebuff(i) { if(buff[i]==1) { if(ttt[i+7]<1) { ttt[i+7]++; } else { t[i+7]=t[i+7]+buffspeed; Drawbuff(t[i+7]-buffspeed,r[i+7],BLACK); if(r[i+7]<500) { Drawbuff(t[i+7],r[i+7],buffcolor[i]); } ttt[i+7]=1; } } } voidkill(i) { if(enemy[i]==1) { if((r[i]-range)<=s&&s<=(r[i]+range)&&t[i]<=190) { Drawenemy(t[i],r[i],BLACK); score++; r[i]=600; enemy[i]=0; t[i]=0; } if(t[i]>230) { Drawenemy(t[i],r[i],BLACK); if(life>0) { life--; } r[i]=600; enemy[i]=0; t[i]=0; } } } voidgetbuff(i) { if((r[i+7]-8)<=s&&s<=(r[i+7]+8)&&t[i+7]>=200) { Drawbuff(t[i+7],r[i+7],BLACK); r[i+7]=600; buff[i]=0; t[i+7]=0; if(i==2) { if(life<=99) { life++; } } if(i==1) { if(sp<=120) { sp++; } } if(i==0) { if(weapon<=6) { weapon++; range=range+4; if(weapon==6) { range=range+4; } } } } if(t[i+7]>230) { Drawbuff(t[i+7],r[i+7],BLACK); r[i+7]=600; buff[i]=0; t[i+7]=0; } } voidlevup() { if(lev<14) { if(score>=upscore[y]) { y++; lev++; } } } voidlevelup(i) { if(level[i]==0) { sp0=sp0+30; if(i==1||i==3||i==5||i==7||i==9||i==10||i==11||i==12||i==13||i==14) { sp2=sp2+3; buffspeed++; } if(i==12||i==13||i==14) { sp2=sp2+2; } if(i==3||i==7||i==9||i==12||i==13||i==14) { possibuff[2]=possibuff[2]+70; } level[i]=1; } } voidprintlife() { //LCD_TFT_ShowString(170,260,"Life: ",FONT1608,WHITE,BLACK); inta,b; a=life/10; b=life%10; LCD_TFT_ShowString(200,300,printlev[a],FONT1608,WHITE,BLACK); LCD_TFT_ShowString(200,310,printlev[b],FONT1608,WHITE,BLACK); } voidprintscore() { inta,b,c,d; a=score/1000; b=(score-a*1000)/100; c=(score-a*1000-b*100)/10; d=score%10; LCD_TFT_ShowString(220,280,printlev[a],FONT1608,WHITE,BLACK); LCD_TFT_ShowString(220,290,printlev[b],FONT1608,WHITE,BLACK); LCD_TFT_ShowString(220,300,printlev[c],FONT1608,WHITE,BLACK); LCD_TFT_ShowString(220,310,printlev[d],FONT1608,WHITE,BLACK); } voidprintlevel() { inta,b; a=(lev+1)/10; b=(lev+1)%10; LCD_TFT_ShowString(190,2,"LEVEL: ",FONT1608,WHITE,BLACK); LCD_TFT_ShowString(190,50,printlev[a],FONT1608,WHITE,BLACK); LCD_TFT_ShowString(190,60,printlev[b],FONT1608,WHITE,BLACK); } // voiddelay_ms(unsignedintduration) { unsignedinti; for(i=0;i<5000*duration;i++){}; } unsignedcharIs_sw1_pressed(void) { if((P4IN&0x
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 TFTLCD 显示屏 MSP430 单片机 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)