《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)
{