《ARM高级程序设计》实验指导书(李强)

《ARM高级程序设计》实验指导书(李强)
《ARM高级程序设计》实验指导书(李强)

《ARM高级程序设计》实验指导书――(包括Protues仿真实验指导)

编撰李强

2013年6月6日

实验1 UCOS任务的管理机制

一、实验目的:

1.掌握keil集成开发环境及仿真调试

2.掌握C51及汇编程序的设计

3.理解UCOS任务的概念、意义及实现

二、实验设备:

1.硬件

PC机

2.软件

uVision 2

三、实验内容:

1.充分理解UCOS任务的意义,及UCOS对系统的管理机制

2.用uVisoion软件对UCOS软件进行编译、运行,打开串行输出端口Serial #1窗口,观察任务的运行情况,直观的理解UCOS的运行情况。

四、实验步骤

1.启动uVision2,使用建立一个工程。如UCOS

2.将UCOSII文件加入工程中。

3.将移植代码加入工程中

4.编译、连接工程,选择Project Debug ,启动软件仿真调试。

5.打开Serial 1#窗口,监视任务的运行情况

6.可以单步运行程序,可以设置、取消断点,或者全速运行,停止运行,调试时观察寄存器的值,运行结果见图1。

图1实验的运行结果

五、实验主要参考程序

#include "..\uc_os_II\includes.h"

OS_STK xdata Task1Stack[CPU_MAX_STK_SIZE]; OS_STK xdata Task2Stack[CPU_MAX_STK_SIZE]; OS_STK xdata Task3Stack[CPU_MAX_STK_SIZE]; OS_STK xdata Task4Stack[CPU_MAX_STK_SIZE];

void Task1(void xdata * ppdata) reentrant

{

ppdata = ppdata;

while(1)

{

OSTimeDlyHMSM(0, 0, 1, 0);

printf("\n1");

}

}

void Task2(void xdata * ppdata) reentrant

{

ppdata = ppdata;

while(1)

{

OSTimeDlyHMSM(0, 0, 2, 0);

printf("\n2");

}

}

void Task3(void xdata * ppdata) reentrant

{

ppdata = ppdata;

while(1)

{

OSTimeDlyHMSM(0, 0, 3, 0);

printf("\n3");

}

}

void Task4(void xdata * ppdata) reentrant

{

ppdata = ppdata;

while(1)

{

OSTimeDlyHMSM(0, 0, 4, 0);

printf("\n4");

}

}

void SerialInitial()

{

/* set TI to 1, set TR1 to 1 */

SCON = 0x52;/* SM0 SM1 =1 SM2 REN TB8 RB8 TI RI */

TMOD = 0x20;/* GATE=0 C/T-=0 M1 M0=2 GA TE C/T- M1 M0 */

TH1 = 0xE6; /* TH1=E6 4800bit/s when at 24MHz,TH1=F3,9600bit/s,24MHz */ PCON = 0x80;

TCON = 0x40;/* 01101001 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT */

}

void InterruptInitial()

{

/* set timer. 50ms, THTL = 3caf when cpu at 12MHz */

TMOD |= 0x01;

TH0 = 0x70;

TL0 = 0x00;

/* TR0 is set in OSStart() */

ET0 = 1;

}

main()

{

SerialInitial();

InterruptInitial();

OSInit();

printf("\nstart\nThis is my first program!");

OSTaskCreate(Task1, (void xdata *)0, &Task1Stack[0],2);

OSTaskCreate(Task2, (void xdata *)0, &Task2Stack[0],3);

OSTaskCreate(Task3, (void xdata *)0, &Task3Stack[0],4);

OSTaskCreate(Task4, (void xdata *)0, &Task4Stack[0],5);

OSStart();

}

实验2 LedDisp 实验

一、实验目的:

1.掌握启动代码Startup.s用法

2.用LED流水对进一步演示UCOS的工作机制

3.ADS、Protues软件的用法

二、实验设备:

1.硬件

PC机

2.软件

ADS1.2、AXD、Protues

三、实验内容:

1.掌握ADS、Protues软件的用法

2.认真阅读Startup组中的文件init.s,Vectors.s,理解启动代码

3. 用ADS1.2编译LedDisp工程,并形成.hex文件,启动Protues,将该文件下载到Protues 中LPC2106中,全速运行程序,观察运行情况。

四、实验步骤

1.启动ADS1.2,使用ARM Executable Image工程模板建立一个工程。如LedDisp.mcp 2.将UCOS源微机,移植源文件等加入工程中,如图1所示

图1

3.选择Edit - Release Settings 命令,选择ARM Linker,修改RW Base为

0x40000040,如图2所示。

4.在OPTION选项卡中的Image entry point 栏中输入0x00000000,其他不变,如图3所示;

图3

5.选择Project – Make命令,对工程进行编译,并生成Leddisp.hex文件,编译结果如图4所示。

图4

5.启动Protues ,加载LedDisp.DSN 设计,将LedDisp.hex调入LPC2106芯片中,如

图5所示。运行所加载的设计,观察实验结果。

图5 .hex文件加载

6.运行实验结果,见图5

图6 实验的运行结果

五、实验参考程序

/****************************************************************************** ***************************

** 函数名称: main

** 功能描述: c语言的主函数,由它启动多任务环境

******************************************************************************* *************************/

int main (void)

{

OSInit();

OSTaskCreate(Main_Task, (void *)0, &Main_TaskStk[TASK_STK_SIZE - 1], 0);

OSStart();

return 0;

}

void LED_Init (void)

{

PINSEL0= 0; /* Use GPIO pins P0.0 to P0.15 for LEDs */

IODIR|= 0x0000FFFF; /* Set GPIO pins as outputs */

LED_Off(0); /* Turn OFF all the LEDs */

}

/****************************************************************************** ***************************

** 函数名称: Main_Task

** 功能描述: μCOS-II的第一个任务,通常由它初始化目标板和建立其它任务

******************************************************************************* *************************/

void Main_Task(void *p_arg)

{ int i;

p_arg = p_arg; /* 避免编译警告*/

TargetInit();

LED_Init(); /* 目标板初始化*/

while (TRUE) { /* Task body, always written as an infinite loop. */

for (i = 1; i <= 16; i++) {

LED_On(i);

OSTimeDlyHMSM(0, 0, 0, 50);

LED_Off(i);

}

for (i = 1; i <= 16; i++) {

LED_On(17 - i);

OSTimeDlyHMSM(0, 0, 0, 50);

LED_Off(17 - i);

}

}

}

// End Of File

实验3 Counter 实验

一、实验目的:

6.进一步掌握启动代码Startup.s用法

7.用Counter流水对进一步演示UCOS的工作机制

8.ADS、Protues软件的用法

二、实验设备:

1.硬件

PC机

2.软件

ADS1.2、AXD、Protues

三、实验内容:

1.掌握ADS、Protues软件的用法

2.认真阅读Startup组中的文件init.s,Vectors.s,和Target.c,理解启动代码

3. 用ADS1.2编译Counter工程,并形成.hex文件,启动Protues,将该文件下载到Protues中LPC2106中,全速运行程序,观察运行情况。

四、实验步骤

1.启动ADS1.2,使用ARM Executable Image工程模板建立一个工程。如Counter.mcp 2.将UCOS源微机,移植源文件等加入工程中,如图1所示

图1

4.选择Edit - Release Settings 命令,选择ARM Linker,修改RW Base为

0x40000040,如图2所示。

图2

9.在OPTION选项卡中的Image entry point 栏中输入0x00000000,其他不变,如图3所示;

图3

10.选择Project – Make命令,对工程进行编译,并生成Counter.hex文件,编译结果如图4所示。

图4

5.启动Protues ,加载Counter.DSN 设计,将Counter.hex调入LPC2106芯片中,如

图5所示。运行所加载的设计,观察实验结果。

图5 .hex文件加载

6.运行实验结果,见图5

图6 实验的运行结果

五、实验参考程序

/****************************************************************************

* File:Main.C

* 功能:计数器,通过两个按键来控制加减计数器,并输出数码管显示.。

****************************************************************************/ #include "config.h"

#define CON 0x000000ff //控制P0.0~P0.7

#define TASK_STK_SIZE 64

OS_STK Main_TaskStk[TASK_STK_SIZE];

OS_STK Task0Stk[TASK_STK_SIZE];

void Main_Task(void *data);

void Task0(void *data);

/**************************************************************************** * 名称:main()

* 功能:主函数,启动多任务环境

****************************************************************************/ int main (void)

{

OSInit();

OSTaskCreate(Main_Task, (void *)0, &Main_TaskStk[TASK_STK_SIZE - 1], 0);

OSStart();

return 0;

}

/**************************************************************************** * 名称:Main_Task()

* 功能:初始化目标板,建立其他任务

****************************************************************************/

void Main_Task(void *pdata)

{

pdata=pdata;

TargetInit();

OSTaskCreate(Task0, (void *)0, &Task0Stk[TASK_STK_SIZE - 1], 1);

PINSEL0=0x0;

IODIR=CON;

IOCLR=CON;

OSTaskSuspend(OS_PRIO_SELF);

}

/**************************************************************************** * 名称:Task0()

* 功能:任务

****************************************************************************/ void Task0(void *pdata)

{ uint16 temp;

pdata=pdata;

temp=0;

for(;;)

{

if((IOPIN&0x00030000)!=0x00030000)

OSTimeDly(OS_TICKS_PER_SEC/50);

if((IOPIN&0x00030000)!=0x00030000)

{

if((IOPIN&0x00030000)==0x00020000)

temp++;

if((IOPIN&0x00030000)==0x00010000)

temp--;

while((IOPIN&0x00030000)!=0x00030000);

IOCLR=CON;

IOSET=temp;

}

}

OSTaskResume(0);

}

实验4 Counter 实验

一、实验目的:

11.进一步掌握UCOS的工作原理

12.用Counter流水对进一步演示UCOS的工作机制

13.ADS、Protues软件的用法

二、实验设备:

1.硬件

PC机

2.软件

ADS1.2、AXD、Protues

三、实验内容:

1.掌握ADS、Protues软件的用法

2.认真阅读头文件Target,h和config.h,进一步理解UCOS代码

3. 用ADS1.2编译Led工程,并形成.hex文件,启动Protues,将该文件下载到Protues中LPC2106中,全速运行程序,观察运行情况。

四、实验步骤

1.启动ADS1.2,使用ARM Executable Image工程模板建立一个工程。如led.mcp

2.将UCOS源微机,移植源文件等加入工程中,如图1所示

图1

5.选择Edit - Release Settings 命令,选择ARM Linker,修改RW Base为

0x40000040,如图2所示。

图2

14.在OPTION选项卡中的Image entry point 栏中输入0x00000000,其他不变,如图3所示;

图3

15.选择Project – Make命令,对工程进行编译,并生成Led.hex文件,编译结果如图4所示。

图4

5.启动Protues ,加载Counter.DSN 设计,将Counter.hex调入LPC2106芯片中,如

图5所示。运行所加载的设计,观察实验结果。

图5 .hex文件加载

6.运行实验结果,见图5

图6 实验的运行结果

五、实验参考程序

#include "config.h"

#define rs (1<<8)

#define rw (1<<9)

#define en (1<<10)

#define busy (1<<7)

#define TASK_STK_SIZE 64

OS_STK TaskStartStk[TASK_STK_SIZE];

void TaskStart(void *data);

uint8 txt[]={"helloworld"};

/**************************************************************************** * 名称:ChkBusy()

* 功能:检查总线是否忙

****************************************************************************/ void ChkBusy()

{

PINSEL0=0xffc00000;

IODIR=0x700;

while(1)

{

IOCLR=rs;

IOSET=rw;

IOSET=en;

if(!(IOPIN & busy))break;

IOCLR=en;

}

IODIR=0x7ff;

}

/**************************************************************************** * 名称:WrOp()

* 功能:写函数

****************************************************************************/ void WrOp(uint8 dat)

{

ChkBusy();

IOCLR=rs; //全部清零

IOCLR=rw;

IOCLR=0xff; //先清零

IOSET=dat; //再送数

IOSET=en;

IOCLR=en;

}

/**************************************************************************** * 名称:WrDat()

* 功能:写数据函数

****************************************************************************/ void WrDat(uint8 dat) //读数据

{

ChkBusy();

IOSET=rs;

IOCLR=rw;

IOCLR=0xff; //先清零

IOSET=dat; //再送数

IOSET=en;

IOCLR=en;

}

/**************************************************************************** * 名称:DisText()

* 功能:显示文本函数

****************************************************************************/

void DisplayText(uint8 addr,uint8 *p)

{

相关主题
相关文档
最新文档