如何用51单片机做计算器(要求用C语言编程) 由于是新手所以没积分 对不住各位了

作者&投稿:乜骆 (若有异议请与网页底部的电邮联系)
大神,求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
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();
}
}

首先,你的原理图没有问题的。
你可以设置几个缓冲区(也就是变量),分别放几个输入的数,例如输入的第一个数,第二个数结果等等但是一定要注意这个缓冲区的位宽。有了这些存放数据的“容器”再对这些数进行加减乘除运算就简单多了。还有一点,尽管在C语言里有运算乘除的操作符,但是我不建议你用这些,你最好用移位运算来代替。
在编程上我建议你用模块化编程(也就是若干个子函数),例如分成显示模块,运算模块,键盘检测模块等等。一个一个地调,上一个模块调好了之后再调另一个模块。如果你不这么做的话很可能到最后你自己都找不到头绪!呵呵....加油!这个不难的.....

给你参考一下的,我最近做的:

我的实验板上的键不够,所以只能做加法运算,而且两数之和不能大于十。

嘿嘿,没错这个给某种人用的。

//********** myh.h ***********有两个文件,一个是头文件myh.h一个是js.c

#include <reg52.h>

typedef unsigned char uchar;

typedef unsigned int  uint;

typedef bit BOOL;

//**

sbit rs=P2^6;

sbit rw=P2^5;

sbit e=P2^7;

//**

uchar Key_Down(void);//返回0到12的键盘的编码

void delay(uchar);//延时

void Init(void);

void Write_Cmd(uchar);

void Write_Data(uchar);

BOOL If_Busy();

//**

uchar code Lcd_tab[]="0123456789+=";

uchar code Key_tab[]={0xb7,0xbb,0xbd,0xbe,0xd7,0xdb,0xdd,0xde,0xe7,0xeb,0xed,0xee};

//**********

uint Q0;

uint Q1;

uint Q2;

//*************js.c********

 

#include "myh.h"

//**************

void main()

{uchar m_key; 

uchar m_inc=0;

Init();

Write_Cmd(0x80);

while(1)

{  Q1=0;

   Q0=0;

   Q2=0;

   

 m_key=Key_Down();

 Write_Cmd(0x01);

 Write_Data(Lcd_tab[m_key]);

 Q0=m_key;

   

 m_key=Key_Down();

 Write_Data(Lcd_tab[m_key]);

       

 m_key=Key_Down();

 Write_Data(Lcd_tab[m_key]);

 Q1=m_key;

       

 m_key=Key_Down();

 Write_Data(Lcd_tab[m_key]);

 Q2=Q0+Q1;

 Write_Data(Lcd_tab[Q2]);

     

 

  

   

}

}

//************************

uchar Key_Down(void)

{uchar Key_number=0;

  uchar m_cx;

  uchar m_cy;

  uchar m_cxy;

  P3=0x0f;

  m_cx=P3;

  while(1)

  {if(m_cx!=0x0f)

    {delay(500);

     m_cx=P3;

     if(m_cx!=0x0f)

  break; }  

 else {P3=0x0f;m_cx=P3;}

  }

  P3=0x0f;

  m_cx=P3&0x0f;

  P3=0xf0;

  m_cy=P3&0xf0;

  m_cxy=m_cx|m_cy;

for(Key_number=0;Key_number<12;Key_number++)

{if(m_cxy==Key_tab[Key_number])

   break;

}

return Key_number;}

//**********

void delay(uchar time)

{uchar j;

for(;time>0;time--)

for(j=0;j<200;j++);

}

//**************

void init()

{ delay(10);

  Write_Cmd(0x38);

  delay(10);

  Write_Cmd(0x38);

  delay(10);

  Write_Cmd(0x38);

  delay(10);

  Write_Cmd(0x0c);

  delay(10);

  Write_Cmd(0x06);

  delay(10);

  Write_Cmd(0x01);

}

//***********

void Write_Cmd(uchar cmd)

{//while(If_Busy());

 e=0;

 rw=0;

 rs=0;

 delay(4);

 P0=cmd;

 delay(4);

 e=1;

 delay(10);

 e=0;

}

//***

void Write_Data(uchar dat)

{//while(If_Busy());

 e=0;

 rw=0;

 rs=1;

 delay(4);

 P0=dat;

 delay(4);

 e=1;

 delay(10);

 e=0;

}

//**

BOOL If_Busy()

{

  BOOL result;

  rw=1;

  rs=0;

  e=1;

  delay(4);

  result=(BOOL)(P2&0x80);

  e=0;

  return result;

}



关键还是要先有硬件方案,也就是方框图,之后是详细电路图,最后才能谈到写程序。关键点有如下几点:一、要设计单片机最小系统,包括复位、晶振、EA接高电平(不许外扩存储器)。二、要有键盘,对应软件为判键程序。推荐用4×4行列式键盘。三、要有显示单元,新手推荐你用数码管(用164串转并做),或是用1602液晶做显示(更容易些)。对应软件部分是显示函数。以上三点是硬件方案,最后数学计算可以用C写,不复杂。总体来说,判键是难点。因为你首先要输入数据进入单片机;输入的数据进行相应的数学运算;再把结果显示到液晶中去。

首先准备一块最小系统版 就是板子都做好了了 件都焊上了的那种
再准备一个伟福仿真器 使用配套的C语言 就可以了
最小系统版一般会配套示例程序给你 分为C语言 和汇编2个版本
你参考下C语言版本 只关注下键盘扫描(那个键盘)和显示(一般是8段管)2部分的程序就可以了
C语言中实现计算不难。
程序就不给你了 因为硬件系统不一样 地址都不同 给你也作用不大

需要的功能有:键盘扫描,以及显示。
主要是配合硬件。51自带有数学运算符,可直接调用,如果没有时,可自己定义一些函数实现此功能。


以51单片机为基体 用C语言设计一个计数器 要求显示数据8位 有复位功 ...
(cnt[6]==pre_cnt[6])&&(cnt[7]==pre_cnt[7])) 若计数值等于预置值 out_flag=1; 输出标志置1 else out_flag=0; 否则输出标志置0 === if(out_flag)drv=0; 若输出标志为1,输出端(P3.4)置0,驱动光耦U2 else drv=1; 否则输出端(P3.4)置1 } 输出控制子程序结束 void main...

如何用单片机做一个简单的倒计时器
51单片机实现数码管99秒倒计时,其实很简单,就是使用定时器中断来实现。目的就是学习怎样用单片机实现倒计时,从而实现一些延时控制类的东西,99秒只是一个例子,你完全可以做出任意倒计时如10秒倒计时程序。定时器定时时间计算公式:初值X=M(最大计时)-计数值。初值,换算成十六进制,高位给TH0,低位...

51单片机做9999秒倒计时怎么原理图怎么做啊还要程序
include<reg51.h>#include "intrins.h"#include "absacc.h"#define uchar unsigned charuchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff};\/\/0-9unsigned char sec=0,dat=0,scanled;unsigned char key=0,mode,time; unsigned char disdat[4];...

想用51单片机编个倒计时的c程序,要求用两位数码管显示分钟的,并用一...
你这数码管的1、2口就这么悬着或者接dp一起了真的没问题吗……全局变量2个用于表示个位和十位,显示的时候可以省点力不用每次计算个位十位。然后一个全局变量代表秒 编程的话,首先是按键响应中断,控制某个全局变量flag的值,三种状态:正常、暂停、到时间。按键可以在前两种之间切换,如果已经是第...

51单片机制作简易数字频率计程序
这里有一个四位数码管的频率计,供参考 include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; \/\/所需的段的位码\/\/uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; \/\/位的控制端(开发板)uc...

利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开...
共阳数码管中断程序:include<reg52.h> define uint unsigned int define uchar unsigned char uchar code table[]= { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uint num,a;uchar bai,shi,ge;void init();void delay(uint);void ...

时钟频率为12MHZ, 如何利用51单片机定时\/计数器定时500ms
我说一下原理 12MHZ的51单片机,定时器最大只能定时65.535ms,所以要定时500ms的时间,需要产生10次50ms的定时。步骤如下:1、每隔50ms定时器中断溢出,计数+1。2、当计数达到10次时,便产生了500ms的定时啦,然后,你自己根据你的设计,需要让单片机做什么就自己写些什么(比如让某个io口取反)3...

用51单片机连接max7219芯片做秒计时器,求帮看下程序
include <reg51.h>#include <intrins.h>#define uchar unsigned charsbitpinDIN= P3^0;\/\/DIN 串行数据输入端口。在时钟上升沿时数据被载入内部的16位寄存器。sbitpinLOAD= P3^1;\/\/LOAD (MAX7219) 载入数据。连续数据的后16位在LOAD端的上升沿时被锁定。sbitpinCLK= P3^2;\/\/在时钟的上升沿, ...

51单片机的数字频率计
      由P3.4输入信号,低电平有效,触发T0外部中断。当T0触发中断的时候执行的程序。这里只进行了一个操作,t0++。所以,t0的值表示触发了几次中断,也就表示接受到的脉冲几次从0到65536。所以会有t0*65536。 另外,由于计时的机制是THO++、TL0++,所以,THOTL0就表示当前的计...

我想用51单片机做一个篮球计时器24秒倒计时,用数码管显示,求各位高手帮 ...
include "reg51.h"define uchar unsigned char uchar display_code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};uchar display_data[8]={0,0,0,0,0,0,0,0};uchar time[]={0,0,0};void delay(void){ uchar i;for(i=250;i...

延寿县17838912064: 利用51单片机制作LCM显示的简单计算器程序 C的 -
毓肩愈美: 楼主,我给你一个代码,你参考一下和验证一下! 用51单片机做的简单计算器的程序./**********************按键处理*******************/void KeyDeal(unsigned char Key){ if(Key!=0) //判断 有无按键按下.{switch(Key) { //以下定义0~9的数字...

延寿县17838912064: 求一个用51单片机结合数码管和举证键盘做的一个C语言的计算器 不用有小数点 只要普通加减乘除四则运 -
毓肩愈美: 用51单片机结合数码管和距阵键盘做一个计算器,用proteus仿真来做比较容易实现,还有一个现成的计算器用的矩阵按键,正好有+ - * ÷ 四个按键,很漂亮.再用一个8位一体的共阴数码管显示,就是一个不错的计算器.仿真图如下.

延寿县17838912064: 51单片机C语言编程,简易计算器,复位键如何编程会简单些?要求能随时返回主程序开头..
毓肩愈美: 提供个思路 void (*RecallBp)(void); main() { 保存堆栈指针 clear: RecallBp=(void*) &amp;clear; 恢复堆栈指针 初始化 ........ } 需要返回时 调用 RecallBp();

延寿县17838912064: 51单片机1602显示屏简易计算器c语言代码 -
毓肩愈美: 1,首先得有个矩阵键盘 2,然后焊好线写好驱动 3,实现内部算法,顶多加减乘除4种了 4,1602显示响应 一步一步做吧,说起来不难,做起来是很烦的哦

延寿县17838912064: 怎么利用51单片机做一个简单计算器? -
毓肩愈美: 你是要程序?自己写吧,又不难,用C语言写+、-、*、%不就可以,用lcd1602显示就行

延寿县17838912064: 基于51单片机的简易计数器设计,求c语言程序! -
毓肩愈美: #include<reg51.h>#define uchar unsigned char uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//0-9 unsigned char sec=0,scanled; unsigned char disdat[2]; sbit key1=P1^0; sbit key2=P1^1; sbit key3=P1^2; void ...

延寿县17838912064: 用c语言编写一个计数器(单片机为51型,数码管为共阴)要求有三个按键分别控制停止、加、减 -
毓肩愈美: 一看到你说是计数器,又看到你要求有停止功能,意思是把Timer改为计数器,然后可以通过一个键停止计数对吧?如果这样的话挺简单的,51单片机的计数器io口记得好像是P3^0和P3^1,但不管怎么,首先设置TMOD,将C/T位置1,这就改为计数器了,然后可以编写函数来对一个变量进行加减;同样利用51单片机的外部中断也可以实现计数功能,打开外部中断开关,在外部中断服务函数对计数变量进行加减;最简单的,直接利用io口高低电平变化来进行计数,编写if函数,只要某个io口电平变化了,就对计数变量进行加减.如果你对这个有点陌生,那么回复我一起讨论或者我可以帮你写程序.希望我的回答能帮助到你.

延寿县17838912064: 用51单片机仿真计数器,用c语言写程序,LCD1602显示,具体要求:按键按下开始计时,按键再次按 -
毓肩愈美: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 ...

延寿县17838912064: 51单片机键盘矩阵实现个位加法计算器,用c编程 -
毓肩愈美: KEYBUF EQU 40H ;键号存放单元 ORG 0000H LJMP MAIN ORG 0030H MAIN: MOV KEYBUF,#0 ;初始键号设位0,也可以为任意值 MOV R0,#30H ;显示首地址 MOV R2,#0CH ;计算数据存放单元个数 CLR A QING: MOV @R0,A ;将数据存放单元清零 INC R0 DJNZ R2,QING MOV P0,#8FH ;关闭显示 MOV R1,#30H ;将显示首地址存放R1里

延寿县17838912064: 用51单片机实现一个简单计算器的功能
毓肩愈美: 下面是我以前用来显示9999秒倒计时的原程序,仅供学习,版权所有,侵权不究. #include <REGX51.H> #include <./stdint.h> #include <ABSACC.H> #include<AT89X51.H> #include <INTRINS.H> //------------------------------ #define TH_10MS (...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网