编写了51单片机程序 但是有错误 仿真也有点小问题 求高手指点 急求

作者&投稿:大狐池 (若有异议请与网页底部的电邮联系)
求一个99秒倒计时单片机程序和仿真,基于51单片机。~

#include "reg51.h"
sbit start=P3^2; //外部中断0引脚 开始
sbit rst=P3^3; //外部中断1引脚 复位
sbit breakk=P3^4; //暂停倒计时
sbit led=P3^5; //Led灯
sbit beep=P3^7; //蜂鸣器控制引脚

sbit P30=P3^0; //数码管位选
sbit P31=P3^1;

void didi(void);
unsigned char code duanma[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff
};

char time=99; //倒计时缓存
char flag_t=0; // 1秒辅助计时
char now=0; // 0停止 1 计时 2报警 3复位

unsigned char g=0,s=3,i=0;

void delay(unsigned int n)
{
while(--n);
}

void t0_srv() interrupt 1 using 1
{
TH0=0X3C;
TL0=0XB0;
flag_t++;
if(flag_t>=20){ //20*50ms=1s
flag_t=0;
time--;
if(time<=0){
// beep=0;
didi();
didi();
didi();
led=0;
TR0=0;
now=2;
time=0;
}
}
}
void button_start() interrupt 0 using 1 //外部中断0
{
delay(1500);
if(start==0) {
now=1;
TR0=1;
}
else return;
while(start==0);
delay(1500);

}
void button_rst() interrupt 2 using 1
{
delay(1500);
if(rst==0) {
TR0=0;
time=99;// 3;
i=0;
led=1;
now=0;
}
else return;
while(rst==0);
delay(1500);

}

void disp()
{

g=time%10;
s=time/10;
g=duanma[g];
s=duanma[s];


P0=~g;
P31=0;
delay(250);
P31=1;



P0=~s;
P30=0;
delay(250);
P30=1;

}
void key()
{
if(breakk==0)delay(1500);
else return;
if(breakk==0) {
if(now==1){
i++;
if(i%2)TR0=0;
if(!(i%2))TR0=1;
}
}
else return;
while(breakk==0);
delay(1500);
}
/* 延时250us*k */
void delay250(unsigned int k)
{
unsigned int j,i;
for (i=0;i<k;i++)
{
for(j=0;j<25;j++);
}
}
void didi(void)
{
unsigned int j;
for (j=0;j<400;j++) //loop 400,响0.2s
{
beep=0;
delay250(2);
beep=1;
delay250(2);
}
delay250(800); //stop 0.2s

}


main()
{
TMOD=0X01;//定时器0工作在方式1,
EA=1;
IT0=1;
ET0=1;
TH0=0X3C;//在12M 晶振下,定时时间为50ms
TL0=0XB0;

EX0=1;
EX1=1;

//TR0=1;
while(1){
disp();
key();
}


}

char code i=0;改成char i=0;因为你下面i的变量是重新赋值了,所以不能用code关键字的!

也没人管你呀 哈哈 俺来帮你解决吧 你的图选定字太小 看不清楚 根据你的程序 可以看出P1口控制8 个LED指示灯。 P0口作为2个七段数码管的段形输出口 P2.0 作为第一个数码管的位选,P2.1作为第二个数码管的位选, 是这样的吧?
程序修改如下:

程序1和2.

ORG 0000H
LJMP START
ORG 0100H
START: MOV P1,#3BH ; 是低电平 点亮 点亮LED8 LED7 LED3
MAIN: MOV P0,#0FF ; 第一个数码管显示消隐 即显示 灭
MOV P2,#01H
MOV P0,#94H ; 送显示2的显示编码 94H
MOV P2,#01H ; 点亮第一个数码管
LCALL D1MS

MOV P0,#0FF ; 第二个数码管显示消隐 即显示 灭
MOV P2,#02H
MOV P0,#0F8H ; 送显示7的显示编码 0F8H
MOV P2,#02H ; 点亮第二个数码管
LCALL D1MS
LJMP MAIN

D1MS: MOV R7,#02H
DL: MOV R6,#0FFH
DL1: DJNZ R6,DL1
DJNZ R7,DL
RET
END

3,开机后第一位和第二位数码管分别显示“2”和“7”。同时LED2和LED7闪烁,亮一秒灭一秒
参考程序:
ORG 0000H
LJMP START
ORG 000BH
LJMP DSQ0
ORG 0100H
START: MOV TMOD,#01H
SETB EA
SETB ET0
MOV TH0,#06H
MOV TL0,#06H
SETB TR0
MOV P1,#3BH ; 是低电平 点亮 点亮LED8 LED7 LED3
MAIN: MOV P0,#0FF ; 第一个数码管显示消隐 即显示 灭
MOV P2,#01H
MOV P0,#94H ; 送显示2的显示编码 94H
MOV P2,#01H ; 点亮第一个数码管
LCALL D1MS

MOV P0,#0FF ; 第二个数码管显示消隐 即显示 灭
MOV P2,#02H
MOV P0,#0F8H ; 送显示7的显示编码 0F8H
MOV P2,#02H ; 点亮第二个数码管
LCALL D1MS
LJMP MAIN

D1MS: MOV R7,#02H
DL: MOV R6,#0FFH
DL1: DJNZ R6,DL1
DJNZ R7,DL
RET
END

共阳极数码管C0H应显示为0,82H为左右相反的9.
所以数码管显示的原理你要先搞清楚.