单片机第六份实验报告.docx
《单片机第六份实验报告.docx》由会员分享,可在线阅读,更多相关《单片机第六份实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
单片机第六份实验报告
南昌大学实验报告
学生姓名:
学号:
专业班级:
通信152班
实验类型:
□验证□综合□设计□创新实验日期:
实验成绩:
实验六电子计算器仿真
一、实验目的
掌握计算器基础几类算法的仿真。
二、实验内容
1.10个数字键用作数值输入键,小数点的显示用重复按键的方式设置,即如果某数字键被重按,则该数字带小数点显示。
2.A、B、C、D、E、F六个键用作功能键:
A表示求平方根;B表示求sin;C表示求自然对数lnx;D表示求以10为底的对数logx;E表示求一个数的指数函数exp(x);F表示求以a为底的指数函数。
3.输入数字时,第一个输入的数显示在最左边第一个数码管,第二个输入的数显示在第二个数码管,依次类推。
后边不输的位视为0,可显0也可熄灭。
显示结果时,要求用满8个数码显示管
三、实验程序
主程序:
#include
#include"STC15.h"
#include"intrins.h"
#defineMAIN_Fosc11059200L//定义主时钟
typedefunsignedcharu8;
typedefunsignedintu16;
typedefunsignedlongu32;
#defineTimer0_Reload(65536UL-(MAIN_Fosc/1000))//Timer0中断频率,//1000次/秒
#defineDOT0x20
#defineDIS_BLACK0x10
#defineDIS_0x11
u8codeT_KeyTable[16]={0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};
u8codet_display[]=//标准字库
{
//0123456789ABCDEF
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black-HJKLNoPUtGQrMy
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46
};//0.1.2.3.4.5.6.7.8.9.-1
u8codeT_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位码
sbitP_HC595_SER=P4^0;//pin14SERdatainput
sbitP_HC595_RCLK=P5^4;//pin12RCLkstore(latch)clock
sbitP_HC595_SRCLK=P4^3;//pin11SRCLKShiftdataclock
u8LED8[8];//显示缓冲
u8display_index;//显示位索引
bitB_1ms;//1ms标志
u8KeyCode;//给用户使用的键码,1-16有效
u8cnt10ms;
u8IO_KeyState,IO_KeyState1,IO_KeyHoldCnt;//行列键盘变量
u8cnt50ms;
u8KS;
u8i,Key;
u8B_Key;
voidIO_KeyScan(void);//50mscall
u8TmpH,TmpL,KeyCode;//定义变量
doublea,b,c,d,e,f,g,x,y,x_f,x_i;
u8k0,k1,k2,k3,k4,k5,k6,k7,k8,K_Down,count,B_Dot;
u32xa,y_i;
u8led0,led1,led2,led3,led4,led5,led6,led7;
/**********************延时函数************************/
voidDelay(u8ms)
{
u16i;
do
{
i=MAIN_Fosc/13000;//14Tperloop
while(--i)
{
;
}
}
while(--ms);
}
/**********************矩阵键盘************************/
u8ScanKey(void)
{
P0=0xf0;
if(P0!
=0xf0)//扫描列
{
Delay(10);//延时去抖
if(P0!
=0xf0)//确定按键按下
{
//K_Down=1;
TmpH=P0;//读出P0口高四位数据
P0=0x0F;
Delay
(1);//延时
TmpL=P0;//读出P0口低四位数据
TmpH=TmpH+TmpL;//将取出的高四位,低四位组合,得到键值
while(P0!
=0x0F)
{
;//松手检测
}
switch(TmpH&0xF0)
{
case0xE0:
KeyCode=0;
break;
case0xD0:
KeyCode=4;
break;
case0xB0:
KeyCode=8;
break;
case0x70:
KeyCode=12;
break;
}
switch(TmpL&0x0F)
{
case0x0E:
KeyCode+=0;
break;
case0x0D:
KeyCode+=1;
break;
case0x0B:
KeyCode+=2;
break;
case0x07:
KeyCode+=3;
break;
}
returnKeyCode;//输出键值
}
}
return16;//无按键按下输出16
}
/*****************计算10的n次方***********************/
u32pow10(u8n)
{
switch(n)
{
case0:
return1;
break;
case1:
return10;
break;
case2:
return100;
break;
case3:
return1000;
break;
case4:
return10000;
break;
case5:
return100000;
break;
case6:
return1000000;
break;
case7:
return10000000;
break;
}
}
/*****************在数码管上显示一个8位数***********************/
print(u32n)
{
LED8[0]=n%100000000/10000000;
LED8[1]=n%10000000/1000000;
LED8[2]=n%1000000/100000;
LED8[3]=n%100000/10000;
LED8[4]=n%10000/1000;
LED8[5]=n%1000/100;
LED8[6]=n%100/10;
LED8[7]=n%10/1;
}
voidmain(void)
{
P0M1=0;
P0M0=0;//设置为准双向口
P1M1=0;
P1M0=0;
P2M1=0;
P2M0=0;
P3M1=0;
P3M0=0;
P4M1=0;
P4M0=0;
P5M1=0;
P5M0=0;
P6M1=0;
P6M0=0;
P7M1=0;
P7M0=0;
AUXR=0x80;//Timer0setas1T,16bitstimerauto-reload,
TH0=(u8)(Timer0_Reload/256);
TL0=(u8)(Timer0_Reload%256);
ET0=1;//Timer0interruptenable
TR0=1;//Tiner0run
EA=1;//打开总中断
for(i=0;i<8;i++)
{
LED8[i]=0x10;//上电消隐
}
KeyCode=16;//键码,0-15有效,无按键按下时=16
KS=17;
a=20;//以a为底的指数函数,在这里设置a的值
while
(1)
{
if(B_1ms)
{
B_1ms=0;
if(++cnt50ms>=50)
{
cnt50ms=0;
Key=ScanKey();
if((Key<=9)&(count<=7))
{
if(Key==KS)
{
B_Key=1;
KS=17;
B_Dot=count-1;
LED8[B_Dot]=32+Key;
}
else
{
KS=Key;
LED8[count]=Key;
count++;
}
switch(count)
{
case1:
k0=Key;
break;
case2:
k1=Key;
break;
case3:
k2=Key;
break;
case4:
k3=Key;
break;
case5:
k4=Key;
break;
case6:
k5=Key;
break;
case7:
k6=Key;
break;
case8:
k7=Key;
break;
default:
;
}
}
if((Key<=15)&(Key>=10))
{
if(B_Key==0)
{
B_Dot=count-1;
}
xa=k7+k6*10+k5*100+k4*1000+k3*10000+k2*100000+k1*1000000+k0*10000000;
x=(double)xa/(double)pow10(7-B_Dot);
switch(Key)
{
case10:
y=sqrt(x);
break;
case11:
y=sin(x);
break;
case12:
y=log(x);
break;
case13:
y=log10(x);
break;
case14:
y=exp(x);
break;
case15:
y=pow(a,x);
break;
default:
;
}
if(y>=10000000)
{
y_i=y;
print(y_i);
}
elseif(y>=1000000)
{
y_i=y*10;
print(y_i);
LED8[6]=y_i%100/10+32;
}
elseif(y>=100000)
{
y_i=y*100;
print(y_i);
LED8[5]=y_i%1000/100+32;
}
elseif(y>=10000)
{
y_i=y*1000;
print(y_i);
LED8[4]=y_i%10000/1000+32;
}
elseif(y>=1000)
{
y_i=y*10000;
print(y_i);
LED8[3]=y_i%100000/10000+32;
}
elseif(y>=100)
{
y_i=y*100000;
print(y_i);
LED8[2]=y_i%1000000/100000+32;
}
elseif(y>=10)
{
y_i=y*1000000;
print(y_i);
LED8[1]=y_i%10000000/1000000+32;
}
elseif(y>=1)
{
y_i=y*10000000;
print(y_i);
LED8[0]=y_i%100000000/10000000+32;
}
elseif(y>=0.1)
{
y_i=y*100000000;
LED8[0]=32;
LED8[1]=led0=y_i%100000000/10000000;
LED8[2]=led1=y_i%10000000/1000000;
LED8[3]=led2=y_i%1000000/100000;
LED8[4]=led3=y_i%100000/10000;
LED8[5]=led4=y_i%10000/1000;
LED8[6]=led5=y_i%1000/100;
LED8[7]=led6=y_i%100/10;
}
elseif(y>=0.01)
{
y_i=y*1000000000;
print(y_i);
LED8[0]=32;
LED8[1]=0;
LED8[2]=led0=y_i%100000000/10000000;
LED8[3]=led1=y_i%10000000/1000000;
LED8[4]=led2=y_i%1000000/100000;
LED8[5]=led3=y_i%100000/10000;
LED8[6]=led4=y_i%10000/1000;
LED8[7]=led5=y_i%1000/100;
}
elseif(y>=0.001)
{
y_i=y*10000000000;
LED8[0]=32;
LED8[1]=0;
LED8[2]=0;
LED8[3]=led0=y_i%100000000/10000000;
LED8[4]=led1=y_i%10000000/1000000;
LED8[5]=led2=y_i%1000000/100000;
LED8[6]=led3=y_i%100000/10000;
LED8[7]=led4=y_i%10000/1000;
}
elseif(y>=0.0001)
{
y_i=y*100000000000;
LED8[0]=32;
LED8[1]=0;
LED8[2]=0;
LED8[3]=0;
LED8[4]=led0=y_i%100000000/10000000;
LED8[5]=led1=y_i%10000000/1000000;
LED8[6]=led2=y_i%1000000/100000;
LED8[7]=led3=y_i%100000/10000;
}
elseif(y>=0.00001)
{
y_i=y*1000000000000;
LED8[0]=0;
LED8[1]=0;
LED8[2]=0;
LED8[3]=0;
LED8[4]=0;
LED8[5]=led0=y_i%100000000/10000000;
LED8[6]=led1=y_i%10000000/1000000;
LED8[7]=led2=y_i%1000000/100000;
}
elseif(y>=0.000001)
{
y_i=y*10000000000000;
LED8[0]=0;
LED8[1]=0;
LED8[2]=0;
LED8[3]=0;
LED8[4]=0;
LED8[5]=0;
LED8[6]=led0=y_i%100000000/10000000;
LED8[7]=led1=y_i%10000000/1000000;
}
elseif(y>=0.0000001)
{
y_i=y*100000000000000;
LED8[0]=0;
LED8[1]=0;
LED8[2]=0;
LED8[3]=0;
LED8[4]=0;
LED8[6]=0;
LED8[5]=0;
LED8[7]=led0=y_i%100000000/10000000;
}
else
{
for(i=0;i<8;i++)
{
LED8[i]=0x10;
}
LED8[0]=0;
}
}
}
}
}
}
/****************向HC595发送一个字节函数******************/
voidSend_595(u8dat)
{
u8i;
for(i=0;i<8;i++)
{
dat<<=1;
P_HC595_SER=CY;
P_HC595_SRCLK=1;
P_HC595_SRCLK=0;
}
}
/**********************显示扫描函数************************/
voidDisplayScan(void)
{
Send_595(~T_COM[display_index]);//输出位码
Send_595(t_display[LED8[display_index]]);//输出段码
P_HC595_RCLK=1;
P_HC595_RCLK=0;//锁存输出数据
if(++display_index>=8)
{
display_index=0;//8位结束回0
}
}
/**********************Timer01ms中断函数************************/
voidtimer0(void)interrupt1
{
DisplayScan();//1ms扫描显示一位
B_1ms=1;//1ms标志
}
四、实验原理
通过设定单片机上含有的按键进行数字的定义来达到键入数字运算的目的,而对于功能计算,则是通过定义一部分按键为特定触发按键来调用各类计算方法进行计算。
五、实验总结
通过本次实验,我更加熟悉掌握了软件的使用方法以及对于显示部分的认识。
实验过程中,虽然遇到了很多问题,比如怎么设置功能键进行调用,以及如何用满8个数码管,但在同学的帮助下,参考其他同学的程序,总算是对程序设计有了一定的理解。