实验五预习报告
基于 UCOSII 的小型 GUI 的应用程序实验
指导老师:万露 学生:张晓辉 16203125
一、实验目的
1. 掌握 UCOSII 操作系统下编写应用程序的基础方法
二、实验内容
1. 在移植好的 UCOSII 项目中添加串口,LCD,键盘,的驱动程序
2.学习在 UCOSII 下,多应用任务的简单编程实例
三、实验设备
1.
2.
EL-ARM-860+教学实验箱,PentiumII 以上的 PC 机,仿真调试电缆,串口直连电缆
PC 操作系统 WIN98 或 WIN2000 或 WINXP,ADS1.2 集成开发环境,
仿真调试驱动程序。
四、实验原理
实验器材介绍:1.本实验使用实验教学系统的 CPU 板,液晶显示器(LCD),4X4
键盘,串口直连电缆。在 LCD 下方,有一个可调电阻。在 LCD 右下方,有一个黄色的按键,
用于开关 LCD,在进行本实验时、AD 通道选择开关、LCD 电源开关、音频的左右声道开关、
触摸屏中断选择开关等均应处在关闭状态。
2.在 PC 机并口和实验箱的 CPU 板上的 JTAG 接口之间,连接仿真调试电缆,以及串口
间连接公/母接头串口线。
UCOSII 系统介绍: uC/OS II(Micro Control Operation System Two)是一个可以基于
ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理
器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。μC/OS-II 已经移
植到了几乎所有知名的 CPU 上。严格地说 uC/OS-II 只是一个实时操作系统内核,它仅仅包
含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提
供输入输出管理,文件系统,网络等额外的服务。但由于 uC/OS-II 良好的可扩展性和源码
开放,这些非必须的功能完全可以由用户自己根据需要分别实现。
https://blog.csdn.net/overflyme/article/details/51434336
实验要求:设计基于 uCOSII 的多任务综合应用
1 按键任务:捕获上、下、左、右、回车四个按键
2 绘图任务:显示上、下、左、右、回车四个矩形按键框,当相应按键捕获后应用不同
颜色显示激活按键;
3 串口任务:当捕获回车按键后串口输出当前激活按键的值如"Left Button Pressed!"等
六.实验原理准备
主函数:
void Main(void)
{
Target_Init();
GUI_Init();
OSInit();
// ARMII 实验系统的初始化,包括 CPU 板
// 操作系统的初始化
Key_Mbox = OSMboxCreate((void *)0);
OSTaskCreate(Task_1,
(void *)0,
(OS_STK *)&Stack_Task_1[STACKSIZE - 1], 5);
//创建任务一
OSStart();
}
************************************************************************************************
*************
- 函数名称 : Task_START
- 函数说明 : 系统启动后运行的第一个任务
- 输入参数 : pdata
- 输出参数 : 无
************************************************************************************************
*************
*/
void Task_1(void *pdata)
{
INT8U err;
INT8U *Key_P;
INT8U Key_Val;
Timer1_Init();
OSTaskCreate(Task_2, (void *)0, (OS_STK *)&Stack_Task_2[(STACKSIZE) - 1], 9);
//打开时钟节拍,让操作系统跑起来
//在
任务里创建另一个任务
OSTaskCreate(Task_3, (void *)0, (OS_STK *)&Stack_Task_3[(STACKSIZE) - 1], 10);
//在
任务里创建另一个任务
OSTaskCreate(Task_4, (void *)0, (OS_STK *)&Stack_Task_4[(STACKSIZE*3) - 1], 56); //在
任务里创建另一个任务
for(;;){
Key_P = OSMboxPend(Key_Mbox, 0, &err); //等待任务间的通信邮箱内的键值指针
Key_Val = *Key_P;
switch(Key_Val){
case 0x06 :
GUI_StoreKey(GUI_KEY_UP);
break;
case 0x04 :
GUI_StoreKey(GUI_KEY_DOWN);
break;
case 0x01 :
GUI_StoreKey(GUI_KEY_RIGHT);
break;
case 0x09 :
GUI_StoreKey(GUI_KEY_LEFT);
break;
case 0x0C :
GUI_StoreKey(GUI_KEY_ESCAPE);
break;
case 0x03 :
GUI_StoreKey(GUI_KEY_START);
break;
case 0x00:
GUI_StoreKey(GUI_KEY_ESCAPE);
send_byte(cmd_reset);/*zjtianjia*/
break;
default:
break;
}
}
Task2:系统启动后运行的第 2 个任务,,点亮 LED1 熄灭 LED2,优先级为 5
OSTimeDly(30);
if(flag==0){
for(i=0;i<100000;i++);
rGPGDAT = rGPGDAT&~(0x3<<8)|(0x1<<8);
for(i=0;i<100000;i++);
flag = 1;
}else{
for(i=0;i<100000;i++);
rGPGDAT = rGPGDAT&~(0x3<<8)|(0x2<<8);
for(i=0;i<100000;i++);
flag = 0;
}
OSTimeDly(30);
Task3:向串口发送数据
if(key_number!=0xff)
{
//延时 30 个节拍
Uart_Printf("key_number=%x\n",key_number); //任务的干得活儿就是向超
级终端发送内容
if(key_number==0x00){
switch(key){
case 0x06:
Uart_Printf("up button pressed!\n");break;
case 0x04:
Uart_Printf("down button pressed!\n");break;
case 0x09:
Uart_Printf("left button pressed!\n");break;
case 0x01:
Uart_Printf("right button pressed!\n");break;
}
}
key=key_number;
key_number=0xff;
OSTimeDly(30);
延时 100 个节拍
}
Task4:GUI 任务,优先级为 56
case GUI_KEY_START:
// 得到开始命令
Set_Color(GUI_BLUE);
Fill_Rect(0,0,639,479);
Set_Color(GUI_WHITE);
Set_BkColor (GUI_BLUE);
Fill_Rect(0,0,639,2);
Fill_Rect(0,0,2,479);
Fill_Rect(0,477,639,479);
Fill_Rect(6377,0,639,479);
//
Set_Color(GUI_YELLOW);
Set_Font
Disp_String (CN_start" 这 是 一 个 多 任 务 显 示 的 例 程
(&CHINESE_FONT16);
"CN_end,50,30);
Set_Color(GUI_RED);
Fill_Rect (320, 100, 360, 130);//上
//Set_Color(GUI_YELLOW);
Fill_Rect(320, 380, 360, 410);//下
// Set_Color(GUI_GREEN);
Fill_Rect(150, 240, 190, 270);//左
// Set_Color(GUI_GREEN);
Fill_Rect(490, 240, 530, 270);//右
Loop = FALSE;
number = 0;
break;
default:
// 等待主任务发送的键值
命令
number = GUI_WaitKey();
Loop = TRUE;
break;
}
}while(Loop==TRUE);
do{
switch (number){
//选择上面的灯
case GUI_KEY_UP:
Set_Color(GUI_RED);
Fill_Rect (320, 100, 360, 130); //上
Set_Color(GUI_YELLOW);
Set_Font(&CHINESE_FONT16);
Disp_String (CN_start"上"CN_end,330,105);
Set_Color(GUI_GRAY);
Fill_Rect(320, 380, 360, 410);//下
Fill_Rect(150, 240, 190, 270);//左
Fill_Rect(490, 240, 530, 270);//右
Loop = TRUE;
number = 0;
flag = 1;
break;
case GUI_KEY_DOWN:
Set_Color(GUI_RED);
Fill_Rect(320, 380, 360, 410);//下
Set_Color(GUI_YELLOW);
Set_Font(&CHINESE_FONT16);
Disp_String (CN_start"下"CN_end,330,385);
Set_Color(GUI_GRAY);
Fill_Rect(320, 100, 360, 130);//上
Fill_Rect(150, 240, 190, 270);//左
Fill_Rect(490, 240, 530, 270);//右
Loop = TRUE;
number = 0;
flag = 2;
break;
case GUI_KEY_RIGHT:
Set_Color(GUI_RED);
Fill_Rect(490, 240, 530, 270);//右
Set_Color(GUI_YELLOW);
Set_Font(&CHINESE_FONT16);
//选择下面的灯
//选择右面的灯
Disp_String (CN_start"右"CN_end,500,245);
Set_Color(GUI_GRAY);
Fill_Rect(320, 100, 360, 130);//上
Fill_Rect(320, 380, 360, 410);//下
Fill_Rect(150, 240, 190, 270);//左
Loop = TRUE;
number = 0;
flag = 3;
break;
case GUI_KEY_LEFT:
//选择左面的灯
Set_Color(GUI_RED);
Fill_Rect(150, 240, 190, 270);//左
Set_Color(GUI_YELLOW);
Set_Font(&CHINESE_FONT16);
Disp_String (CN_start"左"CN_end,160,245);
Set_Color(GUI_GRAY);
Fill_Rect(490, 240, 530, 270);//右
Fill_Rect(320, 100, 360, 130);//上
Fill_Rect(320, 380, 360, 410);//下
Loop = TRUE;
number = 0;
flag = 4;
break;
case GUI_KEY_ESCAPE:
Set_Color(GUI_BLUE);
Fill_Rect(0,0,639,479);
Set_Color(GUI_WHITE);
Fill_Rect(0,0,639,2);
Fill_Rect(0,0,2,479);
Fill_Rect(0,477,639,479);
Fill_Rect(637,0,639,479);
Loop = FALSE;
number = 0;
break;
// 得到退出命令
case GUI_KEY_ENTER:
结束