1、嵌入式课程设计实验报告计算器华南师范大学嵌入式综设实验报告选题:基于 ARM和 UCOS-II系统的小型计算器 指导老师: 王剑 x组员(学号):( 20122302xxx) (20122302xxx)、实现功能 实现五位整数的加减乘除带括号的运算,由于实验箱的键盘数量有限,于是我们 将键盘设置为虚拟的两层结构,其使用方法如下:1)第一层键盘使用指南123(456)789第二层0第一层=2)第二层键盘使用指南+%-*/二、系统流程图N计算原理计算原理 定义一个操作数栈 sym,一个操作符栈 um 。 思想是:置操作数栈为空,操作符栈压入元素 #( 它具有最高优先级 ),依次读入表达式中的每个字
2、 符 CH,如果 CH是操作数,则 CH压入操作数栈,如果 CH是操作符,那么将 CH 和操作符栈顶元 素进行优先级比较(如优先级高于 )。 如果优先级大于当前栈顶元素,那么将其压栈, 如果其优先级小于当前栈顶元素,那么执行 op=sym.pop();(取当前栈顶操作符) ,a=um.pop() (取当前栈顶操作数存入临时变量 a);b=sym.pop() (取当前栈顶操作数存入临时变量 b) ;c=计算(a opb); sym.push(c);如果优先级相等,则当前操作符出栈。 重复上述操作直到表达式处理完毕。最后操作数栈剩余的操作数就是计算的最终结果。三、程序#include#includ
3、e#includeIncludes.hoption.h2410lib.h/* uC/OS interface */#includeuhal.h/* 任务栈 */OS_STK StackLEDSTACKSIZE= 0, ;任 / 务 LED任务栈OS_STK StackSEGSTACKSIZE= 0, ;任 / 务 SEG任务栈/* 任务ID */char IdLED = 1; / 任务LED IDchar IdSEG = 2; / 任务SEG ID/* 任务处理函数 */void TaskLED(void *Id); / 任务 LED任务处理函数void TaskSEG(void *Id);
4、/ 任务 SEG任务处理函数void TmrFunc1(INT8U arg);/* 定时器 1*/OS_TMR *Tmr1;char ch,ch2;char print_11;char print_2 6; /* 用于串口输出 */int Page=0; /* 键盘的页面标志 */* 栈定义 */ #ifndef STACK_SIZE#define STACK_SIZE 64#endif int NumSTACK_SIZE;/*数字栈 */int NumTop=0;int SymSTACK_SIZE;/*字符栈,用来储存操作符 */int SymTop=0;void Push_(int * s
5、tack,int * top,int val);int Pop_(int * stack,int * top);/* 声明 */#define DELAYTIME 1extern unsigned char seg7table16;int Calculate(int right,int left,int symbol);#define DELAYTIME 1void product(void);int a,b,c;char number255;char sign;int now=0;int num=0;int SymTmp;/* 对操作符处理时的中间变量 */int ResTmp;/* 得数的
6、中间变量 */int Flag = 0;/* 表示数字不为空的标识符 */int count=0;/* 跑马灯闪烁函数,调用一次,四个跑马灯由亮变灭或者由灭变亮*/void User_LED_Blink(void)static int led_status = 0;led_status += 1;if(led_status % 2 = 0)Led_Display(0x0f);elseLed_Display(0x00);/* 数码管显示实验,由 0到 F依次显示*/void User_SEG_Blink(void)static unsigned char seg_value = 0xc0, 0x
7、f9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xc0,0xdf;static int seg_status = 0;/count+;seg_status += 1;/if(seg_status 15)seg_status = 0;/* 定时器 Tmr1、 Tmr2、Tmr3 处理函数* 1 、根据 arg参数确定定时器* 2、三个定时器同时只打开一个,即 Tmr1、Tmr2、Tmr3 ,三个定时器总和闪烁一次跑马灯*/void TmrFunc1(INT8U arg)ch=Key_GetKey();ch2=ch;switch(ch)ca
8、se C:ch2=(;break;case D:ch2=);break;case F:ch2=;break;case A:ch2=.;break;case E:Page=1;Led_Display(0xff);break;case B:Page=0;Led_Display(0x00);break;default:break;if(Page=1)switch(ch)case 1:ch2=+;break;case 4:ch2=-;break;case 7:ch2=*;break;case 0:ch2=/;break;case 2:ch2=%;break;default:ch=0;break;if(
9、ch2=E|ch2=B|ch2=.)print_10=0;else print_10=ch2;uHALr_printf(print_1);product();/* 任务 LED任务处理函数* 1 、OSStart调用之前创建的最高优先级任务,在该函数重启动时钟节拍定时器* 2 、创建三个定时器,定时时间都为 2秒钟,它们使用同样的 TmrFunc1定时器服务函数,但是使用不同的参数,定时器 1的初始状态为开,其余为关*/void TaskLED(void *Id)char key_press;char led_status = 0x0;INT8U err;/* 启动时钟节拍定时器,开始多任务调
10、度 */ARMTargetStart();/* 初始化定时器 */OSTmrInit();/* 创建定时器,定时时间为 2秒钟,它使用 TmrFunc1定时器服务函数, 定时器 1的初始状态为开 */err = OSCreateTimer( &Tmr1, TmrFunc1, 1, 10, OS_TMR_ENABLE);OSEnableTimer(Tmr1);uHALr_printf(n 欢迎使用计算器 n);/* 该任务到此完成,不断延时 */for (;)OSTimeDly(10);/* 任务 SEG任务处理函数* 1、每隔 100 ticks即 1000ms,闪烁数码管*/void Tas
11、kSEG(void *Id)/uHALr_printf(Task2() calledn);for (;)OSSchedLock();OSSchedUnlock();OSTimeDly(1);/* Main 函数 .* 1 、初始化目标系统,初始化硬件定时器等,与操作系统无关* 2、调用 OSInit初始化 uC/OS-II软件数据结构等,必须在打开时钟节拍中断之前调用* 3、创建两个任务, TaskLED和 TaskSEG,TaskLED的优先级为 5, TaskSEG的优先级为 13,TaskLED的优先级高于 TaskSEG* 4 、调用 OSStart启动 uC/OS-II*/void
12、Main(void)/* 目标系统初始化*/ARMTargetInit();/* uC/OS-II 软件初始化*/OSInit();/* 创建两个任务, TaskLED和 TaskSEG,TaskLED的优先级为 5,TaskSEG的优先级为 13,TaskLED 的优先级高于 TaskSEG*/OSTaskCreate(TaskLED(, void *)&IdLED, (OS_STK* )&StackLEDSTACKSIZE- 1, 5);OSTaskCreate(TaskSEG(,v oid *)&IdSEG, (OS_STK* )&StackSEGSTACKSIZE- 1, 13);/*
13、 启动多任务调度*/OSStart();/* 正常情况下,永远不会执行到这里*/return;void product(void)if(ch2=0&ch2=9)num = (num*10)+(ch2-0);Flag = 1;else if(ch2=(|ch2=)|ch2=+|ch2=-|ch2=*|ch2=/|ch2=%|ch2=)if(Flag)Push_(Num,&NumTop,num);num = 0;Flag = 0;switch(ch2)case (: / 对 (的处理 (左括号 )Push_(Sym,&SymTop,();break;case ): / 对 )的处理 (右括号 )w
14、hile(SymTop!=0&(SymTmp=Pop_(Sym,&SymTop)!=()ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),SymTmp);Push_(Num,&NumTop,ResTmp);break;case +: / 对 +(加号)的处理if(SymTop!=0 & SymSymTop-1!=()&SymTop);ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,Push_(Num,&NumTop,ResTmp);Push_(Sym,&SymTo
15、p,+);break;case -: / 对 -(减号)的处理if(SymTop!=0 & SymSymTop-1!=()ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,&SymTop);Push_(Num,&NumTop,ResTmp);Push_(Sym,&SymTop,-);break;case *: / 对 * (乘号)的处理if(SymTop!=0&SymSymTop-1!=(&SymSymTop-1!=+)&SymTop);ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Nu
16、m,&NumTop),Pop_(Sym,Push_(Num,&NumTop,ResTmp);Push_(Sym,&SymTop,*);break;case /: / 对 /(除号)的处理if(SymTop!=0&SymSymTop-1!=(&SymSymTop-1!=+)&SymTop);ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,Push_(Num,&NumTop,ResTmp);Push_(Sym,&SymTop,/);break;case %: / 对(取余)的处理if(SymTop!=0&SymSymTop
17、-1!=(&SymSymTop-1!=+)&SymTop);ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,Push_(Num,&NumTop,ResTmp);Push_(Sym,&SymTop,%);break;case =: / 对 =号处理if(SymTop!=0)while(SymTop!=0&(SymTmp=Pop_(Sym,&SymTop)!=( )ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),SymTmp);Push_(Num,&NumTop,R
18、esTmp);num = Pop_(Num,&NumTop);if(num0)print_20=-;num=-num;else print_20=+;print_21=num/10000+0;print_22=num%10000/1000+0;print_23=num%1000/100+0;print_24=num%100/10+0;print_25=num%10+0;uHALr_printf(nResult= );num);uHALr_printf(print_2);/uHALr_printf(Result= %d, sprintf(print_buf, Task%c() turnedn,
19、*(char *)Id);(void *)&IdLEDNumTop = 0;SymTop = 0;num = 0;uHALr_printf(n);break;/display(num);int Calculate(int right,int left,int symbol)int result = 0;switch(symbol)case +:result = left+right;break;result = left*right;break;case -:result =left-right; break;case /:result = left/right;break;case %:result = left%right;break;return result;/* 栈处理 */void Push_(int * stack,int * top,int val)if(*top = STACK_SIZE)return;stack(*top)+ = val;int Pop_(int * stack,int * top)if(*top=0)return -1;return stack-(*top);
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2