嵌入式课程设计实验报告计算器.docx
《嵌入式课程设计实验报告计算器.docx》由会员分享,可在线阅读,更多相关《嵌入式课程设计实验报告计算器.docx(17页珍藏版)》请在冰点文库上搜索。
嵌入式课程设计实验报告计算器
华南师范大学嵌入式综设实验报告
选题:
基于ARM和UCOS-II系统的小型计算器指导老师:
王剑x
组员(学号):
(20122302xxx)(20122302xxx)
、实现功能实现五位整数的加减乘除带括号的运算,由于实验箱的键盘数量有限,于是我们将键盘设置为虚拟的两层结构,其使用方法如下:
1)第一层键盘使用指南
1
2
3
(
4
5
6
)
7
8
9
第二层
0
第一层
=
2)第二层键盘使用指南
+
%
-
*
/
二、系统流程图
N
计算原理
计算原理定义一个操作数栈sym,一个操作符栈um。
思想是:
置操作数栈为空,操作符栈压入元素"#"(它具有最高优先级),依次读入表达式中的每个字符CH,如果CH是操作数,则CH压入操作数栈,如果CH是操作符,那么将CH和操作符栈顶元素进行优先级比较(如‘×'优先级高于‘+')。
如果优先级大于当前栈顶元素,那么将其压栈,如果其优先级小于当前栈顶元素,那么执行op=sym.pop();(取当前栈顶操作符),a=um.pop()(取
当前栈顶操作数存入临时变量a);b=sym.pop()(取当前栈顶操作数存入临时变量b);c=计算(aop
b);sym.push(c);
如果优先级相等,则当前操作符出栈。
重复上述操作直到表达式处理完毕。
最后操作数栈剩余的操作数就是计算的最终结果。
三、程序
#include
#include
#include
"Includes.h"
"option.h"
"2410lib.h"
/*uC/OSinterface*/
#include
"uhal.h"
/*任务栈*/
OS_STKStackLED[STACKSIZE]={0,};任//务LED任务栈
OS_STKStackSEG[STACKSIZE]={0,};任//务SEG任务栈
/*任务ID*/
charIdLED='1';//任务LEDID
charIdSEG='2';//任务SEGID
/*任务处理函数*/
voidTaskLED(void*Id);//任务LED任务处理函数
voidTaskSEG(void*Id);//任务SEG任务处理函数
voidTmrFunc1(INT8Uarg);
/*定时器1*/
OS_TMR*Tmr1;
charch,ch2;
charprint_1[1];
charprint_2[6];/*用于串口输出*/
intPage=0;/*键盘的页面标志*/
/*栈定义*/#ifndefSTACK_SIZE
#defineSTACK_SIZE64
#endifintNum[STACK_SIZE];/*数字栈*/
intNumTop=0;
intSym[STACK_SIZE];/*字符栈,用来储存操作符*/
intSymTop=0;
voidPush_(int*stack,int*top,intval);
intPop_(int*stack,int*top);
/*声明*/
#defineDELAYTIME1
externunsignedcharseg7table[16];
intCalculate(intright,intleft,intsymbol);
#defineDELAYTIME1
voidproduct(void);
inta,b,c;
charnumber[255];
charsign;
intnow=0;
intnum=0;
intSymTmp;/*对操作符处理时的中间变量*/
intResTmp;/*得数的中间变量*/
intFlag=0;/*表示数字不为空的标识符*/
intcount=0;
/*
*跑马灯闪烁函数,调用一次,四个跑马灯由亮变灭或者由灭变亮
*/
voidUser_LED_Blink(void)
{
staticintled_status=0;
led_status+=1;
if(led_status%2==0)
Led_Display(0x0f);
else
Led_Display(0x00);
}
/*
*数码管显示实验,由0到F依次显示
*/
voidUser_SEG_Blink(void)
{
staticunsignedcharseg_value[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc0,0xdf};
staticintseg_status=0;
//
count++;
seg_status+=1;
//
//
}
if(seg_status>15)
seg_status=0;
/*
*定时器Tmr1、Tmr2、Tmr3处理函数
*1、根据arg参数确定定时器
*2、三个定时器同时只打开一个,即Tmr1、Tmr2、Tmr3,三个定时器总和闪烁一次跑马
灯
*/
voidTmrFunc1(INT8Uarg)
{
ch=Key_GetKey();
ch2=ch;
switch(ch)
{
case'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(ch2=='E'||ch2=='B'||ch2=='.')
print_1[0]='\0';
elseprint_1[0]=ch2;
uHALr_printf(print_1);
product();
/*
*任务LED任务处理函数
*1、OSStart调用之前创建的最高优先级任务,在该函数重启动时钟节拍定时器
*2、创建三个定时器,定时时间都为2秒钟,它们使用同样的TmrFunc1定时器服务函数,
但是使用不同的参数,定时器1的初始状态为开,其余为关
*/
voidTaskLED(void*Id)
{
charkey_press;
charled_status=0x0;
INT8Uerr;
/*启动时钟节拍定时器,开始多任务调度*/
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、每隔100ticks即1000ms,闪烁数码管
*/
voidTaskSEG(void*Id)
{
//uHALr_printf("Task2()called\n");
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
*/
voidMain(void)
{
/*
*目标系统初始化
*/
ARMTargetInit();
/*
*uC/OS-II软件初始化
*/
OSInit();
/*
*创建两个任务,TaskLED和TaskSEG,TaskLED的优先级为5,TaskSEG的优先级为13,TaskLED的优先级高于TaskSEG
*/
OSTaskCreate(TaskLED(,void*)&IdLED,(OS_STK*)&StackLED[STACKSIZE-1],5);
OSTaskCreate(TaskSEG(,void*)&IdSEG,(OS_STK*)&StackSEG[STACKSIZE-1],13);
/*
*启动多任务调度
*/
OSStart();
/*
*正常情况下,永远不会执行到这里
*/
return;
voidproduct(void)
{
if(ch2>='0'&&ch2<='9')
{
num=(num*10)+(ch2-'0');
Flag=1;
}
elseif(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')':
//对‘)'的处理(右括号)
while(SymTop!
=0&&(SymTmp=Pop_(Sym,&SymTop))!
='(')
{
ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),SymTmp);
Push_(Num,&NumTop,ResTmp);
}
break;
case'+':
//对‘+(加号)'的处理
if(SymTop!
=0&&Sym[SymTop-1]!
='(')
{
&SymTop));
ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,
Push_(Num,&NumTop,ResTmp);
}
Push_(Sym,&SymTop,'+');
break;
case'-':
//对‘-(减号)'的处理
if(SymTop!
=0&&Sym[SymTop-1]!
='(')
{
ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,
&SymTop));
Push_(Num,&NumTop,ResTmp);
}
Push_(Sym,&SymTop,'-');
break;
case'*':
//对‘*(乘号)'的处理
if(SymTop!
=0&&Sym[SymTop-1]!
='('&&Sym[SymTop-1]!
='+')
{
&SymTop));
ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,
Push_(Num,&NumTop,ResTmp);
}
Push_(Sym,&SymTop,'*');
break;
case'/':
//对‘/(除号)'的处理
if(SymTop!
=0&&Sym[SymTop-1]!
='('&&Sym[SymTop-1]!
='+')
{
&SymTop));
ResTmp=Calculate(Pop_(Num,&NumTop),Pop_(Num,&NumTop),Pop_(Sym,
Push_(Num,&NumTop,ResTmp);
}
Push_(Sym,&SymTop,'/');
break;
case'%':
//对‘(取余)'的处理
if(SymTop!
=0&&Sym[SymTop-1]!
='('&&Sym[SymTop-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,ResTmp);
}
}
num=Pop_(Num,&NumTop);
if(num<0)
{print_2[0]='-';num=-num;}
elseprint_2[0]='+';
print_2[1]=num/10000+'0';
print_2[2]=num%10000/1000+'0';
print_2[3]=num%1000/100+'0';
print_2[4]=num%100/10+'0';
print_2[5]=num%10+'0';
uHALr_printf("\nResult=");
num);
uHALr_printf(print_2);//uHALr_printf("Result=%d",sprintf(print_buf,"Task%c()turned\n",*(char*)Id);(void*)&IdLED
NumTop=0;
SymTop=0;
num=0;
uHALr_printf("\n");
break;
}
}
//display(num);
intCalculate(intright,intleft,intsymbol)
intresult=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;
}
returnresult;
}
/*栈处理*/
voidPush_(int*stack,int*top,intval)
{
if(*top==STACK_SIZE)
return;
stack[(*top)++]=val;
}
intPop_(int*stack,int*top)
{
if(*top==0)
return-1;
returnstack[--(*top)];