51单片机实现三位十进制数加减乘除运算
一.题目
51单片机IO接口作业
请将附件给出的Proteus图用51单片机完成一个计算器功能。
1、显示采用动态分时8位共阳数码管输出。
2、采用4*4矩阵键盘输入,键盘上已经标识对应键。
3、完成三位十进制数的加、减、乘、除运算。
4、开机显示最右边数码管显示‘0’,输入按键值后依次左移。"+—*/"数码管显示分别“A B C D”。
按要求上交实验报告(加、减、乘、除的对应的Proteus仿真截图一定要有,下载到开发板图也必须有)。
二.实验思路
程序分为以下几步:
- 数码管显示模块,数码管上显示数字
- 矩阵键盘模块,用户按下按键返回相应的按键值
- 主函数,实现加减乘除运算,偷了点懒,其实加减乘除运算也可以独立出来做成一个模块
三.程序代码
#include<reg52.h>//共阳极数码管
unsigned char code segCodeTable[16] = {0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
//位码表
unsigned char code posCodeTable[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char code key_value[16]={0xD7,0xEB,0xDB,0xBB,0xED,0xDD,0xBD,0xEE,0xDE,0xBE,0x77,0x7B,0x7D,0x7E,
0xB7,0xE7};//键盘标识对应的键盘值
void dis_seg7(unsigned long num,unsigned char dec_hex);
unsigned char keyscan();
void delayms (void);
unsigned char pre_P1;void main()
{unsigned char key0=0,key1=0,key2=0;unsigned char value = 0,j = 0;unsigned char state = 0;unsigned char dec_hex = 10;unsigned int NUMA = 0,NUMB = 0;unsigned long dis_num = 0;while(1){value = keyscan();//if((pre_P1 == 0xf0)&&(P1 != 0xf0))//实现数码管显示多位数字if((pre_P1 == 0xf0)&&(P1 != 0xf0)){if(value >= 0 && value <= 9){dec_hex = 10;key2 = key1;key1 = key0;key0 = value;dis_num = 100*key2 + 10* key1 + key0;}//按下操作符+-*/前,保存数码管显示数字dis_num到NUMA// key0 = 0;key1 = 0;//key2 = 0;dis_num = value;//上述四条语句的目的:按下操作符显示对应的16进制数;//实现数码管的清零,即实现120+150,数码管一次显示120;//A(表示加号);150else if(value>=10&&value<=13){NUMA = dis_num;key0 = 0;key1 = 0;key2 = 0;dis_num = value;dec_hex = 16;if(value == 10 ){state ='+'; }else if(value == 11){state = '-';}else if (value == 12){state = '*';}else if (value == 13){state = '/';}}//按下等号时,保存数码管显示数字dis_num到NUMB,实现计算else if(value == 14){dec_hex = 10;key0 = 0;key1 = 0;key2 = 0;NUMB = dis_num;if(state == '+'){dis_num = NUMA + NUMB;}else if(state == '-'){dis_num = NUMA - NUMB;}else if(state == '*'){dis_num = NUMA * NUMB;}else if(state == '/'){dis_num = NUMA / NUMB;}} //数码管清零else if(value == 15){dec_hex = 10;key0 = 0;key1 = 0;key2 = 0;NUMA = 0;NUMB = 0;dis_num = 0; }}pre_P1 = P1;dis_seg7(dis_num,dec_hex);for(j = 0;j < 200;j++);}
}//七段数码管显示模块
void dis_seg7(unsigned long num,unsigned char dec_hex)
{char i = 0,count = 8;unsigned int j =0;char dis_data = 0;for(i = 0;i < count;i++){dis_data = num % dec_hex;num = num / dec_hex;P2 = segCodeTable[dis_data];P3 = posCodeTable[i];for(j = 0;j < 200;j++);P2 = 0xff; //清除余晖if(num == 0){break;}}
}//延时模块
void delayms (void)
{
unsigned char i;
for (i=200;i>0;i--);
}//按键扫描模块
unsigned char keyscan()
{unsigned char rowscan,colscan,row_col,i;static unsigned char value;P1 = 0xf0; //P1输出 0xf0if((P1&0xf0) != 0xf0) //P1读入数据,判断是否有按键按下{delayms();//延时消抖if((P1&0xf0) != 0xf0){//本代码采用逐行扫描的方式来确定按下的按键rowscan = 0xfe;while((rowscan&0x10)!=0){P1 = rowscan;colscan = P1 & 0xf0;if(colscan != 0xf0){//确定按下按键的行号与列号,查表,返回按键值row_col = colscan | (rowscan&0x0f);for(i = 0;i<16;i++){if(row_col == key_value[i]){value = i;}}break;}else {rowscan = (rowscan << 1) | 0x1;}}}}return value;
}
四.运行结果
1.加法
123 + 456 = 579
2.减法
789 - 123 = 666
3.乘法
100 * 234 = 23400
4.除法
480/160 =3
github下载链接
代码及proteus工程下载