111
实验项目名称:基于ucOS的多任务系统
一、实验目的
(1) 掌握LPC2200(for MagicARM2200)专用工程模板的使用;
(2) 能够在MagicARM2200-S 上运行基于μC/OS-II 操作系统的程序;
(3) 掌握基于μC/OS-II 操作系统的用户程序的编写格式。
二、实验内容及要求
建立三个或三个以上的μC/OS-II 的任务,一个任务用于检测KEY1 按键输入,称之为按键检测任务,另一个任务用于控制蜂鸣器,就称之为蜂鸣器控制任务。还有LED灯任务和电机任务。要求各个任务之间不是独立的,而是有相互关联的,达到多任务间的数据通信和同步的实验要求。
三、实验设备及软件
硬件:PC 机 一台
MagicARM2200-S 教学实验开发平台 一套
软件:Windows98/XP/2000 系统,ADS 1.2 集成开发环境
μC/OS-II 操作系统(V2.52)
四、设计方案
方案一: 建立四个任务:LED灯、按键、电机、蜂鸣器
LED任务:LED灯有不同的花样,由数组中的十六进制数据决定。可通过设计数组的数据来设计出很多的花型。
按键任务:按键任务主要是对按下的键在0到4内计数,再将所计的数通过邮箱发送给LED、电机任务,来控制任务间的通信。
电机任务:电机的转速会不断的改变,电机的转速也是靠按键任务里发送的广播邮箱的值确定的,有五种转速。每次按下一次按键,转速就会改变一次。
蜂鸣器任务:蜂鸣器的响灭是由LED任务里发送的信号量控制的,当LED灯亮完一个周期后就发送一个信号让蜂鸣器响起来,响完后蜂鸣器自己删除信号量,等着LED灯再一次并且发送信号。
这四个任务间都有着相互的交互关系。
方案二: 建立三个任务:LED灯、蜂鸣器、按键 LED任务:LED灯花样在数组中确定,方法很简单,只要改变数组内十六进制的数据后,就可以很简单的控制灯的闪烁方式了, LED显示完一个周期就会继续执行下一个周期,往复循环,直到按下REST键就会停止。
蜂鸣器任务:蜂鸣器可由按键控制,当按键1按下后,蜂鸣器开始鸣叫,鸣叫的次数可由程序控制,延时也同样可控,在本人的设计中,我把鸣响次数设为10.,同样按下REST键就会停止鸣响。
按键任务:按键任务其实就是进行等待按键按下,然后发送信号量给LED任务、蜂鸣器任务。
方案选择:
在我的这个设计中任务之间的联系并不是很紧密,而且每一个状态都很简单的, 通过设置优先级来控制优先发生次序,但是四个功能都是很好的实现了的,但是在调试方案一时,程序老是出不来,电机总是不转,检查了程序,但是最后因为时间有限就放弃了四个任务的,选择了稍微简单的三个任务的程序,虽然简单了一些,但是道理都是一样的。为了更完美一些,我设计了很多种LEDA灯的花型 。相对而言程序比较简单,易懂!适合我们这些初学者。
五﹑实验步骤
在MagicARM2200-S 上运行基于μC/OS-II 操作系统的程序的具体操作步骤如下。 安装ADS 1.2 (PC)
了解ADS 1.2 (PC)
连接EasyJTAG 仿真器和MagicARM2200-S (硬件)
安装EasyJTAG 驱动程序 (PC)
添加工程模板 (PC)
建立项目目录并添加μC/OS源代码和移植代码 (PC)
用工程模板建立工程 (PC)
仿真调试工程 (PC+硬件)
(1) 安装ADS 1.2
运行在ADS 目录下Setup.exe,开始安装ADS1.2。(若已安装过,此步省略)
按照安装软件的提示安装,与其它软件安装操作方法基本一致。
(2) 了解ADS 1.2
使用ADS1.2 建立工程,编译链接设置,调试操作等,更详细的使用方法参考ADS1.2 的在线帮助文档或相关资料。(若已熟悉ADS 1.2,此步省略)
(3) 连接EasyJTAG 仿真器和MagicARM2200-S
将EasyJTAG 仿真器的25 针接口通过并口延长线与PC 机的并口连接,先给
MagicARM2200-S 实验箱供电,再将EasyJTAG 仿真器的20 针接口通过20 PIN 连接电缆接
到MagicARM2200-S 的J3 上。(若已连接好,此步省略)
(4) EasyJTAG 仿真器的安装与应用
若已安装过,此步省略。
(5) 添加工程模板
若已添加过,此步省略。
(6) 建立项目目录并添加μC/OS源代码和移植代码
建立一个项目目录,比如uCOS-II。将μC/OS源代码Source(目录)复制到项目目录, 将移植代码ARM(目录) 复制到项目目录。
将移植的PC 服务代码Arm_Pc 复制到项目目录,使用移植的PC 服务代码,就可以通 过串口向PC 发送显示数据(由EasyARM 软件的DOS 字符窗口显示)。
μC/OS 源代码可以从参考文献[4]的附带光盘上获得。
移植代码ARM 和移植的PC 服务代码Arm_Pc 可以从MagicARM2200-S 的产品配套光 盘上获得。
(7) 用工程模板建立工程
使用LPC2200(for MagicARM2200)专用工程模板建立工程(比如“ARM Executable Image for UCOSII(MagicARM2200)”工程模板),工程存放路径为项目目录下,建立源文件并加入
工程,然后编写程序代码。更改Os_cfg.h 文件,配置μC/OS-II 操作系统。 编译链接工程,若有错误,则修改程序,然后再次编译。
(8) 仿真调试工程
正确设置MagicARM2200-S 的跳线;
启动AXD 进行仿真调试。
六、部分主要代码
方案一程序如下:
#include "config.h"
#include "stdlib.h"
#define KEY1 (1 << 20) /* P0.20 为KEY1 */
#define BEEP (1 << 7) /* P0.7 为蜂鸣器*/
#define LED_OFF() IO1SET=LED_IOCON
#define LED_DISP(dat) LED_OFF(); IO1CLR=((dat)<<LED_ADJ) #define LED_ADJ 16
#define LED_IOCON (0xFF<<LED_ADJ)
#define LEDCON 0x00ff0000 // LED 控制字
#define CYCLE_DATA 200000 // 定义周期
#define DUTY_CYCLE_DATA 20000 // 定义基本占空比参数 #define LED1 1<<16 // P1.16
#define LED2 1<<17 // P1.17
#define LED3 1<<18 // P1.18
#define LED4 1<<19 // P1.19
#define LED5 1<<20 // P1.20
#define LED6 1<<21 // P1.21
#define LED7 1<<22 // P1.22
#define LED8 1<<23 // P1.23
#define TaskStkLengh 64
OS_STK TaskStk0[TaskStkLengh];
OS_STK TaskStk1[TaskStkLengh];
OS_STK TaskStk2[TaskStkLengh];
OS_STK TaskStk3[TaskStkLengh];
void Task0(void *pdata); //Task0 任务
void Task1(void *pdata); //Task0 任务
void Task2(void *pdata); //Task2 任务
void Task3(void *pdata); //Task2 任务
OS_EVENT *semled;
OS_EVENT *sempwm;
OS_EVENT *sembeep;
int main(void)
{
OSInit ();
OSTaskCreate (Task0,(void *)0, &TaskStk0[TaskStkLengh - 1],3); OSTaskCreate (Task2,(void *)0, &TaskStk2[TaskStkLengh - 1],5);
OSTaskCreate (Task3,(void *)0, &TaskStk3[TaskStkLengh - 1],4); OSStart ();
return 0;
}
void Task0(void *pdata)
{
INT8U err;
const uint8 DISP_TAB[24] = {
0xFF,0xEE, 0xDD,0xCC, 0X55,0xBB,0xAA,0x99,0x88,0x77,0x66, 0x55,0xCC, 0x44,0x22,0x11,0x00
,0xFF,0x18, 0x3C,0x7E, 0xFF,0x00,0xFF};
uint8 i;
pdata = pdata;
semled=OSSemCreate(0);
TargetInit ();
PINSEL0 = 0x00000000;
IO0DIR = BEEP;
IO1DIR = LED_IOCON;
LED_OFF();
OSTaskCreate (Task1,(void *)0, &TaskStk1[TaskStkLengh - 1],6); while (1)
{
OSSemPend(semled,0,&err);
for(i=0; i<24; i++)
{
LED_DISP(DISP_TAB[i]);
OSTimeDly(OS_TICKS_PER_SEC);
}
OSSemPost(sempwm);
}
}
void Task1(void *pdata)
{
INT8U err;
pdata = pdata;
sembeep=OSSemCreate(0);
sempwm=OSSemCreate(0);
while(1)
{
OSSemPend(sembeep,0,&err);
OSTimeDly(OS_TICKS_PER_SEC/8);
IO0CLR = BEEP;
OSTimeDly(OS_TICKS_PER_SEC/4); IO0SET = BEEP;
OSTimeDly(OS_TICKS_PER_SEC/2); IO0CLR = BEEP;
OSTimeDly(OS_TICKS_PER_SEC/4); IO0SET = BEEP;
OSTimeDly(OS_TICKS_PER_SEC/8); IO0CLR = BEEP;
OSTimeDly(OS_TICKS_PER_SEC/2); IO0SET = BEEP; }
}
void Task2(void *pdata)
{
pdata = pdata;
IO0DIR&=~KEY1;
while(1)
{
while((IO0PIN & KEY1) != 0)
{
OSTimeDly(OS_TICKS_PER_SEC ); OSSemPost(sembeep);
OSSemPost(sempwm);
}
OSSemPost(semled);
while ((IO0PIN & KEY1) == 0) {
}
}
void Task3 (void *pdata)
{ INT8U err;
uint8 i = 0;
pdata = pdata;
PINSEL1 = 0x01<<10;
IO1DIR = LEDCON;
PWMPR = 0x00;
PWMMCR = 0x02;
PWMMR0 = CYCLE_DATA;
PWMMR5 = DUTY_CYCLE_DATA;
PWMLER = 1 << 0 | 1<< 5;
PWMPCR = 1 << 13;
PWMTCR = 0x09;
while (1)
{
OSSemPend(sempwm, 0, &err);
PWMMR5 = DUTY_CYCLE_DATA*i;
PWMLER = 1 << 0 | 1<< 5;
PWMTCR = 0x09;
i = (i+1)%5;
OSTimeDly(OS_TICKS_PER_SEC*3 );
}
}
方案二程序如下:
#include "config.h"
#include "stdlib.h"
// P0.7 为蜂鸣器的控制I/O
#define BEEP (1<<7)
#define KEY1 (1<<20)
// LED 控制宏函数定义。LED1--LED8 的控制I/O 为P1.16--P1.23
#define LED_ADJ 16
#define LED_IOCON (0xFF<<LED_ADJ)
#define LED_OFF() IO1SET=LED_IOCON
#define LED_DISP(dat) LED_OFF(); IO1CLR=((dat)<<LED_ADJ)
#define TaskStkLengh 100 //定义用户任务堆栈长度
OS_STK TaskStk0[TaskStkLengh]; //Define the Task0 stack 定义用户任务0 的堆栈 OS_STK TaskStk1[TaskStkLengh]; //Define the Task1 stack 定义用户任务1 的堆栈 OS_STK TaskStk2[TaskStkLengh]; //Define the Task2 stack 定义用户任务2 的堆栈
void Task0(void *pdata); //Task0 任务0
void Task1(void *pdata); //Task1 任务1
void Task2(void *pdata); //Task2 任务2
OS_EVENT *Mbox;
int dly;
int main (void)
{
OSInit();
OSTaskCreate (Task0,(void *)0, &TaskStk0[TaskStkLengh - 1], 4);/*创建LED任务*/ OSTaskCreate (Task1,(void *)0, &TaskStk1[TaskStkLengh - 1], 6); /*创建BEEP任务*/ OSTaskCreate (Task2,(void *)0, &TaskStk2[TaskStkLengh - 1], 2); /*创建KEY任务*/
OSStart ();
return 0;
}
/*****************************************************************************************
** Task0 任务0
*****************************************************************************************/
void Task0(void *pdata)
{ const uint8 DISP_TAB[32] = { 0x18,0x3C,0x7E,0xFF,0x7E,0x3C,0x18,0x00,0xAA,0x55,0xAA,0x55,0xCC,0x33,0xCC,0x33,0x99,0x66,0x99,0x66,0x18,0x3C,0x81,0xC3,0x00,0xC3,0x66,0x3C,0x18,0x3C,0x66,0xC3
};
//INT8U err;
//INT16U *pd;
uint8 i;
//pdata = pdata;
TargetInit ();
PINSEL1=0x00000000;
IO0DIR = BEEP; // 设置蜂鸣器控制口为输出
IO0SET = BEEP;
IO1DIR = LED_IOCON; // 设置LED1-LED8 的控制口为输出 LED_OFF();
Mbox=OSMboxCreate(NULL);
while(1)
{
// pd=(INT16U *)OSMboxPend(Mbox,0,&err);
for(i=0;i<32;i++)
{
LED_DISP(DISP_TAB[i]); // 输出LED 显示数据
OSTimeDly(OS_TICKS_PER_SEC/2); // 延时0.5S
}
}
}
/********************TASK1****************************/ void Task1(void *pdata)
{ int i;
INT8U err;
INT16U *pd;
pdata=pdata;
IO0DIR|=BEEP;
while(1) {
pd=(INT16U *)OSMboxPend(Mbox,0,&err);
for(i=0;i<10;i++)
{
IO0CLR=BEEP;
OSTimeDly(50);
IO0SET=BEEP;
OSTimeDly(50);
}
}
}
/********************TASK2**************************/ void Task2(void *pdata)
{
pdata=pdata;
IO0DIR&=~KEY1;
while(1)
{
while((IO0PIN&KEY1)!=0)
{
OSTimeDly(1);
}
OSMboxPostOpt(Mbox,&dly,OS_POST_OPT_BROADCAST);
while((IO0PIN&KEY1)==0)
{
OSTimeDly(1);
}
}
}
六、测试结果
方案一仿真测试后并没有实现理想的设计功能,电机没有转动,可能是软件设计有问题或者是试验箱由问题,功能不齐全了。由于实验考试的时间关系,也没有仔细的花费时间检查,于是我就采取了简单一些的三个任务的程序,实现起来还是很好的,该有的功能也有,而且花型比较好看,满足老师的设计要求。
方案二实现了LED等闪烁、蜂鸣器响、电机转动、按键有效的功能。并且他们之间也存在着一定的关系。
LED灯的花型如下:
○○○●●○○○ ●○●○●○●○
○○●●●●○○ ○●○●○●○●
○●●●●●●○ ●○●○●○●○
●●●●●●●● ○●○●○●○●
○●●●●●●○ ●●○○●●○○
○○●●●●○○ ○○●●○○●●
○○○●●○○○ ●●○○●●○○
○○○○○○○○ ○○●●○○●●
●○○●●○○● ○○○○○○○○
○●●○○●●○ ●●○○○○●●
○○○●●○○○ ○●●○○●●○
○○●●●●○○ ○○●●●●○○
○○○●●○○○ ○○○●●○○○
○○●●●●○○ ○○●●●●○○
●○○○○○○● ○●●○○●●○
●●○○○○●● ●●○○○○●●
七、总结体会
说实话,ARM这门课对于我来说是比较难学和难理解的一门课,在学习当中遇到了很多的问题,对于很多很抽象的概念不理解,但是通过做了好几次的实验,在老师的精心指导和严格要求下,还是掌握了不少的知识,记得刚开始做实验的时候连软件的用起来很吃力,但是通过几次的实验和最后的综合实验,让我掌握了MagicARM2200-S的使用方法,而且对ARM嵌入式系统的知识有了很具体的理解,有利于更好的学习这门课,为以后的学习奠定良好的基础。
这个综合实验是MagicARM2200-S 上运行基于μC/OS-II 操作系统的程序,让我掌握了μC/OS-II程序设计的方法,任务间通信可以通过信号量,消息邮箱和消息队列实现,在本次设计中,我采用了消息邮箱的方法,因为我对这种方法理解的更深。邮箱用来在任务间或中断与任务间传递一个指针,以便任务可以通过指针发送和接受任意类型的数据,一个邮箱只能存放一条消息。邮箱的工作方式有一对一工作方式和多对一工作方式,一对多工作方式。
本来为了更好的完成设计,想实现四个任务的,由于没有及时的调试出来,时间有限,只有选择一个稍微简单一些的设计了,但是设计的思路应该是没有问题的,相信如
果有足够的时间的话一定可以调试出来的。为了使它不是很单调,我设计了很多种花型,希望可以弥补没有完成四个任务的不足。这次的实验让我学会了自学,学会了耐心,学会了请教他人,收获良多,受益匪浅。
嵌入式系统设计实验报告专业微电子学姓名胡文彬学号10122120xx1一静态数码管一实验要求使用的IO数码管使用P0键盘使用P30…
111实验项目名称基于ucOS的多任务系统一实验目的1掌握LPC2200forMagicARM2200专用工程模板的使用2能够在M…
嵌入式系统设计实验报告实验三LINUX网络与应用程序开发文件file实验内容在PC上的linux虚拟机中调试通过定时器filec文…
嵌入式系统设计实验报告班级学号姓名成绩指导教师1实验一11实验名称博创UP3000实验台基本结构及使用方法12实验目的1学习嵌入式…
合肥学院嵌入式系统设计实验报告(20___-20___第__学期)专业:_____________________________…
重庆航天职业技术学院课程作业课程名称嵌入式系统专选班级学号姓名成绩前言嵌入式系统是基于单片机的一种升级版它是以应用为中心以计算机技…
嵌入式系统设计实验报告班级学号姓名成绩指导教师1实验一11实验名称博创UP3000实验台基本结构及使用方法12实验目的1学习嵌入式…
嵌入式系统实验报告姓名:##学号:##班级:计算机科学与技术非师范121班实验一LCD控制一、实验目的1、初步掌握液晶显示屏的使用…
嵌入式系统实验报告书院系姓名专业学号指导老师电子通信工程系蒋瑾通信工程101307313赵成实验一认识嵌入式开发平台一实验目的认识…
实验报告20xx20xx学年第二学期课程名称ARM嵌入式系统原理与开发实验名称嵌入式Linux交叉开发环境建立与程序开发实验时间指…
《嵌入式系统》实验报告姓名:学号:班级:湖南工业大学电气与信息工程学院20xx年x月实验一ARM汇编指令实验1一、实验目的1.初步…