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

作者&投稿:顾颜 (若有异议请与网页底部的电邮联系)
51单片机数码管计算器的C程序(可以显示小数)~

http://download.csdn.net/detail/likang123321/2973621

这是我当年上大学时候写的垃圾代码,不过能用,你自己愁着改改,后来我替人也写过一个,比这个好多了,系统也靠谱,但是找不到了,你凑合着看吧,很多不好的地方,你自己改改

你是不是用2了锁存器啊。
P2=led_table[ten];
led_ten=1;//打开锁存器
led_ten=0;//关闭锁存期

存储10位
P2=led_table[single];
led_single=1;//打开锁存器
led_single=0;//关闭锁存器

存储个位
另外led_ten,led_single 你要先定义一下吧

你再把分加到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

兄弟,不好意思,我这个程序可以计算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;
}
}

兄弟,不好意思,我这个程序可以计算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;
}
}

兄弟,不好意思,我这个程序可以计算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;
}
}

能说得详细点吗?


怎样用单片机控制数码管显示0或者1?
1、LS147优先编码器的输入端和输出端都是低电平有效,即当某一个输入端低电平0时,4个输出端就以低电平0的输出其对应的8421BCD编码。当9个输入全为1时,4个输入出也全为1,代表输入十进制数0的8421BCD编码输出。2、不用单片机,用数字电路实现很容易呀。用一片10线-4线编码器,接10个按键,输...

单片机数码管如何从1显示到9
把 数码管的 1-9 的 对应的码算出来就好了 例如:#include <AT89X51.H>\/\/数字0-9的字形码unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};unsigned char dispcount;void delay02s(void);void main(void){ P1_0=0;\/\/选通第一位数码管 while(...

单片机两个单独的数码管显示数字一个1另一个6
显示“1”,则P0端口得输出七段码为1的数据(是共阴极),P0=0x6;那么显示“6”时,则P2=0x7d;要数码管不亮时,得 P0=P2=0(因为是共阴极数码管);所以;void delaymS(int t){ 自己找个延时程序填进来} \/\/或者用定时器中断定时2秒钟,更精确 main(){ while(1){ P0=0x06;P2=0x7...

单片机C51编程(C语言):1到100的求和显示,在数码管里显示出来.
void convert();void display();void delay();\/\/共阴:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F code unsigned char Led[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};uchar num,sw,gw;void main(){ num=0;while(1){ co...

如何用51单片机用一位数码管显示对应数字?
首先你要把0到9的数字对应的七段码放在一个数组中,然后用一个变量计按键的次数或序号,把该序号的七段码输出到对应的端口即可。

利用数码管和单片机编写1-2-3-4每秒加一的循环程序
SETB P2.3 就是关闭第1个数码管 TABLE为共阳数码管的七段码 ORG 0000H LJMP MAIN;转初始化程序ORG 000BH;定位中断子程序地址 LJMP INTT0ORG 0020HMAIN:MOV A,#0C0H MOV 30H,A;先清0,30H-33H分别存个、十、百、千位的七段码 MOV 31H,A MOV 32H,A MOV 33H,A ;***...

单片机上数码管的位码是怎样计数出来?
位码选择就是对应你的几个(一般是六个或者八个)数码管的哪几个亮,与段码区分开来,至于怎么确定位码就要看你连接位码用的是哪几个io端口了,然后一一对应起来,想点亮那个数码管就改变对应的那一个二进制位的电平就可以了。。。

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

用程序写出单片机数码管在两个数码管上显示数字,从0显示到60,就是1...
2、要选择你的数码管是静态显示,还是动态显示。静态要占用8个I\/O。3、动态显示,全动态还是只是十个位动态。全动态,需要74HC154之类的4线译码管,个十位动态呢,只需要74LS283之类的锁存器,相对来讲后者亮度要是前者的8倍。4、调用数组来显示。。LZ自己应该找点动态显示的文章来研究下,这样的...

如何用单片机实现数码管显示1~7?求程序,和实做原理图。。急!!!_百度...
Time_Delay1ms(1); \/\/数码管的切换时间 viewdate[2]=getdate\/100; \/\/提取变量getdate的百显示编码 getdate=getdate%100;viewdate[1]=getdate\/10; \/\/提取变量getdate的十位显示编码 viewdate[0]=getdate%10; \/\/提取变量getdate的个位显示编码 \/*以上四行程序,用来把一个变量转换...

乌马河区19451683410: 用AT89C51单片机编写一个C语言程序实现2个数码管秒计数器,用4个按键分别控制暂停、加一秒、减一秒和继续 -
聂惠当归: #include<reg51.h>#define uchar unsigned char; uchar LED1,LED2; uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar num=0;sec,key; void delay(unsigned int a) { unsigned int i,j; for(i=0;i<a;i++) for(j=0;j<120;j++); } void ...

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

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

乌马河区19451683410: 求个 51单片机 计数器 程序 -
聂惠当归: #include "reg52.h" #define u8 unsigned char #define u16 unsigned intsbit sw1=P3^4; sbit sw2=P3^5; sbit sw3=P3^6;sbit e0=P2^0; sbit e1=P2^1; sbit e2=P2^2; sbit e3=P2^3;u8 ds[4]={0,0,0,0}; u16 num=0;u8 code table[]={0X3F,0X06,0X5B...

乌马河区19451683410: 51单片机用c语言编写一个程序,数码管显示从10到30,再从30到10. -
聂惠当归: 大概理解你的意思,是在数码管一次排列好这一句话,首先第一步需要做的是数码管的取模工作.#include//这边为了让你看的更容易,用的是单独操作,没有用总线sbitled1=P1^0;sbitled2=P1^1;sbitled3=P1^2;sbitled4=P1^3;sbitled5=P1^4;sbitled6=P1^5;sbitled7=P1^6;//看清楚自己的管脚,不一定对应,这里采用P0对应段选codeunsignedcharled_paly[5]={0x76,0x79,0x38,0x38,0x5c};//HELLOvoiddelay(unsignedintum)//延时函数{inti,j;for(i=0;i

乌马河区19451683410: 怎样用51单片机P3.3口外部电平变化做一个4位数码管显示的计数器?要求用C语言编写 -
聂惠当归: /*p0口接段选,p1口接位选*/#include"reg51.h"#define uchar unsigned char#define uint unsigned int uchar qian,bai,shi,ge; uint num=0; uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管的编码 void ISR(void)//中断...

乌马河区19451683410: 急求用51单片机P3.3口电平负跳变方式在4位数码管显示的计数器,要求C程序 -
聂惠当归: void main {unsigned char count=0;P3|=0x08;while(1){if(P3^3==0){count++;while(P3^3==0);}disp_count(count); //数码管显示次数} }

乌马河区19451683410: 用C语言51单片机编写数码管从00到99的循环程序 -
聂惠当归: {TMOD=0x01;ET0=1;EA=1;TR0=1;TH0=0x3c;TL0=0xaf; }void time_1s (void) interrupt 1 {int ncount;TH0=0x3c;TL0=0xaf;ncount++;if(ncount<20) return;{ncount=0;i++;if(i==100) i=0;} }

乌马河区19451683410: 单片机c语言,设计一个计数器,中断一次,数码管数字从0起加1, 4位的数码管 -
聂惠当归: 我直接拿一个现成的例子吧.这个是用定时器中断的,你可以改成外部中断.这是8位的数码管,对4位稍加修改就行了.#include <reg52.h> //包括一个52标准内核的头文件#include<intrins.h> /****************************声明函数********************...

乌马河区19451683410: 求一个单片机51的,用c语言编写,可对数码管闪烁赋值的程序 -
聂惠当归: #include<reg52.h> #include<intrins.h> sbit LS138A=P2^2; sbit LS138B=P2^3; sbit LS138C=P2^4; unsigned int i; void delay(i) {unsigned int j;for(i;i>0;i--)for(j=110;j>0;j--); } unsigned int code Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,...

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