北航ARM9实验报告
更新时间:2024-04-12 09:41:01 阅读量: 综合文库 文档下载
1
ARM9嵌入式系统实验
实验报告
院(系)名称 自动化科学与电气工程学院 学生姓名 学
号
任课老师
2013年 11 月 15 日
北京航空航天大学研究生实验报告
实验一
ARM基础知识和开发环境
一、实验目的
1.掌握ARM的串行口工作原理。 2.学习编程实现ARM的UART通讯。 3.掌握S3C2410寄存器配置方法。
二、实验内容
1.熟悉打开已有工程的步骤,掌握仿真调试的方法。
2.建立一个新工程,熟练掌握编译器和链接器的设置方法。
3.从串口输入字符串,将0~9数字在超级终端上连续显示,―Enter‖键换行。 4.将第三步得到的字符转换成BCD码,限制在0~1023,用于控制直流电机。
三、预备知识
1. 了解EWARM集成开发环境的基本功能 2. 学习串口通讯的基本知识
3. 熟悉S3C2410串口有关的寄存器
四、实验设备及工具
1. 2410s教学实验箱
2. S3C2410的JTAG仿真器
3. ARM EWARM5.3集成开发环境 4. 串口连接线
五、实验原理及说明
1. 异步串行I/O
异步串行方式是将传输数据的每个字符一位接一位(例如先低位、后高位)地传送。数据的各不同位可以分时使用同一传输通道,因此串行I/O可以减少信号连线,最少用一对线即可进行。接收方对于同一根线上一连串的数字信号,首先要分割成位,再按位组成字符。为了恢复发送的信息,双方必须协调工作。在微型计算机中大量使用异步串行I/O方式,双方使用各自的时钟信号,而且允许时钟频率有一定误差,因此实现较容易。但是由于每个字符都要独立确定起始和结束(即每个字符都要重新同步),字符和字符间还可能有长度不定的空闲时间,因此效率较低。
- 1 -
北京航空航天大学研究生实验报告
2. RS-232C接口通信的两种基本连接方式
这是美国电子工业协会推荐的一种标准(Electronic industries Association
Recoil-mended Standard)。它在一种25针接插件(DB—25)上定义了串行通信的有关信号。这个标准后来被世界各国所接受并使用到计算机的I/O接口中。两种连接方式如下图:
3. 信号电平规定
1) EIA电平:双极性信号逻辑电平, 它是一套负逻辑定义
? -3V到-25V之间的电平表示逻辑―1‖。 ? +3V到+25V之间的电平表示逻辑―0‖。
2) TTL电平:计算机内部(S3C2410)使用LVTTL电平 3) 电平转换电路:常用专门的RS-232接口芯片,如SP3232、SP3220等,在LVTTL
电平和EIA电平之间实现相互转换。
4. 异步串行口接口电路
六、实验方法
1. 以实验一为模板,完成实验的1和2。
2. 将接收串口数据的数组cl[1]改为cl[256],用cl[i]==0x0d 回车字符作为一帧结束的
条件。
3. 将―Exp4 电机转动控制实验‖ inc目录下的MotorCtrl.H 和src目录下的MotorCtrl.C
拷到该工程相应目录,将MotorCtrl.C 添加到工程中。
4. 在main函数里包含以下头文件 #include ―../inc/MotorCtrl.h‖
5. 在main函数里包含以下头文件 #include ―inc/macro.h―,#define
MOTOR_COUNT 12657。
6. 在Main函数里执行init_MotorPort()。
7. 直流电机调试的函数是 SetPWM((setspeed -512)*MOTOR_COUNT/1024),
setspeed是速度指令,取值范围0~1023。
七、程序源代码
#include \#include \
- 2 -
北京航空航天大学研究生实验报告
#define U8 unsigned char #include
#define MOTOR_COUNT 12657
//#pragma import(__use_no_semihosting_swi) // ensure no functions that use semihosting
#define rUTRSTAT0 (*(volatile unsigned *)0x50000010) #define rUTRSTAT1 (*(volatile unsigned *)0x50004010)
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch) #define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch) #define RdURXH0() (*(volatile unsigned char *)0x50000024) #define RdURXH1() (*(volatile unsigned char *)0x50004024) //void Uart_SendByten(int Uartnum, U8 data); void Uart_SendByten(int,U8);
char Uart_Getchn(char* Revdata, int Uartnum, int timeout);
unsigned int num;
void ARMTargetInit(void); void hudelay(int time); int main(void) { //int ndev; char c[2];
char err; ARMTargetInit(); // do target (uHAL based ARM system) initialisation // init_MotorPort(); Uart_SendByten(0,0xa);//换行 Uart_SendByten(0,0xd);//回车
printf(\ while(1) { err=Uart_Getchn(c,0,0); //从串口采集数据
if (err==TRUE) {
if(c[0] == '\\r') {
Uart_SendByten(0,0xa);//换行
- 3 -
北京航空航天大学研究生实验报告
Uart_SendByten(0,0xd);//回车 if(num < 1024) {
printf(\ SetPWM((num -512)*MOTOR_COUNT/1024); } else {
printf(\ }
num = 0;
Uart_SendByten(0,0xa);//换行 Uart_SendByten(0,0xd);//回车
printf(\ } else {
Uart_SendByten(0,c[0]); //显示采集的数据 if(c[0] > '9' || c[0] < '0') {
Uart_SendByten(0,0xa);//换行 Uart_SendByten(0,0xd);//回车
printf(\ Uart_SendByten(0,0xa);//换行 Uart_SendByten(0,0xd);//回车
printf(\ num = 0; } else {
c[1] = c[0] - '0';
num = num * 10 + c[1]; } } } } }
void Uart_SendByten(int Uartnum, U8 data)//ok eric rong { //int i; if(Uartnum==0) { while(!(rUTRSTAT0 & 0x4)); //Wait until THR is empty.
- 4 -
北京航空航天大学研究生实验报告
hudelay(10); WrUTXH0(data); } else { while(!(rUTRSTAT1 & 0x4)); //Wait until THR is empty. hudelay(10); WrUTXH1(data); } }
char Uart_Getchn(char* Revdata, int Uartnum, int timeout) { if(Uartnum==0){ while(!(rUTRSTAT0 & 0x1)); //Receive data read *Revdata=RdURXH0(); return TRUE; } else{ while(!(rUTRSTAT1 & 0x1));//Receive data read *Revdata=RdURXH1(); return TRUE; } }
八、思考题
1. 232串行通讯的数据格式是什么? 答:格式如下图所示
2. 串行通讯最少需要几根线,分别如何连接?
答:至少需要三根线,分别是发送线,接收线,和接地线。连接方法如图所示,
- 5 -
北京航空航天大学研究生实验报告
3. ARM的串行口有几个,相应的寄存器是什么? 答:S3C2410自带三个异步串行口控制器。控制寄存器UCONn,FIFO控制寄存器UFCONn,线路控制寄存器ULCONn,控制寄存器UMCONn,状态寄存器UTRSTAT,错误状态寄存器UERSTAT,FIFO状态寄存器UFSTAT,发送寄存器UTXH和接收寄存器URXH,波特率因子寄存器UBRDIV。
4. 用中断方式实现串口驱动。
答:中断方式实现串口驱动的流程图如下:
- 6 -
北京航空航天大学研究生实验报告
实验二
LCD 和电机等综合实验
一、实验目的
1.熟悉ARM本身自带的六路即三对PWM,掌握相应寄存器的配置。
2.编程实现ARM系统的PWM输出用于控制直流电机。 3.了解LCD基本概念与原理。 4.理解LCD的驱动控制。
5.熟悉用ARM内置的LCD控制器驱动LCD。
二、实验内容
学习直流电机的工作原理,了解实现电机转动对于系统的软件和硬件要求。学习ARM知识,掌握PWM的生成方法。
1.编程实现ARM芯片的一对PWM输出用于控制直流电机的转动,通过A/D旋钮控制其正反转及转速。
2.通过超级终端来控制直流电机的转动。 学习LCD显示器的基本原理,理解其驱动控制方法。掌握两种LCD驱动方式的基本原理和方法。并用编程实现:
1. 用ARM内置的LCD控制器来驱动LCD。
三、预备知识
1、用EWARM集成开发环境,编写和调试程序的基本过程。 2、ARM应用程序的框架结构。
3、掌握通过ARM自带的A/D转换器的使用。 4、了解直流电机的基本原理。
四、实验设备及工具
硬件:ARM嵌入式开发平台、用于S3C2410的JTAG仿真器、PC机Pentium100以上。 软件:PC机操作系统Win2000或WinXP、EWARM集成开发环境、仿真器驱动程序、超级终端通讯程序
五、实验原理及说明
1)直流电动机的PWM电路原理
晶体管的导通时间也被称为导通角а,若改变调制晶体管的开与关的时间,也就是说通过改变导通角а的大小,如下图所示,来改变加在负载上的平均电压的大小,以实现对电动机的变速控制,称为脉宽调制 (PWM)变速控制。在PWM变速控制中,系统采用直流电源,放大器的频率是固定,变速控制通过调节脉宽来实现。
- 7 -
北京航空航天大学研究生实验报告
2)开发平台中直流电机驱动的实现
开发板中的直流电机的驱动部分如图7-3所示;由于S3C2410X芯片自带PWM定时器,所以控制部分省去了三角波产生电路、脉冲调制电路和PWM信号延迟及信号分配电路,取而代之的是S3C2410X芯片的定时器0、1组成的双极性PWM发生器。
PWM发生器用到的寄存器主要有以下几个:TCFG0、TCFG1、TCON、TCNTB0 & TCMPB0、TCNTO0。
3)LCD(Liquid Crystal Display)原理
液晶得名于其物理特性:它的分子晶体,以液态存在而非固态。 LCD显示器的基本原理就是通过给不同的液晶单元供电,控制其光线的通过与否,从而达到显示的目的。因此,LCD的驱动控制归于对每个液晶单元的通断电的控制,每个液晶单元都对应着一个电极,对其通电,便可使光线通过(也有刚好相反的,即不通电时光线通过,通电时光线不通过)。
4)S3C2410 LCD控制器逻辑框图
5)UPTECH-2410-S LCD图形显示方式
UPTECH-2410-S的LCD显示模块由LCD控制器和16位色彩色LCD示器组成。其显示方式以直接操作显示缓冲区的内容进行,LCD控制器会通过DMA从显示缓冲区中获取数据,不需要CPU干预。
本系统采用的LCD分辨率为640X480,工作在65536色彩色显示模式,在该模式下,显示缓冲区中的一个字节数据代表LCD上的一个点的颜色信息,因此,所需要的显示缓冲区大小为640X480X2字节。其中每个字节的彩色数据格式如下图所示:
- 8 -
北京航空航天大学研究生实验报告
六、实验方法
电机试验
1 通过一个电位器控制直流电机转动速度,并且用该电位器值使屏幕显示不同颜色。 2 用三个电位器分别控制R、G、B,观察屏幕的变化。 3 使用函数Uart_Printf(),将RGB的值打印到串口输出。 LCD实验:
1 在Main函数里执行LCD_Init();
2 将AD采样的结果在驱动电机的同时,和jcolor建立起联系。 3 显示缓冲区填充LCDBufferII2[k][j]=jcolor; 4 调用LCDFresh()函数。
七、程序源代码
#include \#include \#include
#include \#include \#include \#include \#include \
#define MCLK (50700000)
#define MOTOR_SEVER_FRE 1000 //20kHz #define MOTOR_CONT (MCLK/2/2/MOTOR_SEVER_FRE) #define MOTOR_MID (MOTOR_CONT/2)
#define ADCCON_FLAG (0x1<<15)
//#define ADCCON_ENABLE_START_BYREAD (0x1<<1) #define ADCCON_ENABLE_START_BYREAD (0x0<<1)
#define rADCCON (*(volatile unsigned *)0x58000000) #define rADCDAT0 (*(volatile unsigned *)0x5800000C) #define PRSCVL (49<<6)
#define ADCCON_ENABLE_START (0x1) #define STDBM (0x0<<2) #define PRSCEN (0x1<<14)
- 9 -
北京航空航天大学研究生实验报告
#define rADCCON (*(volatile unsigned *)0x58000000) #define rADCDAT0 (*(volatile unsigned *)0x5800000C) #define rUTRSTAT0 (*(volatile unsigned *)0x50000010) //#define rUTRSTAT0 (*(volatile unsigned *)0x50000024) #define RdURXH0() (*(volatile unsigned char *)0x50000024)
extern U32 LCDBufferII2[480][640];
void ARMTargetInit(void);
void init_ADdevice() {//初始化 rADCCON=(PRSCVL|ADCCON_ENABLE_START|STDBM|PRSCEN); } /*
int GetADresult(int channel) {
rADCCON=ADCCON_ENABLE_START_BYREAD|(channel<<3)|PRSCEN|PRSCVL; hudelay(10); while(!(rADCCON&ADCCON_FLAG));//转换结束 return (0x3ff&rADCDAT0);//返回采样值 } */
int GetADresult(int channel) { rADCCON=ADCCON_ENABLE_START_BYREAD|(channel<<3)|PRSCEN|PRSCVL;
rADCCON|=0x01; //启动AD转换器 hudelay(10); while(!(rADCCON&ADCCON_FLAG));//转换结束 return (0x3ff&rADCDAT0);//返回采样值} }
int main(void)
- 10 -
北京航空航天大学研究生实验报告
{ //int i,j,ADData,lastADData,count=0; //char Revdata[10]; //////////////A, AB, B, BC, C CD, D, DA //int stepdata[]={0x10,0x30,0x20,0x60,0x40,0xc0,0x80,0x90}; int i,ADData[3],j = 0; char ADData_8[3] = {0}; ARMTargetInit(); //开发版初始化 init_MotorPort(); init_ADdevice(); LCD_Init(); for(;;) { //begin: Uart_Printf(0,\motor.\\n\ for(;;) { for(i=0;i<3;i++) { ADData[i]=GetADresult(i);
ADData_8[i]=ADData[i] >> 2;
printf(\ } //Uart_Printf(0,\ hudelay(10); SetPWM((ADData[1]-512)*MOTOR_CONT/1024); hudelay(10);
for(i=0;i LCDBufferII2[j][i] = (U32)(ADData_8[0]<<16) + (U32)(ADData_8[1]<<8) + ADData_8[2]; } } LCD_Refresh(); } } }八、思考题 1)液晶显示的基本原理是什么? 答:LCD显示器是通过给不同的液晶单元供电,控制其光线的通过与否,从而达到显示 - 11 - 北京航空航天大学研究生实验报告 的目的。因此,LCD的驱动控制归于对每个液晶单元通断电的控制,每个液晶单元都对应着一个电极,对其通电,便可使用光线通过(也有刚好相反的,即不通电时光线通过,通电时光线不通过)。光源的提供方式有两种:透射式和反射式。笔记本电脑的LCD显示屏即为透射式,屏后面有一个光源,因此外界环境可以不需要光源。而一般微控制器上使用的LCD为反射式,需要外界提供光源,靠反射光来工作。 2)总线方式驱动液晶模块和使用控制器进行驱动控制有什么异同? 答:(1) 总线驱动方式 一般带有驱动模块的LCD显示屏使用这种驱动方式,由于LCD已经带有驱动硬件电路,因此模块给出的是总线接口,便于与单片机的总线进行接口。驱动模块具有八位数据总线,外加一些电源接口和控制信号。而且自带显示缓存,只需要将要显示的内容送到显示缓存中就可以实现内容的显示。由于只有八条数据线,因此常常通过引脚信号来实现地址与数据线复用,以达到把相应数据送到相应显示缓存的目的。下图为一个典型的显示模块(HY-12864B)提供的总线接口。 (2) 控制器扫描方式 S3C2410X中具有内置的LCD控制器,它具有将显示缓存(在系统存储器中)中的LCD图象数据传输到外部LCD驱动电路的逻辑功能。 S3C2410X中内置的LCD控制器可支持灰度LCD和彩色LCD。在灰度LCD上,使用基于时间的抖动算法(time-based dithering algorithm)和FRC (Frame Rate Control)方法,可以支持单色、4级灰度和16级灰度模式的灰度LCD。 在彩色LCD上,可以支持256级彩色,使用STN LCD可以支持4096级彩色。对于不同尺寸的LCD,具有不同数量的垂直和水平象素、数据接口的数据宽度、接口时间及刷新率,而LCD控制器可以进行编程控制相应的寄存器值,以适应不同的LCD显示板。 3)LCD显示图形的基本思想是什么? 答:UPTECH-3000的LCD显示模块由S3C2410的LCD控制器和256色彩色LCD显示器组成。其显示方式以直接操作显示缓冲区的内容进行,LCD控制器会通过DMA从显示缓冲区中获取数据,不需要CPU干预。本系统采用的LCD分辨率为320X240,工作在256色彩色显示模式,在该模式下,显示缓冲区中的一个字节数据代表LCD上的一个点的颜色信息,因此,所需要的显示缓冲区大小为320X240X1字节。其中每个字节的彩色数据格式如下图所示: - 12 - 北京航空航天大学研究生实验报告 实验三 基于实时操作系统μC/OS-II实验 一、 实验目的 1. 了解uCOS-II内核的主要结构。 2. 在内核移植了uCOS-II 的处理器上创建任务。 二、实验内容 1. 运行实验十,在超级终端上观察四个任务的切换。 2. 任务1~3,每个控制―红‖、―绿‖、―蓝‖一种颜色的显示,适当增加OSTimeDly()的时间,且优先级高的任务延时时间加长,以便看清三种颜色。 3. 引入一个全局变量 BOOLEAN ac_key,解决完整刷屏问题。 4. 任务4管理键盘和超级终端,当键盘有输入时在超级终端上显示相应的字符。 三、预备知识 1.掌握在EWARM集成开发环境中编写和调试程序的基本过程。 2.了解S3C2410处理器的结构。 3.了解uCOS-II系统结构。 四、实验设备及工具 硬件:ARM嵌入式开发平台、用于S3C2410的JTAG仿真器、PC机Pentium100以上。 软件:PC机操作系统Win2000或WinXP、EWARM集成开发环境、仿真器驱动程序、超级终端通讯程序。 五、实验原理及说明 所谓移植,指的是一个操作系统可以在某个微处理器或者微控制器上运行。虽然uCOS-II的大部分源代码是用C语言写成的,仍需要用C语言和汇编语言完成一些与处理器相关的代码。比如:uCOS-II在读写处理器、寄存器时只能通过汇编语言来实现。因为uCOS-II在设计的时候就已经充分考虑了可移植性,所以,uCOS-II的移植还是比较容易的。 1. 要使uCOS-II可以正常工作,移植?COS-II时须满足的条件: a) b) c) d) e) 处理器的C编译器能产生可重入代码; 在程序中可以打开或者关闭中断; 处理器支持中断,并且能产生定时中断(通常在10—100Hz之间); 处理器能容纳一定量数据的硬件堆栈; 处理器有将栈指针和其他CPU寄存器内容保存到栈(或者内存)的指令,以及相应的出栈指令。 2. 多任务,uCOS-II支持多任务并行执行,使用OSTaskStkInt()创建新任务, 同时调用本函数来初始化该任务的栈结构。任务的状态转换如下图: - 13 - 北京航空航天大学研究生实验报告 六、实验方法 1 以实验十为模板,将实验六 inc目录下的LCD320.H 和src目录下的LCD640.C拷到 模板下的相应目录,将LCD640.C加入工程中。 2 包含以下头文件 #include ―inc/lcd320.h‖。 3 改LCD640.C 文件中包含头文件的路径, #include \ 4 声明引用的变量 extern U32 LCDBufferII2[LCDHEIGHT][LCDWIDTH]; 七、程序源代码 #include\ /* uC/OS interface */ #include \#include \#include \ #include \ #include \#include \#include //#pragma import(__use_no_semihosting_swi) // ensure no functions that use semihosting OS_EVENT *MboxSem; extern U32 LCDBufferII2[LCDHEIGHT][LCDWIDTH]; BOOLEAN ac_key = TRUE; int i,j = 0; - 14 - 北京航空航天大学研究生实验报告 char err; char *c; #define rUTRSTAT0 (*(volatile unsigned *)0x50000010) #define RdURXH0() (*(volatile unsigned char *)0x50000024) #define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch) #define RED (0xff << 16) #define BLUE (0xff << 8) #define GREEN (0xff) char Uart_Getchn(char* Revdata, int Uartnum, int timeout); void Uart_SendByten(int Uartnum, U8 data); ///******************任务定义***************/// /*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, }; //Main_Test_Task堆栈 void Task1(void *Id); //Main_Test_Task #define Task1_Prio 12 OS_STK task2_Stack[STACKSIZE]={0, }; //test_Test_Task堆栈 void Task2(void *Id); //test_Test_Task #define Task2_Prio 15 OS_STK task3_Stack[STACKSIZE]={0, }; //test_Test_Task堆栈 void Task3(void *Id); //test_Test_Task #define Task3_Prio 17 OS_STK task4_Stack[STACKSIZE]={0, }; //test_Test_Task堆栈 void Task4(void *Id); //test_Test_Task #define Task4_Prio 19 /**************已经定义的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 - 15 - 北京航空航天大学研究生实验报告 #define Led_Flash_Prio 60 ***************************************///////// ///*****************事件定义*****************/// ///////////////////////////////////////////////////// // Main function. // //////////////////////////////////////////////////// int main(void) { ARMTargetInit(); // do target (uHAL based ARM system) initialisation // OSInit(); // needed by uC/OS-II // //OSInitUart(); //initOSFile(); //#if USE_MINIGUI==0 // initOSMessage(); // initOSDC(); // LoadFont(); //#endif //loadsystemParam(); // create the tasks in uC/OS and assign increasing // // priorities to them so that Task3 at the end of // // the pipeline has the highest priority. // //LCD_printf(\ //OSTaskCreate(SYS_Task, (void *)0, (OS_STK *)&SYS_Task_Stack[STACKSIZE-1], SYS_Task_Prio); OSTaskCreate(Task1, (void *)0, (OS_STK *)&task1_Stack[STACKSIZE-1], Task1_Prio); OSTaskCreate(Task2, (void *)0, (OS_STK *)&task2_Stack[STACKSIZE-1], Task2_Prio); OSTaskCreate(Task3, (void *)0, (OS_STK *)&task3_Stack[STACKSIZE-1], Task3_Prio); OSTaskCreate(Task4, (void *)0, (OS_STK *)&task4_Stack[STACKSIZE-1], - 16 - 北京航空航天大学研究生实验报告 Task4_Prio); OSAddTask_Init(0); BSPprintf(0,\ //LCD_printf(\ //LCD_printf(\ //LCD_ChangeMode(DspGraMode); OSStart(); // start the OS // // never reached // return 0; }//main ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Task1(void *Id) { for(;;){ BSPprintf(0,\ if(ac_key == TRUE) { ac_key = FALSE; for(i=0;i LCDBufferII2[j][i] = RED; } } LCD_Refresh(); ac_key = TRUE; } OSTimeDly(1000); } } void Task2(void *Id) { for(;;){ BSPprintf(0,\ if(ac_key == TRUE) - 17 - 北京航空航天大学研究生实验报告 { ac_key = FALSE; for(i=0;i LCDBufferII2[j][i] = GREEN; } } LCD_Refresh(); ac_key = TRUE; } OSTimeDly(2000); } } void Task3(void *Id) { /*char txmsg; MboxSem = OSMboxCreate((void *)0); txmsg = 'A';*/ for(;;){ //OSMboxPost(MboxSem, (void *)&txmsg); //BSPprintf(0,\ if(ac_key == TRUE) { ac_key = FALSE; for(i=0;i LCDBufferII2[j][i] = BLUE; } } LCD_Refresh(); ac_key = TRUE; } OSTimeDly(5000); } } void Task4(void *Id) { - 18 - 北京航空航天大学研究生实验报告 //char *rxmsg; // INT8U err; for(;;){ // rxmsg = (char *)OSMboxPend(MboxSem, 0, &err); //BSPprintf(0,\ err=Uart_Getchn(c,0,0); //从串口采集数据 Uart_SendByten(0, *c); Uart_SendByten(0,0xa);//换行 Uart_SendByten(0,0xd);//回车 //OSTimeDly(1000); } } void Uart_SendByten(int Uartnum, U8 data)//ok eric rong { //int i; if(Uartnum==0) { while(!(rUTRSTAT0 & 0x4)); //Wait until THR is empty. hudelay(10); WrUTXH0(data); } } char Uart_Getchn(char* Revdata, int Uartnum, int timeout) { while(!(rUTRSTAT0 & 0x1)); //Receive data read *Revdata=RdURXH0(); return TRUE; } 八、思考题 1. 如何提高键盘的响应速度? 答:可以设置键盘任务具有较高的优先级,并且任务设置短延时时间。 2. 全局变量 ac_key对共享资源管理有何意义? 答:ac_key的引入有效地保证了进行多个任务时,任务的有效完成,由于进入任务后 - 19 - 北京航空航天大学研究生实验报告 将ac_key置为0,使得其他具有高优先级任务进行时,无法进入任务本身的实际执行,从而等待原任务进行结束后,将ac_key从新置1后,其他任务才能开始执行,本实验中保证了刷屏的顺利进行,使得刷屏结束后才能进行新的任务,解决了完整刷屏的问题。 - 20 - 北京航空航天大学研究生实验报告 实验四 多任务综合实验 一、实验目的 1. 学习周期任务、任务的同步和任务间通信。 二、实验内容 1.运行实验十,删除任务四、任务定义和OSTaskCreate(Task4…),任务三for循环体内仅保留以下两句BSPprintf(0,―run task3\\n‖); OSTimeDly(3000),在超级终端上观察任务运行情况。 2. 使用系统定时中断实现周期任务,任务1 、2、3进入for循环就挂起,在定时钩子函 数中定时1秒、2秒和4秒后将其恢复。 3. 创建信号量管理数组实现任务间同步,在主函数中定义一个INT16U的两维数组 a[2][3],不同的任务往数组内写不同的值,连同任务号一起打印在超级终端上。 4. 创建消息邮箱实现任务间通信,Task1记录任务执行的次数,通过消息邮箱在Task2 里显示。 5. 附加题:文件的使用。 二、 预备知识 1.掌握在EWARM集成开发环境中编写和调试程序的基本过程。 2.了解S3C2410处理器的结构。 3.了解uCOS-II系统结构。 4. 了解多任务的创建,及互斥同步控制。 四、实验设备及工具 硬件:ARM嵌入式开发平台、用于S3C2410的JTAG仿真器、PC机Pentium100以上。 软件:PC机操作系统Win2000或WinXP、EWARM集成开发环境、仿真器驱动程序、 超级终端通讯程序。 五、实验原理及说明 1)同步与互斥 为了实现资源共享,一个操作系统必须提供临界区操作的功能。 μC/OS采用关闭/打开中断的方式来处理临界区代码,从而避免竞争条件,实现任务间的互斥;μC/OS定义两个宏(macros)来开关中断,即:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL();这两个宏的定义取决于所用的微处理器,每种微处理器都有自己的OS_CPU.H文件。 ARM9S3C2410中断的打开与关闭; #define OS_ENTER_CRITICAL() { cpu_sr = INTS_OFF(); } #define OS_EXIT_CRITICAL() { if(cpu_sr == 0) INTS_ON(); } 2)任务间同步:信号量(Semaphores) - 21 - 北京航空航天大学研究生实验报告 a. 信号量在多任务系统中的功能 实现对共享资源的互斥访问(包括单个共享资源或多个相同的资源); 实现任务之间的行为同步; b. 必须在OS_CFG.H中将OS_SEM_EN开关常量置为1,这样μC/OS才能支持信号量。 c. uC/OS中信号量由两部分组成:信号量的计数值(16位无符号整数)和等待该信号量的任务所组成的等待任务表; d. uC/OS中信号量系统服务函数有:OSSemCreate()、OSSemPend(),、OSSemPost()、OSSemAccept()、OSSemQuery()。 3)任务间通信:消息邮箱(MailBox) a.邮箱(MailBox):一个任务或ISR可以通过邮箱向另一个任务发送一个指针型的变量,该指针指向一个包含了特定―消息‖(message)的数据结构; b.必须在OS_CFG.H中将OS_MBOX_EN开关常量置为1,这样μC/OS才能支持邮箱。 c. 邮箱的系统服务函数:OSMboxCreate()、OSMboxPend()、OSMboxPost()、OSMboxAccept()、OSMboxQuery()。 六、实验方法 1. 以实验十为模板。 2. 将任务函数内的OSTimeDly()删除,在打印语句之前悬挂任务1~3, OSTaskSuspend(Taskn_Prio),按以下路径ucos-ii->arch->os_cpu_c.c 找到钩子函数void OSTimeTickHook (void),用计数器控制恢复任务操作,编写OSTaskResume( Taskn_Prio); 3. 信号量管理 声明信号量OS_EVENT *Fun_Semp; 在Main函数里创建信号量Fun_Semp=OSSemCreate(1); 在各个Task里执行下列操作 OSSemPend(Fun_Semp,0,&err); …………. OSSemPost(Fun_Semp); 4 . 定义事件控制块指针OS_EVENT *Str_Box, 在main函数里创建消息邮箱,Str_Box=OSMboxCreate((void*) 在Task1里发送消息 Times+=1; s=&Times; OSMboxPost(Str_Box,s); 在Task2里请求消息邮箱ss=OSMboxPend(Str_Box,0,&err);printf(\ 5. 文件的使用.文件使用的关键是加载文本文件,用记事本创建 test.txt文件,文件的内容不包含汉字。运行实验十三,此时LCD上没有任何显示。打开超级终端,按回车键,显示/sys> 用mkdir创建ucos子目录,在ucos下再创建fj子目录,用cd进入/sys/ucos/fj> ,在该目录下执行命令dl test.txt –d,按回车键,加载test.txt 。再运行文件十三,在LCD上即可观察你编写的文本文件。 七、程序源代码 #include\ /* uC/OS interface */ #include \#include \ #include \#include \#include - 22 - 北京航空航天大学研究生实验报告 #include //#pragma import(__use_no_semihosting_swi) // ensure no functions that use semihosting OS_EVENT *MboxSem; OS_EVENT *Fun_Semp; OS_EVENT *Str_Box; INT8U err; INT16U a[2][3]; INT8U i,j; INT8U Times,*s,*ss; ///******************任务定义***************/// /*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, }; //Main_Test_Task堆栈 void Task1(void *Id); //Main_Test_Task #define Task1_Prio 12 OS_STK task2_Stack[STACKSIZE]={0, }; //test_Test_Task堆栈 void Task2(void *Id); //test_Test_Task #define Task2_Prio 15 OS_STK task3_Stack[STACKSIZE]={0, }; //test_Test_Task堆栈 void Task3(void *Id); //test_Test_Task #define Task3_Prio 17 /**************已经定义的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 ***************************************///////// ///*****************事件定义*****************/// - 23 - 北京航空航天大学研究生实验报告 ///////////////////////////////////////////////////// // Main function. // //////////////////////////////////////////////////// int main(void) { ARMTargetInit(); // do target (uHAL based ARM system) initialisation // OSInit(); // needed by uC/OS-II // Fun_Semp=OSSemCreate(1); Str_Box=OSMboxCreate((void *)0); //OSInitUart(); //initOSFile(); //#if USE_MINIGUI==0 // initOSMessage(); // initOSDC(); // LoadFont(); //#endif //loadsystemParam(); // create the tasks in uC/OS and assign increasing // // priorities to them so that Task3 at the end of // // the pipeline has the highest priority. // //LCD_printf(\ //OSTaskCreate(SYS_Task, (void *)0, (OS_STK *)&SYS_Task_Stack[STACKSIZE-1], SYS_Task_Prio); OSTaskCreate(Task1, (void *)0, (OS_STK *)&task1_Stack[STACKSIZE-1], Task1_Prio); OSTaskCreate(Task2, (void *)0, (OS_STK *)&task2_Stack[STACKSIZE-1], Task2_Prio); OSTaskCreate(Task3, (void *)0, (OS_STK *)&task3_Stack[STACKSIZE-1], Task3_Prio); OSAddTask_Init(0); BSPprintf(0,\ //LCD_printf(\ //LCD_printf(\ //LCD_ChangeMode(DspGraMode); OSStart(); // start the OS // - 24 - 北京航空航天大学研究生实验报告 Times = 0; // never reached // return 0; }//main ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Task1(void *Id) { for(;;){ OSTaskSuspend(Task1_Prio); OSSemPend(Fun_Semp,0,&err); BSPprintf(0,\ Times+=1; s=&Times; OSMboxPost(Str_Box,s); for(i = 0;i < 2;i++) { for(j = 0;j < 3;j++) {a[i][j] = 1; BSPprintf(0,\ } BSPprintf(0,\ OSSemPost(Fun_Semp); //OSTimeDly(1000); } } void Task2(void *Id) { for(;;){ OSTaskSuspend(Task2_Prio); OSSemPend(Fun_Semp,0,&err); ss=OSMboxPend(Str_Box,0,&err); BSPprintf(0,\ for(i = 0;i < 2;i++) { for(j = 0;j < 3;j++) { a[i][j] = 2; BSPprintf(0,\ - 25 - 北京航空航天大学研究生实验报告 } BSPprintf(0,\ printf(\ //OSTimeDly(3000); OSSemPost(Fun_Semp); } } void Task3(void *Id) { for(;;){ OSTaskSuspend(Task3_Prio); OSSemPend(Fun_Semp,0,&err); BSPprintf(0,\ for(i = 0;i < 2;i++) { for(j = 0;j < 3;j++) {a[i][j] = 3; BSPprintf(0,\ } BSPprintf(0,\ //OSTimeDly(3000); OSSemPost(Fun_Semp); } } 创建消息邮箱实现任务间通信,Task1记录任务执行的次数,通过消息邮箱在Task2里显示。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Task1(void *Id) { int *s; static int Times=0; for(;;){ OSTaskSuspend(Task1_Prio); //OSSemPend(Fun_Semp,0,&err); BSPprintf(0,\Times+=1; s=&Times; OSMboxPost(Str_Box,s); //OSSemPost(Fun_Semp); } } void Task2(void *Id) { for(;;){ - 26 - 北京航空航天大学研究生实验报告 } OSTaskSuspend(Task2_Prio); //OSSemPend(Fun_Semp,0,&err); BSPprintf(0,\ ss=OSMboxPend(Str_Box,0,&err); BSPprintf(0,\//OSSemPost(Fun_Semp); } Hook函数调用代码: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OSTimeTickHook (void) { static int i=0; switch(i) { case 1000: OSTaskResume(12); break; case 2000: OSTaskResume(12);OSTaskResume(15); break; case 3000: OSTaskResume(12); break; case 4000: OSTaskResume(12);OSTaskResume(15);OSTaskResume(17); i=-1; break; } i++; } 八、思考题 1. 用钩子函数实现周期任务有何特点? 答:钩子函数是由系统每隔1ms自动调用一次,从而通过合理使用钩子函数可以保证时间的周期性任务的完成。 2. 用信号量是如何实现任务间同步的? 答:信号量的同步主要是通过OSSemCreate()、OSSemPend()和OSSemPost()三个函数来完成的。首先创建一个信号量,从空闲事件控制块链表中得到一个ECB,初始化ECB,包括设置信号量的初始值、把等待任务列表清零、设置ECB的事件类型等,然后返回一个指向该事件控制块的指针。如果信号量的计数值大于0,将它减1并返回,如果信号量的值等于0,则调用本函数的任务将被阻塞起来,等待另一个任务把它唤醒,调用OSSched()函数,调度下一个最高优先级的任务运行。最后,检查是否有任务在等待该信号量,如果没有,将信号量的计数值加1并返回;如果有,将优先级最高的任务从等待任务列表中删除,并使它进入就绪状态,调用 OSSched(),判断是否需要进行任务切换。 3. 简述消息邮箱实现任务间通信的过程。 - 27 - 北京航空航天大学研究生实验报告 答:消息邮箱实现任务间通信主要通过以下函数过程进行的: a.OSMboxCreate():创建一个邮箱;在创建邮箱时,须分配一个ECB,并使用其中的字段OSEventPtr指针来存放消息的地址; b. OSMboxPend():等待一个邮箱中的消息;若邮箱为满,将其内容(某消息的地址)返回;若邮箱为空,当前任务将被阻塞,直到邮箱中有了消息或等待超时; c. OSMboxPost():发送一个消息到邮箱中;如果有任务在等待该消息,将其中的最高优先级任务从等待列表中删除,变为就绪状态; d.OSMboxAccept():无等待地请求邮箱消息;若邮箱为满,返回它的当前内容;若邮箱为空,返回空指针; 4. 简述文件加载到FLASH过程。 答:文件加载到FLASH过程如下: a. 用记事本创建test.txt文件,文件的内容不包含汉字。 b. 打开超级终端,按回车键,显示/sys>时,使用mkdir命令创建文件要存放的目录。 c. 使用cd命令进入存放文件的目录。 d. 在该目录下执行命令:dl test.txt –d。 e. 在超级终端下选择已经创建好的文件test.txt,发送到FLASH中。 - 28 -
正在阅读:
北航ARM9实验报告04-12
圆的基本性质12-14
DB2数据库日志调整12-29
C++实训时钟显示系统12-21
2012年节日节点04-11
篮球运球教学设计102-29
会计干货之水煮SAP从SAP组织架构看企业经营分析06-26
浅谈如何使小学英语教学面向全体05-11
复杂形状零部件转动惯量测试方法研究04-20
空运CCA01-26
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 北航
- 实验
- 报告
- ARM9
- 毕业设计(施工部分)华远实验中学办公楼设计
- 从獐子岛事件谈存货监盘
- 2018年牛津深圳版初中英语七年级下册Unit4 Save the trees单元测
- 现代汉语复习提纲 - 图文
- 单面连接单角钢的理解和计算
- 甘肃省张掖市2015年高三4月诊断考试理综物理试卷
- 巴林银行倒闭案例分析
- 关注一年级,为成长领航
- 第03次作业 - 顺序结构答案
- 高效农业节水灌溉项目可行性研究报告
- 液压与气动课程设计说明书
- 证券分公司2013年一季度合规工作报告
- 关于印发《东莞市农业龙头企业申报认定与监测管理办法》的通知
- 农业综合开发土地治理中低产田改造施工组织设计
- HP各种机型面板信息汇总
- 山西太原学化妆学费大概要多少钱?
- 计算机组成原理实验十
- 浅论初中数学单元复习课教学设计-2019年教育文档
- 银行承兑汇票复习题
- 河南宜阳二叠系孙家沟组沉积环境分析 - 图文