大连理工软件学院嵌入式大作业51单片机计算器报告讲解Word下载.docx
- 文档编号:985590
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:51
- 大小:7.45MB
大连理工软件学院嵌入式大作业51单片机计算器报告讲解Word下载.docx
《大连理工软件学院嵌入式大作业51单片机计算器报告讲解Word下载.docx》由会员分享,可在线阅读,更多相关《大连理工软件学院嵌入式大作业51单片机计算器报告讲解Word下载.docx(51页珍藏版)》请在冰点文库上搜索。
18
总计
学分:
8位十进制整数计算器
实验报告
一、课题任务及要求
1.矩阵键盘功能分配:
S1~S10:
1~9、0
S11:
Backspace
S12:
=
2.独立按键功能分配:
3.其他要求:
1、两个操作数分别显示在两个行里;
2、十进制数的最大为数为8位;
3、运算符号显示在第二行最左边:
开方、整除、倒数、正负用字母A、B、C、D显示;
4、可以退格;
5、连按两次=,清除显示;
二、程序清单
/********************************************************************************
*描述:
*
*矩阵键盘1602液晶显示键值*
*连接方法:
JP8(P1)与JP4(矩阵键盘接口)连接*
*矩阵键盘定义:
*
*P1.1-P1.4为列线,P1.4-P1.7为行线*
*喇叭接P1.5口矩阵键盘P1口,*
*注意:
请将JP165短路冒断开*
*作者:
aaron*
*时间:
2013/6/20至2013/6/23*
********************************************************************************/
#include<
reg52.h>
intrins.h>
math.h>
//公共函数和宏
#defineucharunsignedchar
#defineluintunsignedlong
voiddelay(ucharx);
//延时函数,x是几则代表延时几毫秒
ucharchange(ucharkey);
//把数码转换成ascII码函数
voidhand(uchartem);
//独立按键松手判断
ucharjump();
//数字输入跳出函数,用在输入第一个数字之后,输入符号之前
voidresult(uchar*innum,ucharinlength);
//结果输出函数
luintcom(uchar*innum,ucharlength);
//组合函数,把最开始输入的数组值转换成一个longunsignedint储存起来
ucharresolve(luintinlarnum,uchar*innum);
//拆分函数,把一个longunsignedint转换成最开始输入的数组值储存起来
//1602函数、宏和位
#definedelayNOP();
{_nop_();
_nop_();
};
//用在以下1602函数中延时用
voidlcd_wcmd(ucharcmd);
//写指令数据到LCD
voidlcd_wdat(uchardat);
//写显示数据到LCD
voidlcd_init();
//LCD初始化设定
bitlcd_busy();
//检查LCD忙状态
voidlcd_pos(ucharpos);
//设定显示位置
sbitLCD_RW=P2^5;
sbitLCD_RS=P2^6;
sbitLCD_EN=P2^7;
//矩阵键盘函数
ucharkeydown(void);
//键判断
ucharkeyscan(void);
//键扫描子程序
//voiddelay0(ucharx);
//x*0.14MS不清楚用途!
!
//矩阵与lcd
ucharS1_S12(ucharhang,uchar*num3,uchar*S12_flag);
ucharS12clear(uchar*S12_flag);
//清屏函数
//独立键盘
voidsign_input(ucharsign);
ucharsign_display(uchar*innum,ucharinlength);
//符号显示函数
//显示函数
uchardisplay();
//液晶屏上显示函数
voidmove(uchar*innum,ucharinlength);
//数字位移函数
//检测发光二级管位声明
sbitLED=P2^0;
//运算函数
ucharplus(uchar*innum1,uchar*innum2,ucharinlength1,ucharinlength2);
//加法函数,用大数加法实现
ucharminus(uchar*innum1,uchar*innum2,ucharinlength1,ucharinlength2);
//减法函数
/*最开始不知道longunsignedint可以储存八位,知道之后编写了com和resolve函数,这两个函数简化了后续的一切运算函数*/
/*还有解决ram不够的问题,让我一度绝望,但是最后用单片机以外的ram实现了,真是感觉大作业做的很有提高,遇到了几乎大部分问题,解决了之后真的好开心*/
ucharmulti(uchar*innum1,uchar*innum2,ucharinlength1,ucharinlength2);
/*乘法函数,当时忘记把乘法函数加进来了,又调了20多分钟,真是什么错误都犯啊*/
uchardivision(uchar*innum1,uchar*innum2,ucharinlength1,ucharinlength2);
/*除法函数
ucharsquare(uchar*innum1,ucharinlength1);
//开方函数*/
uchardivided(uchar*innum1,uchar*innum2,ucharinlength1,ucharinlength2);
//整除函数
ucharbottom(uchar*innum1,ucharinlength1);
//倒数函数
ucharne_po(uchar*innum1,ucharinlength1);
//正负函数
#include"
head.h"
/*************************************************************/
/**/
/*主程序*/
/*************************************************************/
main()
{
P0=0xFF;
//置P0口
P1=0xFF;
//置P1口
delay(10);
//延时
lcd_init();
//初始化LCD
while
(1)
{
display();
}
}
/************************************************************/
#include"
//显示数函数
uchardisplay()
//signflag是运算符的代表,length1,length2分别代表输入的第一个数和第二个数的位数
ucharsignflag,length1,length2,S12_flag[1]={0};
/*最终结果是由num1或者num2储存,尽管数最多八位,但是结果可能出现16位,故申请数组时空间为16*/
ucharnum1[16],num2[16];
//第一步,显示并输入第一个数字(可以删可以改)
length1=S1_S12(0x4f,num1,S12_flag);
if(S12clear(S12_flag)==1)//判断S12是否按了两次,用于清屏
lcd_wcmd(0x01);
return0;
S12_flag[0]=0;
//进去之后另算,所以清屏也另算
//第二步,输入符号
signflag=sign_display(num1,length1);
//第三步,进行相应的运算
//K12346这五个独立按键都是两个数的运算,故而放在一块
if(signflag==1||signflag==2||signflag==3||signflag==4||signflag==6)
{
//S12clear(S12_flag,1);
//判断S12是否按了两次,用于清屏
//输入第二个数字
length2=S1_S12(0x4f,num2,S12_flag);
/*在S1_S12函数中现阶段来讲按S12与按K1~K8是有区别的
区别在于按S12之后,S1_S12函数退出,在while
(1)循环中一直到sign_display函数,无法前进而按K1~K8在while
(1)循环中一直到S1_S12函数时无法前进,经过sign_display之后num2的值发生改变,导致第二行的数字被清空*/
if(signflag==1)
//此处为加法运算函数该函数返回运算结果的长度
length1=plus(num1,num2,length1,length2);
if(signflag==2)
//此处为减法运算函数该函数返回运算结果的长度
length1=minus(num1,num2,length1,length2);
if(signflag==3)
length1=multi(num1,num2,length1,length2);
if(signflag==4)
length1=division(num1,num2,length1,length2);
if(signflag==6)
length1=divided(num1,num2,length1,length2);
}
else//都是只需要一位运算数的
if(signflag==5)
length1=square(num1,length1);
if(signflag==7)
length1=bottom(num1,length1);
if(signflag==8)
length1=ne_po(num1,length1);
//此处为结果输出函数
result(num1,length1);
if(S12clear(S12_flag)==1)//判断S12是否按了两次,用于清屏
}
//数字位移函数,用于输入完符号后,最开始输入的数字移到第一行,并且把最后一行消去
voidmove(uchar*innum,ucharinlength)
ucharxdatacount;
for(count=0;
count<
inlength;
count++)
lcd_pos(0x0f-count);
//显示位置设置
lcd_wdat(innum[inlength-count-1]);
//数字显示
//此处inlength+1,多抹一位,为了让类似23/12之后能够把第二行消去
inlength+1;
lcd_pos(0x4f-count);
lcd_wdat(0x20);
/*键扫描子程序(4*3的矩阵)P1.4P1.5P1.6P1.7为行*/
/*P1.1P1.2P1.3为列*/
/**/
ucharkeyscan(void)//
{
uchartem,key;
//第一行矩阵键盘
P1=0xfd;
tem=P1;
tem=tem&
0xf0;
if(tem!
=0xf0)
delay(10);
tem=P1;
tem=tem&
if(tem!
tem=P1;
switch(tem)
{
case0xed:
key=0;
break;
case0xdd:
key=1;
case0xbd:
key=2;
case0x7d:
key=3;
}
/*观察按键是否释放循环,不能在函数最后用一个总的判断是否释放函数
那样的话只有最后一行的数字可以在停止按键后显示数字,其他的按了就显示*/
while(tem!
tem=tem&
//第二行矩阵键盘
P1=0xfb;
case0xeb:
key=4;
case0xdb:
key=5;
case0xbb:
key=6;
case0x7b:
key=7;
=0xf0)//观察按键是否释放循环
//第三行矩阵键盘
P1=0xf7;
case0xe7:
key=8;
case0xd7:
key=9;
case0xb7:
key=10;
case0x77:
key=11;
if(key==10||key==11)//10和11键的功能特殊,不用转换成ASCII码
returnkey;
else
key=change(key);
//用来吧数码转换成ASCII码,该函数在公共函数中
/*判断键是否按下*/
ucharkeydown(void)
{
ucharkey3;
if(key3==0)
key3=0x30;
//key3=0x30是为了让计算器初始化的时候显示0,0x30是0的ASCII码
P1=0xF0;
delay(100);
/*延时函数,确保数字显示在lcd上,不能过长也不能过短,时间过短显示无法再lcd上固定,时间过长按键不流畅*/
if(P1!
=0xF0)//判断按键是否按下如果按钮按下会拉低P1其中的一个端口
key3=keyscan();
returnkey3;
/*检查LCD忙状态*/
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据*/
bitlcd_busy()
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
delayNOP();
result=(bit)(P0&
0x80);
LCD_EN=0;
return(result);
/*******************************************************************/
/*写指令数据到LCD*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/
/*******************************************************************/
voidlcd_wcmd(ucharcmd)
{
while(lcd_busy());
LCD_RW=0;
_nop_();
P0=cmd;
/*写显示数据到LCD*/
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
voidlcd_wdat(uchardat)
LCD_RS=1;
P0=dat;
/*LCD初始化设定*/
voidlcd_init()
delay(15);
lcd_wcmd(0x38);
//16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x0c);
//显示开,关光标
lcd_wcmd(0x06);
//移动光标
lcd_wcmd(0x01);
//清除LCD的显示内容
/*设定显示位置*/
voidlcd_pos(ucharpos)
lcd_wcmd(pos|0x80);
//数据指针=80+地址变量
/*延时子程序*/
voiddelay(ucharx)
{ucharj;
while((x--)!
=0)
{for(j=0;
j<
125;
j++)
{;
ucharchange(ucharkey2)
key2=key2&
0x0f;
if(key2>
9)//转换为ASCII码
key2=key2+0x37;
key2=key2+0x30;
return(key2);
voidhand(uchartem)
while(tem!
=0xff)
tem=P3;
0xff;
ucharjump()
ucharxdatatem,flag=0
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 大连理工 软件 学院 嵌入式 作业 51 单片机 计算器 报告 讲解