嵌入式系统实验报告

嵌入式系统

实验报告

姓名:   ##

学号:    ##             

班级:计算机科学与技术非师范121班

实验一  LCD控制

一、实验目的

1、初步掌握液晶显示屏的使用及其电路设计方法。

2、掌握S3C44B0X处理器的LCD控制器的使用。

3、通过实验掌握液晶显示文本和图形的方法以及程序设计方法。

二、实验内容

学习LCD显示器的基本原理,理解其驱动的控制方法。掌握S3C44B0X处理器的基本原理和方法,并编程实现:

1、画出多个矩形框

2、显示ASCII字符

3、显示汉字字符

三、实验流程图

嵌入式系统实验报告

四、实验核心代码

#include "44b.h"

#include"uhal.h"

#include "option.h"

#include"def.h"

#pragma import(__use_no_semihosting_swi)  // ensure no functions that use semihosting

extern U32 LCDBuffer[240][320];

int main(void)

{

int i,j,k;

U32 jcolor;

    ARMTargetInit();  //开发版初始化

    LCD_Init();             //LCD初始化

        for (k=10;k<200;k++)

          LCDBuffer[k][10]=0x000000e0;

        for (k=10;k<200;k++)

          LCDBuffer[k][100]=0x000000e0;

        for (j=10;j<100;j++)

          LCDBuffer[10][j]=0x000000e0;

        for (j=10;j<100;j++)

          LCDBuffer[200][j]=0x000000e0;

    LCD_Refresh() ;    

    while(1);

    return 0;

}

实验二  键盘控制实验

一、实验目的

1、学习键盘及LED驱动原理。

2、掌握ZLG7289芯片的使用方法。

二、实验内容

通过ZLG7289芯片驱动17键的键盘和8个共阴极LED,将按键值在LED上面显示出来。

三、实验流程图

 1、定义ZLG7289 寄存器(zlg7289.h)

嵌入式系统实验报告  

2、定义键值读取函数

嵌入式系统实验报告                                  

    3、编写主函数,将键值在数码管上显示

嵌入式系统实验报告

四、实验核心代码:

#include"uhal.h"

#include"keyboard.h"

#include"zlg7289.h"

#include"44b.h"

#include"myuart.h"

#include"LCD320.h"

#pragma import(__use_no_semihosting_swi) 

extern int Zlg7289SIOBand;

extern int Zlg7289SIOCtrl;

int main(void)

{

      U32 key;

      ARMTargetInit();  //开发版初始化

      Uart_Printf("\nArm Target Init OK.");

      Zlg7289_Reset();//zlg7289复位

      ARMTargetInit();  //开发版初始化

      LCD_Init();

      LCD_ChangeMode(DspTxtMode);//转换LCD显示模式为文本显示模式

      LCD_Cls();//文本模式下清屏命令

      while(1)

      {     key=GetKey();//得到按键值

            Delay(7000);

            switch(key)

            {

                  case(0):

                  LCD_printf("NUM\n ");

                  Uart_Printf("\nNUM\n");

                  break;

                  case(1):

                  LCD_printf("/\n ");

                  Uart_Printf("\n1\n");

                  break;

                  case(2):

                  LCD_printf("*\n ");

                  Uart_Printf("\n2\n");

                  break;

                  case(3):

                  LCD_printf("-\n ");

                  Uart_Printf("\n3\n");break;

                  case(4):

                  LCD_printf("7\n ");

                  Uart_Printf("\n4\n");break;

                  case(5):

                  LCD_printf("8\n ");

                  Uart_Printf("\n5\n");break;

                  case(6):

                  LCD_printf("9\n ");

                  Uart_Printf("\n6\n");break;

                  case(7):

                  LCD_printf("+\n ");

                  Uart_Printf("\n7\n");break;

                  case(8):

                  LCD_printf("4\n ");

                  Uart_Printf("\n8\n");break;

                  case(9):

                  LCD_printf("5\n ");

                  Uart_Printf("\n9\n");break;

                  case(10):

                  LCD_printf("6\n ");

                  Uart_Printf("\nNUM LOCK\n");break;

                  case(11):

                  LCD_printf("1\n ");

                  Uart_Printf("\n/\n");break;

                  case(12):

                  LCD_printf("2\n ");

                  Uart_Printf("\n*\n");break;

                  case(13):

                  LCD_printf("3\n ");

                  Uart_Printf("\n-\n");break;

                  case(14):

                  LCD_printf("Enter\n");

                  Uart_Printf("\nEnter\n");break;

                  case(15):

                  LCD_printf("0\n ");

                  Uart_Printf("\n+\n");break;

                  case(16):

                  LCD_printf("Dle\n ");

                  Uart_Printf("\nDle\n");break;

            }

            ZLG7289_ENABLE();//使zlg7289占有同步串口

            Delay(5);//延时

        WriteSDIO(ZLG7289_CMD_DATA0|0);//数码管以方式0译码,第一个

数码管亮

            //WriteSDIO(key);//显示个位

            Delay(1);//延时*/

            if(key>=4&&key<16)

           

            {

                  switch(key)

                  {

                        case(4):

                        WriteSDIO(7);

                        Delay(1);

                        break;

                        case(5):

                        WriteSDIO(8);

                        Delay(1);

                        break;

                        case(6):

                        WriteSDIO(9);

                        Delay(1);

                        break;

                        case(8):

                        WriteSDIO(4);

                        Delay(1);

                        break;

                        case(9):

                        WriteSDIO(5);

                        Delay(1);

                        break;

                        case(10):

                        WriteSDIO(6);

                        Delay(1);

                        break;

                        case(11):

                        WriteSDIO(1);

                        Delay(1);

                        break;

                        case(12):

                        WriteSDIO(2);

                        Delay(1);

                        break;

                        case(13):

                        WriteSDIO(3);

                        Delay(1);

                        break;

                        case(15):

                        WriteSDIO(0);

                        Delay(1);

                        break;     

                  }

            }

            ZLG7289_DISABLE();//zlg7289放弃同步串口控制权

      }

      return 0;

}

五、实验体会

在本次实验,熟悉了键盘以及LED的驱动原理。键盘的闭合键,通常采用两种方法,即行扫描法和行反转法获取键值。同时还了解了ZLG7289芯片的特点和基本使用方法。

实验三  A/D接口实验

一、实验目的

1、  熟悉ARM本身自带的八路十位A/D控制器及相应寄存器。

2、  编程实现ARM系统的A/D功能,掌握带有A/D的CPU编程实现A/D功能的主要方法。

二、实验内容

学习A/D和LCD接口原理,了解实现A/D和LCD系统对于系统的软件和硬件要求。阅读ARM芯片文档,掌握ARM的A/D和LCD相关寄存器的功能,熟悉ARM系统硬件的A/D和LCD相关接口。利用外部模拟信号编程实现ARM循环采集全部前4路通道,并且在LCD上动态显示曲线。每个通道以不同颜色的画笔绘制曲线。

三、实验流程图

1、获取转换结果函数

              嵌入式系统实验报告   

四、实验核心代码

#include "44b.h"

#include"uhal.h"

#include "option.h"

#include"def.h"

#include"myuart.h"

#include"LCD320.h"

extern U32 LCDBuffer[240][320];

#pragma import(__use_no_semihosting_swi)

#define ADCCON_FLAG           0x40

#define ADCCON_SLEEP          0x20

#define ADCCON_ADIN0          (0x0<<2)

#define ADCCON_ADIN1          (0x1<<2)

#define ADCCON_ADIN2          (0x2<<2)

#define ADCCON_ADIN3          (0x3<<2)

#define ADCCON_ADIN4          (0x4<<2)

#define ADCCON_ADIN5          (0x5<<2)

#define ADCCON_ADIN6          (0x6<<2)

#define ADCCON_ADIN7          (0x7<<2)

#define ADCCON_READ_START     0x2

#define ADCCON_ENABLE_START   0x1

void init_ADdevice()

{//初始化

      rADCPSR=20;

      rADCCON=ADCCON_SLEEP;

}

int GetADresult(int channel)

{

      rADCCON=(channel<<2)|ADCCON_ENABLE_START;

      Delay(10);

      while(!(rADCCON&ADCCON_FLAG));//转换结束

      return rADCDAT;//返回采样值

}

int main(void)

{

U32 jcolor;

U32 jcolor1;

U32 jcolor2;

U32 jcolor3;

      int mid;

      int fs;

      int i,j,k,s,t;

      int pre[4];

      float d;

      ARMTargetInit();  //开发版初始化

      init_ADdevice();

      Uart_Printf("\n");

      LCD_Init();

         jcolor  = 0x0000e0e0;

         jcolor1 = 0x000000e0;

         jcolor2 = 0x00e0e0e0;

         jcolor3 = 0x0000e000;

         t = 320;

   while(1)

      {

if(t == 320)

            {//采样0~3路A/D值

                  t = 0;

                  for(k=0;k<240;k++)

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

                   LCDBuffer[k][j]=0x00000000;//背景黑色

            }

            for(i=0;i<1;i++)

            {

                  d=GetADresult(i)*2.5/1023;

                  s=(int)(d*15);

                  fs=55*(i+1)-s;

                   LCDBuffer[fs][t]=jcolor;//线条颜色

              if(t!=0)

              {

                  mid=(pre[i]+fs)/2;

                  for(k=pre[i];k

                  LCDBuffer[k][t-1]=jcolor;

                  for(k=mid;k

                  LCDBuffer[k][t]=jcolor;

                  for(k=mid;k

                  LCDBuffer[k][t-1]=jcolor;

                  for(k=fs;k

                  LCDBuffer[k][t]=jcolor;

              }

              pre[i]=fs;

             }     

            for(i=1;i<2;i++)

            {

                   d=GetADresult(i)*2.5/1023;

                   s=(int)(d*15);

                    fs=55*(i+1)-s;

                    LCDBuffer[fs][t]=jcolor1;//线条颜色

                    if(t!=0)

              {

                    mid=(pre[i]+fs)/2;

                    for(k=pre[i];k

                    LCDBuffer[k][t-1]=jcolor1;

                    for(k=mid;k

                    LCDBuffer[k][t]=jcolor1;

                    for(k=mid;k

                    LCDBuffer[k][t-1]=jcolor1;

                    for(k=fs;k

                    LCDBuffer[k][t]=jcolor1;

              }

              pre[i]=fs;

             } 

             for(i=2;i<3;i++)

            {

                    d=GetADresult(i)*2.5/1023;

                    s=(int)(d*15);

                    fs=55*(i+1)-s;

                    LCDBuffer[fs][t]=jcolor2;//线条颜色

                    if(t!=0)

              {

                   mid=(pre[i]+fs)/2;

                   for(k=pre[i];k

                   LCDBuffer[k][t-1]=jcolor2;

                   for(k=mid;k

                   LCDBuffer[k][t]=jcolor2;

                   for(k=mid;k

                   LCDBuffer[k][t-1]=jcolor2;

                   for(k=fs;k

                   LCDBuffer[k][t]=jcolor2;

              }

              pre[i]=fs;

             } 

             for(i=3;i<4;i++)

            {

                  d=GetADresult(i)*2.5/1023;

                  s=(int)(d*15);

                  fs=55*(i+1)-s;

                  LCDBuffer[fs][t]=jcolor3;//线条颜色

                  if(t!=0)

              {

                  mid=(pre[i]+fs)/2;

                 for(k=pre[i];k

                  LCDBuffer[k][t-1]=jcolor3;

                  for(k=mid;k

                  LCDBuffer[k][t]=jcolor3;

                  for(k=mid;k

                  LCDBuffer[k][t-1]=jcolor3;

                  for(k=fs;k

                  LCDBuffer[k][t]=jcolor3;

              }

              pre[i]=fs;

             } 

LCD_Refresh();

              t++;

              Uart_Printf("\r");         

      }

      return 0;

}

实验四  触摸屏驱动实验

一、实验目的

1、了解触摸屏基本概念及原理。

2、理解触摸屏与LCD的密切配合。

3、编程实现对触摸屏的控制。

二、实验内容

结合液晶显示控制实验,编写程序获取用户输入的4个坐标位置,并在液晶上画出由用户输入的坐标组成的矩形。

三、实验流程图

1、读取触摸点x轴电压值

2、读取触摸点坐标                    3、判断触摸动作

四、实验核心代码

#include "44b.h"

#include "LCD320.h"

#include "tchScr.h"

#include "maro.h"

#define ADS7843_CMD_X (ADS7843_CTRL_START|ADS7843_GET_X|ADS7843_CTRL_12MODE|ADS7843_CTRL_DFR|ADS7843_CTRL_ENPWD)

//采样x轴电压值,数据为12位,参考电压输入模式为差分模式,允许省电模式

#define ADS7843_CMD_Y (ADS7843_CTRL_START|ADS7843_GET_Y|ADS7843_CTRL_12MODE|ADS7843_CTRL_DFR|ADS7843_CTRL_ENPWD)

 extern U32 LCDBuffer[240][320]; 

IntT chScr_Xmax=1876,TchScr_Xmin=269,TchScr_Ymax=229,

TchScr_Ymin=1725;//触摸屏返回电压值范围

void TchScr_GetScrXY(int *x, int *y, U8 bCal)

{//获得触摸点坐标

      unsigned int temp;

      rPDATF&=~ADS7843_PIN_CS;//打开ADS7843

      SendSIOData(ADS7843_CMD_X);//发送读取x电压值控制字

      SendSIOData(0);//等待8个时钟节拍,因为完成一转换需要16个时钟

      temp=ReadSIOData();//读取采样值高8位

      SendSIOData(ADS7843_CMD_X);

      temp<<=8;

      temp|=ReadSIOData();//读取低8位并与以前高8位组成16位数据

      *x=(temp>>4);//去掉低4位,保留12位有效数据

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_X);

      temp<<=8;

      temp|=ReadSIOData();

      *x+=(temp>>4);

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_X);

      temp<<=8;

      temp|=ReadSIOData();

      *x+=(temp>>4);

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_Y);

      temp<<=8;

      temp|=ReadSIOData();

      *x+=(temp>>4);

      *x>>=2;           //采样4次取平均值

      //读取y电压值

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_Y);

      temp<<=8;

      temp|=ReadSIOData();

      *y=(temp>>4);

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_Y);

      temp<<=8;

      temp|=ReadSIOData();

      *y+=(temp>>4);

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(ADS7843_CMD_Y);

      temp<<=8;

      temp|=ReadSIOData();

      *y+=(temp>>4);

      SendSIOData(0);

      temp=ReadSIOData();

      SendSIOData(0);

      temp<<=8;

      temp|=ReadSIOData();

      *y+=(temp>>4);

      *y>>=2;          

      rPDATF|=ADS7843_PIN_CS;//关闭ADS7843

      if(bCal){//对采样结果进行转换

            *x=(*x-TchScr_Xmin)*LCDWIDTH/(TchScr_Xmax-TchScr_Xmin);

            *y=(*y-TchScr_Ymin)*LCDHEIGHT/(TchScr_Ymax-TchScr_Ymin);

      }

}

U32 TchScr_GetOSXY(int *x, int *y)

{//获得触摸点坐标并返回触摸动作

      static U32 mode=0;

      static int oldx,oldy;

      int i,j;

      for(;;){

      if((mode!=TCHSCR_ACTION_DOWN) && (mode!=TCHSCR_ACTION_MOVE)){

                  if(!TCHSCR_IsPenNotDown){//有触摸动作

                        TchScr_GetScrXY(x, y,TRUE);//得到触摸点坐标

                        for(i=0;i<40;i++){

                              if(TCHSCR_IsPenNotDown)//抬起

                                    break;

                              Delay(100);

                        }

if(i<40){//在规定的双击时间之内抬起,检测是不是及时按下

                              for(i=0;i<60;i++){

                                    if(!TCHSCR_IsPenNotDown){

                        if (i<10) {i=60;break;}//如果单击后很短时间内按下,不视为双击

                                    mode=TCHSCR_ACTION_DBCLICK;

                                    for(j=0;j<40;j++) Delay(100);//检测到双击后延时,防止拖尾

                                    break;

                                    }

                    Delay(100);

                              }

                              if(i==60)         //没有在规定的时间内按下

                                    mode=TCHSCR_ACTION_CLICK;

                        }

                        else{ //没有在规定的时间内抬起

                              mode=TCHSCR_ACTION_DOWN;

                        }

              break;

                  }

            }

            else{

                  if(TCHSCR_IsPenNotDown){      //抬起

                        mode=TCHSCR_ACTION_UP;

                        *x=oldx;

                        *y=oldy;

                        return mode;

                  }

                  else{

                        TchScr_GetScrXY(x, y,TRUE);

                        if(ABS(oldx-*x)>4 ||ABS( oldy-*y)>4){//有移动动作

                              mode=TCHSCR_ACTION_MOVE;

                              break;

                        }

                  }

            }

            Delay(50);

      }

      oldx=*x;

      oldy=*y;

      return mode;

}

void print_line(int x1,int y1,int x2,int y2)

{

      int i,j,k;

      double k1;

      k1=(y2-y1)*1.0/(x2-x1);

      Uart_Printf("x1=%d,y1=%d,x2=%d,y2=%d %lf\n",x1,y1,x2,y2,k1);

      for(i=x1;i<=x2;i++)

      {

            j=k1*(i-x1)+y1+0.5;

            Uart_Printf("i=%d,j=%d\n",i,j);

            LCDBuffer[i][j]=0x0000e000;

      }

      for(i=x1;i>=x2;i--)

      {

            j=k1*(i-x1)+y1+0.5;

            Uart_Printf("i=%d,j=%d\n",i,j);

            LCDBuffer[i][j]=0x0000e000;

      }

      for(i=y1;i<=y2;i++)

      {

            j=1.0/k1*(i-y1)+x1+0.5;

            Uart_Printf("i=%d,j=%d\n",i,j);

            LCDBuffer[j][i]=0x0000e000;

      }

      for(i=y1;i>=y2;i--)

      {

            j=1.0/k1*(i-y1)+x1+0.5;

            Uart_Printf("i=%d,j=%d\n",i,j);

            LCDBuffer[j][i]=0x0000e000;

      }

}

void TchScr_Test()

{

      U32 mode;

      int x,y;

      int i,j;

      int a[4],b[4];

      LCD_Init();

      Uart_Printf("\nplease touch the screen\n");

      for(i=0;i<4;i++){

            mode=TchScr_GetOSXY(&x, &y);

            switch(mode){

            case TCHSCR_ACTION_CLICK:

                  Uart_Printf("Action=click:x=%d,\ty=%d\n",x,y);

                  a[i]=x;b[i]=y;

                  Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

                  break;

            case TCHSCR_ACTION_DBCLICK:

                  Uart_Printf("Action=double click:x=%d,\ty=%d\n",x,y);

                  a[i]=x;b[i]=y;

                  Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

                  break;

            case TCHSCR_ACTION_DOWN:

                  Uart_Printf("Action=down:x=%d,\ty=%d\n",x,y);

                  a[i]=x; b[i]=y;

                  Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

                  break;

            case TCHSCR_ACTION_UP:

                  Uart_Printf("Action=up:x=%d,\ty=%d\n",x,y);

                  a[i]=x; b[i]=y;

                  Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

                  break;

            case TCHSCR_ACTION_MOVE:

                  Uart_Printf("Action=move:x=%d,\ty=%d\n",x,y);

                  a[i]=x; b[i]=y;

                  Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

                  break;

            }

            Delay(1000);

      }

      for(i=0;i<4;i++)

      {

            print_line(a[i],b[i],a[(i+1)%4],b[(i+1)%4]);

            LCD_Refresh() ;

            Uart_Printf("x=%d,y=%d\n",a[i],b[i]);

      }

}

五、实验体会

本次实验,解释了触摸屏基本概念及原理,触摸屏与LCD的配合。同时也使我们学会了对触摸屏的控制。

实验五  uCOS-II在ARM微处理器上的移植及编译

一、实验目的

1、了解uCOS-II内核的主要结构。

2、掌握将uCOS-II内核移植到ARM7处理器上的基本方法。

二、实验内容

1、将uCOS-II内核移植到ARM7处理器上。

2、编写两个简单任务,在超级终端上观察两个任务的切换。

三、实验流程图

 

四、实验核心代码

#include"..\ucos-ii\includes.h"               /* uC/OS interface */

#include

#include"uhal.h"

#include"LCD320.h"

#pragma import(__use_no_semihosting_swi)  // ensure no functions that use semihosting

///******************任务定义***************///

OS_STK SYS_Task_Stack[STACKSIZE]= {0, }; //system task刷新任务堆栈

#define SYS_Task_Prio                     1

void SYS_Task(void *Id);

OS_STK Task1_Stack[STACKSIZE]={0, };

void Task1(void *Id);

#define Task1_Prio     14

OS_STK Task2_Stack[STACKSIZE]= {0, };

void Task2(void *Id);

#define  Task2_Prio       13

OS_STK Task3_Stack[STACKSIZE]= {0, };

void Task3(void *Id);

#define  Task3_Prio       12

int main(void)

{

      ARMTargetInit();

      LCD_Init() ;

      LCD_ChangeMode(DspTxtMode);

      LCD_Cls();       // do target (uHAL based ARM system) initialisation //

      OSInit(); 

      OSTaskCreate(SYS_Task,  (void *)0,  (OS_STK *)&SYS_Task_Stack[STACKSIZE-1],  SYS_Task_Prio);

      OSTaskCreate(Task3,  (void *)0,  (OS_STK *)&Task3_Stack[STACKSIZE-1],  Task3_Prio);

      OSTaskCreate(Task2,  (void *)0,  (OS_STK *)&Task2_Stack[STACKSIZE-1],  Task2_Prio);

      OSTaskCreate(Task1,  (void *)0,  (OS_STK *)&Task1_Stack[STACKSIZE-1],  Task1_Prio);

      OSStart();              // start the game //

      // never reached //

      return 0;

}//main

void Task1(void *Id)    

{

       for(;;){

       OSTimeDly(1000);

       LCD_printf("run task1\n");

       Uart_Printf("run task1\n");

       OSTimeDly(1000);

      }

}

void Task2(void *Id)

{

      for (;;)

      {

            LCD_printf("run task2\n");

            Uart_Printf("run task2\n");

            OSTimeDly(1000);

      }

}

void Task3(void *Id)    

{

      for(;;){

                  LCD_printf("run task3\n");

                  Uart_Printf("run task3\n");

                  OSTimeDly(1000);

      }

}

void SYS_Task(void *Id)

{     OSRunning=TRUE;          //使能多任务切换

      uHALr_InstallSystemTimer();

      LCD_printf("start system task.\n");

      Uart_Printf("start system task.\n");

      for (;;)

      {

            OSTimeDly(10000);

      }

}

五、实验体会

通过本次实验,了解uCOS-II内核的主要结构,掌握了将uCOS-II内核移植到ARM7处理器上的基本方法。掌握了在ARM SDT2.5或ADS1.2集成开发环境中编写和调试程序的基本过程。通过此次实验,让我复习了嵌入式ARM系统软、硬件的基本知识,分析了uC/OS-II的源代码,对移植相关部分的代码作了分析解读,熟悉了ARM体系架构,最后基于ARM微处理器作了uC/OS-II的具体移植工作。不管是移植还是自己设计的,我想最终的目的是解决这个问题,这首先要有个好的学习态度,通过它让我自己认识到自己的不足和弱项,多分析做些实验验证,对于问题解决是帮助的。

实验六 捉小鸡

一、实验目的

学习设计一个复杂应用程序的结构并编译完成它,结合应用之前实验学到的知识,编写一个功能比较复杂的综合应用程序。

二、实验内容

      小游戏:捉小鸡。

一只小鸡不停地随机出现在9个格子的任意一个,在小鸡停留在某一格子的时间段内,游戏者如果能正确按相应的键,就算游戏者抓住一只小鸡。游戏总共20只小鸡,每抓住一只得5分,20只小鸡全部出现后游戏结束。

界面中左边是9个格子,一只小鸡不停地随机出现在9个格子的任意一个,假如目前小鸡正出现在第5个格子。如果游戏者能赶在小鸡出现在另一个格子前按下“5”键,就算游戏者抓住一只小鸡,如果游戏者没有按下正确的键,则没有抓住小鸡。

界面的右边显示游戏的一些相关信息。“共有”栏显示游戏中到目前为止已经出现的小鸡总数。“抓住”栏显示本级游戏中到目前为止游戏者已经抓住小鸡的数目。“得分”栏显示游戏进行到现在,游戏者所有得分的累积。

三、实验流程图

嵌入式系统实验报告

四、实验核心代码

#include"..\ucos-ii\includes.h"               /* uC/OS interface */

#include "..\ucos-ii\add\osaddition.h"

#include

#include

#include

#include"tchScr.h"

#pragma import(__use_no_semihosting_swi)  // ensure no functions that use semihosting

//记录9个格子的位置

structRECT Rect[9];

structRECT *pRect[9];

//记录一些相关位置,StepRect位置显示游戏等级,CountRect位置显示总共出现的小鸡的数目

//CatchRect位置显示抓到的小鸡的数目,ScoreRect位置显示当前的分数

u8 StepRectX,StepRectY,TotalCountRectX,TotalCountRectY;

u8 CatchCountRectX,CatchCountRectY,ScoreRectX,ScoreRectY;

u8 Step;         //游戏等级

u8 TotalCount;   //总共出现的小鸡的数目

u8 CatchCount;   //抓到的小鸡的数目

u8 Score;        //游戏当前的分数

u8 CurrentPos;   //小鸡当前正在哪一个格子中

BOOLEAN gameover,pause;

BOOLEAN gamepass;

BOOLEAN initfinished;//记录初始化是否完成,用于协调多个任务,确保其它任务在主任务初始化结束后再开始工作

PDC pdc;//绘图用的DC

char bmp_hitchick[12]={'1','4','5','_','8','0',' ',' ','B','M','P',0}; //击中小鸡的图片

char bmp_misschick[12]={'1','4','5','_','8','1',' ',' ','B','M','P',0}; //没有击中小鸡的图片

char bmp_gameend[12]={'1','4','5','_','9','0',' ',' ','B','M','P',0}; //游戏通关的图片

char bmp_logo[12]={'1','4','5','_','5','9',' ',' ','B','M','P',0}; //登录图片

char bmp_gamepass[12]={'1','4','5','_','7','0',' ',' ','B','M','P',0}; //游戏过关图片

char bmp_gameover[12]={'1','4','5','_','7','1',' ',' ','B','M','P',0}; //游戏结束图片

char bmp_frame[12]={'1','2','7','_','3','9',' ',' ','B','M','P',0};

char bmp_chick[12]={'1','2','7','_','3','5',' ',' ','B','M','P',0};

char bmp_gamepause[12]={'1','2','7','_','3','7',' ',' ','B','M','P',0};

char bmp_empty[12]={'1','2','7','_','4','0',' ',' ','B','M','P',0};

///******************任务定义***************///

OS_STK Main_Stack[STACKSIZE*8]={0, };   //Main_Task堆栈

void Main_Task(void *Id);               //Main_Task,主要对一些变量进行初始化

#define Main_Task_Prio     12           //Main_Task的优先级

OS_STK Led_Flash_Stack[STACKSIZE]= {0, }; //LED闪烁任务堆栈

void Led_Flash_Task(void *Id);            //LED闪烁任务

#define Led_Flash_Prio           60       //LED闪烁任务的优先级

OS_STK Display_Task_Stack[STACKSIZE*8]={0, };   //Display_Task堆栈

void Display_Task(void *Id);                   //Display_Task,主要实时更新LCD屏幕的显示

#define Display_Task_Prio     20               //Display_Task任务的优先级

/**************已经定义的OS任务*************

#define SYS_Task_Prio                     1

#define Touch_Screen_Task_Prio            9

#define Main_Task_Prio     12

#define Key_Scan_Task_Prio      58

#define Lcd_Fresh_prio           59

#define Led_Flash_Prio           60

void Led_Flash_Task(void *Id)//指示RTOS处于正常工作中

{

     代码略

}

void initOSGUI()  //初始化操作系统的图形界面

{代码略

}

int main()

{

      ARMTargetInit();        // do target (uHAL based ARM system) initialisation //

      OSInit();               // needed by uC/OS-II //

      uHALr_ResetMMU();

      LCD_Init();             //初始化LCD模块

      LCD_printf("LCD initialization is OK\n");

      LCD_printf("240 x 128  Text Mode\n");

      TchScr_init();

      initOSGUI();

      LoadFont(); //加载字体

      LoadConfigSys();//加载配置文件

      LCD_printf("Create task on uCOS-II...\n");

      OSTaskCreate(Main_Task,  (void *)0,  (OS_STK *)&Main_Stack[STACKSIZE*8-1],  Main_Task_Prio);

      OSTaskCreate(Led_Flash_Task,  (void *)0,  (OS_STK *)&Led_Flash_Stack[STACKSIZE-1],  Led_Flash_Prio  );

      OSTaskCreate(Display_Task,(void *)0,  (OS_STK *)&Display_Task_Stack[STACKSIZE-1],  Display_Task_Prio);

      OSAddTask_Init();//创建一些缺省任务,包括键盘任务、触摸屏任务等

      LCD_printf("Starting uCOS-II...\n");

      LCD_printf("Entering graph mode...\n");

      LCD_ChangeMode(DspGraMode);

      InitRtc();

      Nand_Rw_Sem=OSSemCreate(1);   //创建Nand-Flash读写控制权旗语,初值为1满足互斥条件//

      OSStart();              // start the game //

      return 0;

}//main

void PauseGame()

{

    if(gameover == FALSE)

      {

            pause = !(pause);

            {

                  ShowBmp(pdc,bmp_frame, 0, 0);

            }

      }

}

void StartNextGame()

{

      if (Step == 5)

      {

            ShowBmp(pdc,bmp_gameend, 41, 95);//显示游戏通关图片

            gameover = TRUE;

            gamepass = FALSE;

            Step = 1;

      }

      else

      {

            gameover = FALSE;

            pause = FALSE;

      gamepass = FALSE;

      Step++;

      TotalCount = 0;

      CatchCount = 0;

      CurrentPos = 100;

            ShowBmp(pdc,bmp_frame, 0, 0);

      }

}

void onKey(int x, int y)

{//划分屏幕区域

    int nkey;

    if(x>=19&x<=66)

    {

       if(y>=28&y<=81)

       nkey=0;

       if(y>=95&y<=148)

       nkey=4;

       if(y>=159&y<=212)

       nkey=8;   

    }

    if(x>=85&x<=132)

    {

       if(y>=28&y<=81)

       nkey=1;

       if(y>=95&y<=148)

       nkey=5;

       if(y>=159&y<=212)

       nkey=9;   

    }

    if(x>=152&x<=199)

    {

       if(y>=28&y<=81)

       nkey=2;

       if(y>=95&y<=148)

       nkey=6;

       if(y>=159&y<=212)

       nkey=10;   

    }

   

    switch(nkey)//游戏过程

{

   代码略

}

void Main_Task(void *Id)             //Main_Test_Task

{

      int x,y;

      POSMSG  pMsg;

      Wnd MainWindow;

      PWnd pMainWindow;

      structRECT MainwinRect;

      structRECT* pMainwinRect;

     

      char Main_Wnd_Caption_8[]="Catch Chick";

      U16 Main_Wnd_Caption_16[20];

      initfinished = FALSE;

      gameover = FALSE;

      pause = FALSE;

      gamepass = FALSE;

     

      Step = 1;

      TotalCount = 0;

      CatchCount = 0;

      Score = 0;

      CurrentPos = 100;

      pMainWindow=&MainWindow;

      pMainwinRect = &MainwinRect;

      MainwinRect.bottom = 235;

      MainwinRect.left = 1;

      MainwinRect.right = 320;

      MainwinRect.top = 5;

      StepRectX = 255;

      StepRectY = 50;

     

      TotalCountRectX = 255;

      TotalCountRectY = 96;

     

      CatchCountRectX = 255;

      CatchCountRectY = 139;

     

      ScoreRectX = 255;

      ScoreRectY = 179;

      pdc = CreateDC();

      ClearScreen();//清屏

      ShowBmp(pdc,bmp_logo, 1, 1);//显示登录图片

      OSTimeDly(2000);//使显示持续一段时间

      ClearScreen();//清屏

      strChar2Unicode(Main_Wnd_Caption_16, Main_Wnd_Caption_8);

      pMainWindow =CreateWindow(120, pMainwinRect, FONTSIZE_SMALL,WND_STYLE_MODE, Main_Wnd_Caption_16, NULL);

      DrawWindow(pMainWindow);

     

      ClearScreen();

      ShowBmp(pdc,bmp_frame, 0, 0);

      initfinished = TRUE;//初始化部分结束

     

      while(1)

      {

            pMsg = WaitMessage(0);

            switch (pMsg->Message)

            {

                  case OSM_TOUCH_SCREEN:

                        x=pMsg->WParam&0xffff;

                      y=pMsg->WParam>>16;

                        onKey(x,y);

                        break;

            }

            DeleteMessage(pMsg);

            OSTimeDly(50);

      }

      DestoryDC(pdc);

}

void Display_Task(void *Id)

{

      int tempi;

      U16 tempstr[20];

      //判断主任务的初始化部分是否完成,如果完成则继续下面的显示工作,否则不再继续向下执行,交出CPU使用权

      if (initfinished == FALSE)

         OSTimeDly(2000);

      while(1)

      {

            if (gameover == TRUE)

            {

                  OSTimeDly(4000*1-700*Step);

                  continue;  

            }

            else if (pause == TRUE)

            {

                  ShowBmp(pdc,bmp_gamepause, 41, 95);//显示游戏暂停图片

                  OSTimeDly(4000*1-700*Step);

                  continue;

            }

            else

            {                

                  for(tempi=0;tempi<9;tempi++)

                  FillRect2(pdc, pRect[tempi], GRAPH_MODE_NORMAL, RGB(255, 255, 255));

                  CurrentPos = rand()%9;//产生一个0-8之间的随机整数

            ShowBmp(pdc,bmp_chick, Rect[CurrentPos].left, Rect[CurrentPos].top);//在制定的框中显示小鸡

                  TotalCount++;

                  CurrentPos++;

                  Int2Unicode(Step,tempstr);

                  TextOut(pdc, StepRectX, StepRectY, tempstr, TRUE, FONTSIZE_SMALL);

                  Int2Unicode(TotalCount,tempstr);

                  TextOut(pdc, TotalCountRectX, TotalCountRectY, tempstr, TRUE, FONTSIZE_SMALL);

                  Int2Unicode(CatchCount,tempstr);

                  TextOut(pdc, CatchCountRectX, CatchCountRectY, tempstr, TRUE, FONTSIZE_SMALL);

                  Int2Unicode(Score,tempstr);

                  TextOut(pdc, ScoreRectX, ScoreRectY, tempstr, TRUE, FONTSIZE_SMALL);

                  if (TotalCount >= 20)

                  {

                        gameover = TRUE;

                        if (CatchCount >= 10)

                        {

                              gamepass = TRUE;

                              ShowBmp(pdc,bmp_gamepass, 41, 95);//显示游戏过关图片

                        }

                        else

                        {

                              ShowBmp(pdc,bmp_gameover, 41, 95);//显示游戏结束图片

                        }

                  }

                  OSTimeDly(4000*1-700*Step);

           

            }

     

      }

}

五、实验体会

本次实验,我们运用ARM SDT 2.5.2 的集成开发环境,编写了一个小游戏,我们在编写和调试程序的过程中,掌握了LCD驱动方法,掌握了键盘控制方法,学会了如何把键盘控制转换为触摸屏控制。

相关推荐