大神,求51单片机做简易计算器的那个c语言程序
希望能帮助你!!
1、硬件仿真图
硬件部分比较简单,当键盘按键按下时它的那一行、那一列的端口为低电平。因此,只要扫描行、列端口是否都为低电平就可以确定是哪个键被按下。
2、主程序流程图
程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。将操作数分别转化为字符串存储,操作符存储为字符形式。然后调用compute()函数进行计算并返回结果。具体程序及看注释还有流程图。
3、Altium Designer画的PCB图
4、程序源代码
#include #include
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar operand1[9], operand2[9];
uchar operator;
void delay(uint);
uchar keyscan();
void disp(void);
void buf(uint value);
uint compute(uint va1,uint va2,uchar optor);
uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xff};
uchar dbuf[8] = {10,10,10,10,10,10,10,10};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar keyscan()
{
uchar skey;
P1 = 0xfe;
while((P1 & 0xf0) != 0xf0)
{
delay(3);
while((P1 & 0xf0) != 0xf0)
{
switch(P1)
{
case 0xee: skey = '7'; break;
case 0xde: skey = '8'; break;
case 0xbe: skey = '9'; break;
case 0x7e: skey = '/'; break;
default: skey = '#';
}
while((P1 & 0xf0) != 0xf0)
;
}
}
P1 = 0xfd;
while((P1 & 0xf0) != 0xf0)
{
delay(3);
while((P1 & 0xf0) != 0xf0)
{
switch(P1)
{
case 0xed: skey = '4'; break;
case 0xdd: skey = '5'; break;
case 0xbd: skey = '6'; break;
case 0x7d: skey = '*'; break;
default: skey = '#';
}
while((P1 & 0xf0) != 0xf0)
;
}
}
P1 = 0xfb;
while((P1 & 0xf0) != 0xf0)
{
delay(3);
while((P1 & 0xf0) != 0xf0)
{
switch(P1)
{
case 0xeb: skey = '1'; break;
case 0xdb: skey = '2'; break;
case 0xbb: skey = '3'; break;
case 0x7b: skey = '-'; break;
default: skey = '#';
}
while((P1 & 0xf0) != 0xf0)
;
}
}
P1 = 0xf7;
while((P1 & 0xf0) != 0xf0)
{
delay(3);
while((P1 & 0xf0) != 0xf0)
{
switch(P1)
{
case 0xe7: skey = '$'; break;
case 0xd7: skey = '0'; break;
case 0xb7: skey = '='; break;
case 0x77: skey = '+'; break;
default: skey = '#';
}
while((P1 & 0xf0) != 0xf0)
;
}
}
return skey;
}
void main()
{
uint value1, value2, value;
uchar ckey, cut1 = 0, cut2 = 0;
uchar operator;
uchar i, bool = 0;
init:
buf(0);
disp();
value = 0;
cut1 = cut2 = 0;
bool = 0;
for(i = 0;i < 9;i++)
{
operand1[i] = '\0';
operand2[i] = '\0';
}
while(1)
{
ckey = keyscan();
if(ckey != '#')
{
if(isdigit(ckey))
{
switch(bool)
{
case 0:
operand1[cut1] = ckey;
operand1[cut1+1] = '\0';
value1 = atoi(operand1);
cut1++;
buf(value1);
disp();
break;
case 1:
operand2[cut2] = ckey;
operand2[cut2+1] = '\0';
value2 = atoi(operand2);
cut2++;
buf(value2);
disp();
break;
default: break;
}
}
else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/')
{
bool = 1;
operator = ckey;
buf(0);
dbuf[7] = 10;
disp();
}
else if(ckey == '=')
{
value = compute(value1,value2,operator);
buf(value);
disp();
while(1)
{
ckey = keyscan();
if(ckey == '$')
goto init;
else
{
buf(value);
disp();
}
}
}
else if(ckey == '$')
{ goto init;}
}
disp();
}
}
uint compute(uint va1,uint va2,uchar optor)
{
uint value;
switch(optor)
{
case '+' : value = va1+va2; break;
case '-' : value = va1-va2; break;
case '*' : value = va1*va2; break;
case '/' : value = va1/va2; break;
default : break;
}
return value;
}
void buf(uint val)
{
uchar i;
if(val == 0)
{
dbuf[7] = 0;
i = 6;
}
else
for(i = 7; val > 0; i--)
{
dbuf[i] = val % 10;
val /= 10;
}
for( ; i > 0; i--)
dbuf[i] = 10;
}
void disp(void)
{
uchar bsel, n;
bsel=0x01;
for(n=0;n<8;n++)
{
P2=bsel;
P0=table[dbuf[n]];
bsel=_crol_(bsel,1);
delay(3);
P0=0xff;
}
}
扩展资料:
PROTEUS 是单片机课堂教学的先进助手
PROTEUS不仅可将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。前者可在相当程度上得到实物演示实验的效果,后者则是实物演示实验难以达到的效果。
它的元器件、连接线路等却和传统的单片机实验硬件高度对应。这在相当程度上替代了传统的单片机实验教学的功能,例:元器件选择、电路连接、电路检测、电路修改、软件调试、运行结果等。
课程设计、毕业设计是学生走向就业的重要实践环节。由于PROTEUS提供了实验室无法相比的大量的元器件库,提供了修改电路设计的灵活性、提供了实验室在数量、质量上难以相比的虚拟仪器、仪表,因而也提供了培养学生实践精神、创造精神的平台
随着科技的发展,“计算机仿真技术”已成为许多设计部门重要的前期设计手段。它具有设计灵活,结果、过程的统一的特点。可使设计时间大为缩短、耗资大为减少,也可降低工程制造的风险。相信在单片机开发应用中PROTEUS也能茯得愈来愈广泛的应用。
使用Proteus 软件进行单片机系统仿真设计,是虚拟仿真技术和计算机多媒体技术相结合的综合运用,有利于培养学生的电路设计能力及仿真软件的操作能力;
在单片机课程设计和全国大学生电子设计竞赛中,我们使用 Proteus 开发环境对学生进行培训,在不需要硬件投入的条件下,学生普遍反映,对单片机的学习比单纯学习书本知识更容易接受,更容易提高。
实践证明,在使用 Proteus 进行系统仿真开发成功之后再进行实际制作,能极大提高单片机系统设计效率。因此,Proteus 有较高的推广利用价值。
参考资料来源:百度百科-protues
//4*4键盘检测程序,按下键后相应的代码显示在液晶屏上
//显示5位后,第6次显示操作符号
//再显示下一个数
// 键值与功能对应表
//键值 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零
#include<reg52.h>
sbit beep=P2^3;
sbit lcden=P3^4;
sbit rs=P3^5;
sbit rw=P3^6;
#define uint unsigned int
#define ulint unsigned long int
#define uchar unsigned char
#define lcddata P0
ulint bb,dd,ee,ff;
uchar d,flag1;
uchar fd1,fd2;
uchar b1=16,b2=16,b3=16,b4=16,b5=16;
uchar d1=16,d2=16,d3=16,d4=16,d5=16;
uchar f1=16,f2=16,f3=16,f4=16,f5=16,f6=16,f7=16,f8=16,f9=16,f10=16;
uchar key,keyval,c,temp;
void Delay1ms(uint i) //1ms延时程序
{
uint j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void write_com(uchar com)
{
lcddata=com;
rs=0;
rw = 0;
lcden=0;
Delay1ms(10);
lcden=1;
Delay1ms(10);
lcden=0;
}
void write_date(uchar date)
{
lcddata=date;
rs=1;
rw=0;
lcden=0;
Delay1ms(10);
lcden=1;
Delay1ms(10);
lcden=0;
}
void init2()
{
rw=0;
write_com(0x38);
Delay1ms(10);
write_com(0x0f);
Delay1ms(10);
write_com(0x06);
Delay1ms(10);
write_com(0x01);
Delay1ms(10);
}
void display1(uchar A1,uchar A2,uchar A3,uchar A4,uchar A5) //第1个数显示程序
{
init2();
write_com(0x80);//第1行,第1字
Delay1ms(10);
write_date(0x30+A1);
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);
}
void display2(uchar A1,uchar A2,uchar A3,uchar A4,uchar A5) //第2个数显示程序
{
write_com(0x88);//第1行,第1字
Delay1ms(10);
write_date(0x30+A1);
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);
}
void display3(uchar a) //操作符号显示程序
{
write_com(0x86);//第1行,第1字
Delay1ms(10);
switch(a)
{
case 10:
write_date('+');
Delay1ms(10);
case 11:
write_date('-');
Delay1ms(10);
case 12:
write_date('x');
Delay1ms(10);
case 13:
write_date('/');
Delay1ms(10);
}
}
void display4(uchar A1,uchar A2,uchar A3,uchar A4,uchar A5,uchar A6,uchar A7,uchar A8,uchar A9,uchar A10,uchar A11,uchar A12) //结果显示程序
{
write_com(0x80+0x40);//第2行,第1字
Delay1ms(10);
if (flag1==0)
{
write_date('-');
}
else write_date('+');
Delay1ms(10);
write_date(0x30+A1);
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);
write_date(0x30+A6);
Delay1ms(10);
write_date(0x30+A7);
Delay1ms(10);
write_date(0x30+A8);
Delay1ms(10);
write_date(0x30+A9);
Delay1ms(10);
write_date(0x30+A10);
Delay1ms(10);
write_date('.');
Delay1ms(10);
write_date(0x30+A11);
Delay1ms(10);
write_date(0x30+A12);
Delay1ms(10);
}
uchar keyscan()
{
key=16;
P3=0xef;//P3.7输出1个低电平
temp=P3; //读取
temp=temp&0x0f;//屏蔽高4位
if(temp!=0x0f)
{
Delay1ms(10);
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xee:
key=0;
break;
case 0xed:
key=4;
break;
case 0xeb:
key=8;
break;
case 0xe7:
key=12;
break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
beep=0;
}
beep=1;
}
}
P3=0xdf;
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
Delay1ms(10);
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xde:
key=1;
break;
case 0xdd:
key=5;
break;
case 0xdb:
key=9;
break;
case 0xd7:
key=13;
break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
beep=0;
}
beep=1;
}
}
P3=0xbf;
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
Delay1ms(10);
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0xbe:
key=2;
break;
case 0xbd:
key=6;
break;
case 0xbb:
key=10;
break;
case 0xb7:
key=14;
break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
beep=0;
}
beep=1;
}
}
P3=0x7f;
temp=P3;
temp=temp&0x0f;
if(temp!=0x0f)
{
Delay1ms(10);
if(temp!=0x0f)
{
temp=P3;
switch(temp)
{
case 0x7e:
key=3;
break;
case 0x7d:
key=7;
break;
case 0x7b:
key=11;
break;
case 0x77:
key=15;
break;
}
while(temp!=0x0f)
{
temp=P3;
temp=temp&0x0f;
beep=0;
}
beep=1;
}
}
return(key);
}
void main()
{ while(1)
{
c=1;
while(c<6)//输入第1个5 位数
{
keyval=keyscan();
if(keyval<10)
{
switch(c)
{
case 1:b1=keyval; break;
case 2:b2=keyval; break;
case 3:b3=keyval; break;
case 4:b4=keyval; break;
case 5:b5=keyval; break;
}
c++;
}
display1(b1,b2,b3,b4,b5);
}
while(c==6) //输入计算符号
{
keyval=keyscan();
if((keyval>=10)&&(keyval<14)) //可去一层括号,因逻辑运算优先级较低
{
d=keyval;
}
c=1;
display3(d);
}
while(c<6) //输入第2个5 位数
{
keyval=keyscan();
if(keyval<10)
{
switch(c)
{
case 1:d1=keyval; break;
case 2:d2=keyval; break;
case 3:d3=keyval; break;
case 4:d4=keyval; break;// 除
case 5:d5=keyval; break;
}
c++;
}
display2(d1,d2,d3,d4,d5);
}
bb= b1*10000+b2*1000+b3*100+b4*10+b5;
dd=d1*10000+d1*1000+d3*100+d4*10+d5;
while(keyval!=14) //等待按下"="
{
keyval=keyscan();
}
Delay1ms(10);
switch(d)
{
case 10:ee=bb+dd; break;//+
case 11:
flag1=1;
if(bb>=dd)
{
ee=bb-dd; //-
flag1=0;
}
else ee=dd-bb;
break;
case 12:ee=bb*dd; break;//*可能会溢出
case 13:ee=bb/dd; //除法小数部分会丢失,保留2位
ff=bb%dd;
fd1=ff*10/dd;
fd2=ff*100/dd%10;
break;
}
f10=ee/1000000000%10;
f9=ee/100000000%10;
f8=ee/10000000%10;
f7=ee/1000000%10;
f6=ee/100000%10;
f5=ee/10000%10;
f4=ee/1000%10;
f3=ee/100%10;
f2=ee/10%10;
f1=ee%10;
display4(f10,f9,f8,f7,f6,f4,f4,f3,f2,f1,fd1,fd2);
while(keyval!=15)
{
keyval=keyscan();
}
b1=0;b2=0;b3=0;b4=0;b5=0;
d1=0;d2=0;d3=0;d4=0;d5=0;
bb=0;dd=0;ee=0;
init2();
}
}
大神,求51单片机做简易计算器的那个c语言程序
\/\/4*4键盘检测程序,按下键后相应的代码显示在液晶屏上 \/\/显示5位后,第6次显示操作符号 \/\/再显示下一个数 \/\/ 键值与功能对应表 \/\/键值 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \/\/功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零 include<reg52.h> sbit beep...
求单片机大神帮忙设计一个电路,51单片机制作led呼吸灯的
proteus仿真按理来说是不可能达得到效果的,因为这种仿真得有非常快的处理速度。我刚动手试了下和自己的想法相同,LED只会间断的闪烁。我是用AVR单片机,用51也是一样的。我这个程序也在实物试过效果很好。演示定时器1的快速PWM输出@利用快速PWM输出控制LED的亮度变化,达到呼吸灯的效果*\/ include<iom8...
用51单片机写一个程序,求大神
1、使用定时器0方式二,结合软件计数器来实现秒信号的产生;2、定时器必须使用中断的方式来实现;3、使用单片机开发板上的左边四位来扫描显示时间,显示格式为“MM.SS”;4、开机时显示00.00,最大值显示到59.59(59分59秒);5、第一次按电路板上K1(P3.2)键启动走时,K1必须使用中断方式实现...
求51单片机大神帮忙看看一小段代码
XBYTE[0xE000] = 0xff; 是指向地址为0xE000的外部端口输出数据 0xff 同样 XBYTE[0xC000] = (1<<dspcom);是指向地址为0xC000的外部端口输出数据 数据是1左移dspcom位,若dspcom=0 则数据为1 即0000 0001 若dspcom=2 则数据为2 即0000 0010 若dspcom=3 则数据为4 即0000 0100 ...
求大神编一道51单片机实现多种倒计时功能
include <reg51.h> \/\/51单片机通用头文件 unsigned int i,t,h; char fe;sbit a=P3^7; sbit b=P3^6; sbit led=P2^7; sbit lad=P2^6;\/\/按键及LED端口定义 char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};\/\/数码管显示编码 \/***\/ void YS(char ...
51单片机智能小车制作,求通俗易懂的讲解
系统的单片机程序:include"reg52.h"definedet_Dist2.55\/\/ 单个脉冲对应的小车行走距离,其值为车轮周长 \/4#defineRD9\/\/ 小车对角轴长度。definePI3.1415926 defineANG_9090 defineANG_90_T102 defineANG_180189\/ 全局变量定义区。\/sbitP10=P1^0;\/\/ 控制继电器的开闭sbitP11=P1^1;\/\/ 控制金属...
速求51单片机大神帮忙
这个程序主要是考验对定时器的使用,PWM频率是1KHZ,定时时间最长是1s\/1000=1ms,在这1ms的时间内改变P1.0的状态,每次改变10%,就是改变1ms\/10=100us的时间,当占空比超过100时可以考虑关闭定时器,直接使P1.0输出高电平,低于0时,方法一样,直接输出低电平,至于显示你采用的是数码管可以做个段...
51单片机最小系统由什么组成,求大神讲解
51单片机共有40只引脚.下面这个就是最小系统原理图,就是靠这四个部分,这个单片机就可以运行起来了.我们来一,一讲解一下:1 第一部分:电源组(标记为1的部分)40脚接电源5V(右上角),20脚接电源负极(左下角),在单片机里面,负极也可以叫GND或者”地”,我们在单片机的应用中,习惯说负极为”...
求大神解答,用51单片机汇编语言实现一个红绿灯的程序,不是一个路口的...
;某一方向道路拥挤时,可以人工控制调节东西南北方向通行时间。;紧急情况时,各路口交通灯显示红灯,数码管保持数据不变。;工作寄存器及存储单元分配 ;1.工作寄存器 ;R2设置为定时器定时中断次数,R6、R7用于延时程序中的寄存器 ;2.片内存储单元 ;30H、31H作为两组数码管显示数据存储单元;32H、33H作为...
请51单片机大神教我第三题的完整程序!
MOV DPTR, #0FF7CH ;PA 接口地址 MOV A, #30H ;3.的段码 MOVX @DPTR, A INC DPTR ;PB 接口地址 MOV A, #80H MOVX @DPTR, A INC DPTR ;PC 接口地址 MOV A, #92H MOVX @DPTR, A END
淡晶乌鸡: /QQ 296750363 按键...
吉安县19627906145: 利用51单片机制作LCM显示的简单计算器程序 C的 - ?
淡晶乌鸡: 楼主,我给你一个代码,你参考一下和验证一下! 用51单片机做的简单计算器的程序./**********************按键处理*******************/void KeyDeal(unsigned char Key){ if(Key!=0) //判断 有无按键按下.{switch(Key) { //以下定义0~9的数字...
吉安县19627906145: 怎么利用51单片机做一个简单计算器? - ?
淡晶乌鸡: 你是要程序?自己写吧,又不难,用C语言写+、-、*、%不就可以,用lcd1602显示就行
吉安县19627906145: 求51单片机,用1602lcd显示的简易计算器的程序.除了加减乘除,还要有开平方和平方的 - ?
淡晶乌鸡: 电路图:把8位数据线接到单独一个P*口上,其他CS,RS,WR,RD分别接到另一个数据口上,再就是电源和地接上.程序:需要你提供IC型号的,不同的IC指令不同
吉安县19627906145: 用51单片机实现一个简单计算器的功能?
淡晶乌鸡: 下面是我以前用来显示9999秒倒计时的原程序,仅供学习,版权所有,侵权不究. #include <REGX51.H> #include <./stdint.h> #include <ABSACC.H> #include<AT89X51.H> #include <INTRINS.H> //------------------------------ #define TH_10MS (...
吉安县19627906145: 单片机制作简易计算器需要哪些器件 - ?
淡晶乌鸡: 电路不难,主要是程序比较难. 一个矩阵键盘,LCD1602液晶比较好点(用数据管比较麻烦,特别是动态扫描),其它没有什么,主要是运算,可以加个蜂鸣器 我有一个STM32开发板上用的2.4寸触摸液晶一个例程就是计算器,看了下程序比较难.
吉安县19627906145: 求基于AT89C51单片机简易计算器设计的程序,请帮帮忙,谢谢. - ?
淡晶乌鸡: 这个是我原来点的1602驱动.你对照看看,判忙,发数据,发命令函数是不是一样的. 你的程序我没具体看.你尝试在某些命令后加上延时试看. 还有第二行的地址是40H开头的. /************************************************************************...
吉安县19627906145: 51单片机做简易计算器 - ?
淡晶乌鸡: hex就是十六进制的代码 你完全可以用代码转换写成汇编啊 或者直接反汇编做成bin文件
吉安县19627906145: 给予51单片机的简单计算器怎么让它在按键按下的时候 - ?
淡晶乌鸡: 这是我做的一个简易计算器.十位数的加减乘除.#include#define uchar unsigned char; uchar LED1,LED2,LED3,LED4; uchar keyval,calflag,s_dat,d_dat; uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x...
吉安县19627906145: 我想用51单片机,矩阵键盘,lcd1602写个简易计算器程序?
淡晶乌鸡: C语言的语句可以这样写 #include<stdio.h> void main() { float fxx; unsigned char str[10]; fxx = 12.5; sprintf(str,"%8.2f\n",fxx); //将12.5转换成8.2(2位小数)格式以ASCII方式存储到str字符串中 .......... } 由于1620液晶模块支持ASCII码,所以只要将str中的内容送到1602就行了.至于1602的操作我就不写了(其实我也没用过,但知道怎么用,应该不难)