51单片机数码管计算器的C程序

是数码管显示的,不要液晶显示的
我就是想要51单片机上的计算器的c程序代码,要在数码管上显示的,功能是:最高可以计算8位数,可完成加减乘除,有小数点功能,最好能显示负数
三楼的兄弟不好意思哦,,,我想要的是C语言程序,不是汇编语言~~~

你再把分加到100分,我给你一个C语言的,带电路图。
;不知和您的硬件电路是否相同,
;不知和2你的单片机型号是否相同

sec_l equ 30h ;30单元存储秒个位值
sec_h equ 31h ;31单元存储秒十位值
bar_2 equ 32h ;32单元存储"-"段码的偏移量
min_l equ 33h ;33单元存储分个位值
min_h equ 34h ;34单元存储分十位值
bar_5 equ 35h ;35单元存储"-"段码的偏移量
hou_l equ 36h ;36单元存储时个位值
hou_h equ 37h ;37单元存储时十位值

sec equ 38h ;38单元为秒计数器(00s-59s)
min equ 39h ;39单元为分计数器(00m-59m)
hou equ 40h ;40单元为时计数器(00h-23h)

cou equ 41h ;41单元为软计数器,对10ms时基信号累加到1s

dis_b equ 42h ;dis_b(42单元)作为位码选通数码管
dis_r equ 43h ;dis_r(43单元)为取段码时的偏移量

key_v equ 44h ;存储键值
key_t equ 45h ;按键扫描中临时存储键值

org 0000h
ajmp start
org 000bh ;定时器0的中断入口地址
ajmp time0 ;跳到定时器0的中断服务程序处
org 001bh ;定时器1的中断入口地址
ajmp time1 ;跳到定时器1的中断服务程序处
org 0030h
start:
mov p2,#0xff ;关所有数码管
mov p1,#0xff ;p1为准双向口,作输入时先写1
mov key_v,#0xff ;初始键值为ff

mov bar_2,#10 ;'-'段码偏移量为10
mov bar_5,#10 ;'-'段码偏移量为10
mov dis_b,#0x7f ;初始选通P2.7口数码管
mov dis_r,#0 ;初始化偏移量为0
mov sec,#0 ;秒计数清零
mov min,#0 ;分计数清零
mov hou,#0 ;时计数清零
mov cou,#0 ;软计数器清零

mov tmod,#00010001b ;定时/计数器0、1工作于方式1
mov th0,#0xd8 ;预置定时常数55536(d8f0),产生10ms时基信号
mov tl0,#0xf0
mov th1,#0xfc ;预置定时常数64536(fc18),产生1ms间隔用于动态显示
mov tl1,#0x18

setb ea ;开总中断
setb et0 ;定时/计数器0允许中断
setb et1 ;定时/计数器1允许中断
setb tr0 ;开定时/计数器0
setb tr1 ;开定时/计数器1

key:
mov a,p1 ;读入键值
mov key_t,a ;存储到临时变量中
xrl a,key_v ;检测键值是否改变
jz key ;未改变则重新扫描
lcall d_10ms ;有键按下则延时10ms消抖
mov a,p1 ;再次读入键值
mov key_t,a ;存入临时变量
xrl a,key_v ;检测键值是否改变
jz key ;未改变则为抖动继续扫描
mov key_v,key_t ;确定为键按下则保存键值
lcall key_to ;调用键处理部分
ajmp key ;循环扫描按键

key_to: ;键处理子程序
mov a,key_v ;读入键值
cjne a,#0xef,next ;不是P1.4口键值则查下一个
ajmp k1 ;是则转去执行该键的处理
next: cjne a,#0xdf,back ;也不是P1.5口键值则结束
ajmp k2 ;是则转去执行该键的处理
k1: mov a,min ;读入分计数器的值
cjne a,#59,k1_add ;分计数值未到59
mov min,#0 ;分钟加到59时则清零
ajmp back ;结束
k1_add: inc min ;分加1
ajmp back ;结束
k2: mov a,hou ;读入时计数器的值
cjne a,#23,k2_add ;时计数值未到23
mov hou,#0 ;时加到23时则清零
ajmp back ;结束
k2_add: inc hou ;时加1
back: ret ;结束
;--------------------------------------------------------------------------------
time0: ;定时器0中断服务程序
push psw ;保护现场
push acc

inc cou ;软计数器加1
mov a,cou ;计数器值送入a
cjne a,#100,over ;未计到100则返回继续计数
mov cou,#0 ;计到100后软计数器清零(到1s)

inc sec ;秒计数器加1(进位10ms*100=1s)
mov a,sec ;秒计数值送入a
cjne a,#60,over ;未计到60则返回继续计数
mov sec,#0 ;计到60后秒计数器清零

inc min ;分计数器加1(进位60s=1m)
mov a,min ;分计数值送入a
cjne a,#60,over ;未计到60则返回继续计数
mov min,#0 ;计到60后分计数器清零

inc hou ;时计数器加1(进位60m=1h)
mov a,hou ;时计数值送入a
cjne a,#24,over ;未计到24则返回继续计数
mov hou,#0 ;计到24后时计数器清零,重新计时

over: mov th0,#0xd8 ;重置定时常数
mov tl0,#0xf0
pop acc ;恢复现场
pop psw
reti ;中断返回
;--------------------------------------------------------------------------------
time1: ;定时器1中断服务程序
push psw ;保护现场
push acc
push b
;以下是秒计数器值个位十位分开
mov a,sec ;秒计数器值送入a(被除数)
mov b,#10 ;除数10送入b
div ab
mov sec_l,b ;余数b(秒个位值)送入秒个位存储单元
mov sec_h,a ;商a(秒十位值)送入秒十位存储单元
;以下是分计数器值个位十位分开
mov a,min ;分计数器值送入a(被除数)
mov b,#10 ;除数10送入b
div ab
mov min_l,b ;余数b(分个位值)送入分个位存储单元
mov min_h,a ;商a(分十位值)送入分十位存储单元
;以下是时计数器值个位十位分开
mov a,hou ;时计数器值送入a(被除数)
mov b,#10 ;除数10送入b
div ab
mov hou_l,b ;余数b(时个位值)送入时个位存储单元
mov hou_h,a ;商a(时十位值)送入时十位存储单元

mov dptr,#table ;数码管段码表首址送入dptr

mov a,#sec_l ;取秒个位值的地址
add a,dis_r ;基址+偏移量
mov r0,a ;R0为欲显示值的地址
mov a,@r0 ;取欲显示值送入a
; dis_r : 0 1 2 3 4 5 6 7
;对应单元: sec_l sec_h bar_2 min_l min_h bar_5 hou_l hou_h
movc a,@a+dptr ;取对应值的段码
mov p0,a ;段码送入P0口
mov p2,dis_b ;位码送入P2口

inc dis_r ;偏移量加1,下次中断时显示下个数
anl dis_r,#0x07 ;dis_r增到8时自动清0(使之在0到7间循环)

mov a,dis_b ;位码循环右移,下次中断时选通下个数码管
rr a
mov dis_b,a

mov th1,#0xfc ;重置定时常数
mov tl1,#0x18

pop b
pop acc ;恢复现场
pop psw
reti

d_10ms: mov r5,#20 ;1+(1+2*255)*20+2*20=10.261ms@12M
temp1: mov r6,#255 ;1+2*255
djnz r6,$
djnz r5,temp1
ret

table: db 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf ;段码表
; 0 1 2 3 4 5 6 7 8 9 - 对应内容
羚羊
end
温馨提示:内容为网友见解,仅供参考
第1个回答  2020-05-15
兄弟,不好意思,我这个程序可以计算8位数,完成加减乘除,没有小数点
、显示负数的功能,只能帮到这了。
#include
<reg51.h>
#include
<absacc.h>
#include
<math.h>
#pragma
NOREGPARMS
#define
g
DBYTE[0x30]
#define
s
DBYTE[0x31]
#define
b
DBYTE[0x32]
#define
q
DBYTE[0x33]
#define
w
DBYTE[0x34]
#define
sw
DBYTE[0x35]
#define
bw
DBYTE[0x36]
#define
qw
DBYTE[0x37]
#define
flag
DBYTE[0x38]
#define
ww
DBYTE[0x39]
#define
var
DBYTE[0x40]
unsigned
long
data
a0
_at_
0x42;
unsigned
long
data
a1
_at_
0x46;
unsigned
long
data
a2
_at_
0x50;
void
count
()
{
unsigned
long
temp;
if(var>=0&&var<=9)
{
if(ww==1)
{
qw=bw=sw=w=q=b=s=g=0;
g=var;
ww=0;
}
else
{
qw=bw;
bw=sw;
sw=w;
w=q;
q=b;
b=s;
s=g;
g=var;
}
}
if(var>=0x0a&&var<=0x0d)
{
a0=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(var==0x0a)flag=1;//加法运算标志
if(var==0x0b)flag=2;//减法运算标志
if(var==0x0c)flag=3;//乘法运算标志
if(var==0x0d)flag=4;//除法运算标志
ww=1;
}
if(var==0x0e)
{
a1=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(flag==1)a2=a1+a0;
if(flag==2)a2=a0-a1;
if(flag==3)a2=a1*a0;
if(flag==4)a2=a0/a1;
g=a2%10;
temp=a2/10;
s=temp%10;
temp=temp/10;
b=temp%10;
temp=temp/10;
q=temp%10;
temp=temp/10;
w=temp%10;
temp=temp/10;
sw=temp%10;
temp=temp/10;
bw=temp%10;
qw=temp/10;
}
if(var==0x0f)
{
qw=bw=sw=w=q=b=s=g=var=flag=0;
}
}
第2个回答  2019-04-23
兄弟,不好意思,我这个程序可以计算8位数,完成加减乘除,没有小数点
、显示负数的功能,只能帮到这了。
#include
<reg51.h>
#include
<absacc.h>
#include
<math.h>
#pragma
NOREGPARMS
#define
g
DBYTE[0x30]
#define
s
DBYTE[0x31]
#define
b
DBYTE[0x32]
#define
q
DBYTE[0x33]
#define
w
DBYTE[0x34]
#define
sw
DBYTE[0x35]
#define
bw
DBYTE[0x36]
#define
qw
DBYTE[0x37]
#define
flag
DBYTE[0x38]
#define
ww
DBYTE[0x39]
#define
var
DBYTE[0x40]
unsigned
long
data
a0
_at_
0x42;
unsigned
long
data
a1
_at_
0x46;
unsigned
long
data
a2
_at_
0x50;
void
count
()
{
unsigned
long
temp;
if(var>=0&&var<=9)
{
if(ww==1)
{
qw=bw=sw=w=q=b=s=g=0;
g=var;
ww=0;
}
else
{
qw=bw;
bw=sw;
sw=w;
w=q;
q=b;
b=s;
s=g;
g=var;
}
}
if(var>=0x0a&&var<=0x0d)
{
a0=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(var==0x0a)flag=1;//加法运算标志
if(var==0x0b)flag=2;//减法运算标志
if(var==0x0c)flag=3;//乘法运算标志
if(var==0x0d)flag=4;//除法运算标志
ww=1;
}
if(var==0x0e)
{
a1=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(flag==1)a2=a1+a0;
if(flag==2)a2=a0-a1;
if(flag==3)a2=a1*a0;
if(flag==4)a2=a0/a1;
g=a2%10;
temp=a2/10;
s=temp%10;
temp=temp/10;
b=temp%10;
temp=temp/10;
q=temp%10;
temp=temp/10;
w=temp%10;
temp=temp/10;
sw=temp%10;
temp=temp/10;
bw=temp%10;
qw=temp/10;
}
if(var==0x0f)
{
qw=bw=sw=w=q=b=s=g=var=flag=0;
}
}
第3个回答  推荐于2016-05-24
兄弟,不好意思,我这个程序可以计算8位数,完成加减乘除,没有小数点
、显示负数的功能,只能帮到这了。

#include <reg51.h>
#include <absacc.h>
#include <math.h>
#pragma NOREGPARMS
#define g DBYTE[0x30]
#define s DBYTE[0x31]
#define b DBYTE[0x32]
#define q DBYTE[0x33]
#define w DBYTE[0x34]
#define sw DBYTE[0x35]
#define bw DBYTE[0x36]
#define qw DBYTE[0x37]
#define flag DBYTE[0x38]
#define ww DBYTE[0x39]
#define var DBYTE[0x40]
unsigned long data a0 _at_ 0x42;
unsigned long data a1 _at_ 0x46;
unsigned long data a2 _at_ 0x50;
void count ()
{
unsigned long temp;
if(var>=0&&var<=9)
{
if(ww==1)
{
qw=bw=sw=w=q=b=s=g=0;
g=var;
ww=0;
}
else
{
qw=bw;
bw=sw;
sw=w;
w=q;
q=b;
b=s;
s=g;
g=var;
}
}
if(var>=0x0a&&var<=0x0d)
{
a0=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(var==0x0a)flag=1;//加法运算标志
if(var==0x0b)flag=2;//减法运算标志
if(var==0x0c)flag=3;//乘法运算标志
if(var==0x0d)flag=4;//除法运算标志
ww=1;
}
if(var==0x0e)
{
a1=qw*10000000+bw*1000000+sw*100000+w*10000+q*1000+b*100+s*10+g;
if(flag==1)a2=a1+a0;
if(flag==2)a2=a0-a1;
if(flag==3)a2=a1*a0;
if(flag==4)a2=a0/a1;
g=a2%10;
temp=a2/10;
s=temp%10;
temp=temp/10;
b=temp%10;
temp=temp/10;
q=temp%10;
temp=temp/10;
w=temp%10;
temp=temp/10;
sw=temp%10;
temp=temp/10;
bw=temp%10;
qw=temp/10;
}
if(var==0x0f)
{
qw=bw=sw=w=q=b=s=g=var=flag=0;
}
}本回答被提问者采纳
第4个回答  2009-07-22
能说得详细点吗?
相似回答