51单片机中断定时不准确,P1接数码管段选,P0的0到3接位选。4位数码管。

#include<reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
uint16 y;
sbit smg1=P0^0;
sbit smg2=P0^1;
sbit smg3=P0^2;
sbit smg4=P0^3;
code uint8 number[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,};
uint8 a[4];
void smg_led()
{
static uint8 x=0;
P0=0xff; //为什么不加这一句数码管显示乱码?
switch(x)
{
case 0:smg1=0; x++;P1=number[a[0]]; break;
case 1:smg2=0; x++;P1=number[a[1]]; break;
case 2:smg3=0; x++;P1=number[a[2]]; break;
case 3:smg4=0; x=0;P1=number[a[3]]; break;
default: break;
}
}
void T1_time()
{
TMOD=0x01;
TH1=0x3c;
TL1=0xb0;
TR1=1;
}
void T1_zd()
{
EA=1;
ET1=1;
}
main()
{
T1_time();
T1_zd();
while(1);
}
void T1_interrupt()interrupt 3
{
static uint16 j=0;
TH1=0x3c;
TL1=0xb0;
TR1=1;
y++;
if(y==20)//中断20次不是一秒吗。为什么只有1%10左右,晶振12MHZ;
{
j++;
y=0;

a[0]=j%10;
a[1]=j/10%10;
a[2]=j/100%10;
a[3]=j/1000%10;
}
smg_led();
}

第1个回答  2012-11-12
程序修改了一下,你的问题在注释中回答
#include<reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
uint16 y;
sbit smg1=P0^0;
sbit smg2=P0^1;
sbit smg3=P0^2;
sbit smg4=P0^3;
code uint8 number[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,};
uint8 a[4];
void smg_led()
{
static uint8 x=0;
P0=0xff; //不加这句你可能四位全选,所以很乱,这句就是先切断所有段选,再按X值选择段
switch(x)
{
case 0:smg1=0; x++;P1=number[a[0]]; break;
case 1:smg2=0; x++;P1=number[a[1]]; break;
case 2:smg3=0; x++;P1=number[a[2]]; break;
case 3:smg4=0; x=0;P1=number[a[3]]; break;
default: break;
}
}
void T1_time()
{
TMOD=0x10;//你定时不准原因就是定时器1模式错误,模式1是16位,才能达到你期望效果
TH1=0x3c;
TL1=0xb0;
TR1=1;
}
void T1_zd()
{
EA=1;
ET1=1;
}
main()
{
T1_time();
T1_zd();
while(1);
}
void T1_interrupt()interrupt 3
{
static uint16 j=0;
TH1=0x3c;
TL1=0xb0;
TR1=1;
y++;
if(y==20)//中断20次不是一秒吗。为什么只有1%10左右,晶振12MHZ;
{
j++;
y=0;

a[0]=j%10;
a[1]=j/10%10;
a[2]=j/100%10;
a[3]=j/1000%10;
}
smg_led();
}
第2个回答  2012-11-12
问题1, T1 中断方式0 只有 不到 1 mS ( 你现在 T1 为方式0)
问题2, T1 中断设置成方式1 50 mS , 这样中断20次不是一秒。显示会不正常 闪烁。
建议方法, 可以用 T0 设置成方式1 50 mS , 这样中断20次不是一秒, 作计时。
可以用 T1 设置成方式0 2 ~ 5 mS , 用作扫描显示 。
( 扫描显示 一般 2.5 mS 可以正常显示 8 位 数码管)追问

你好,按照你的程序重新编写了一下 ,数码管不亮了,第一个问题已经知道了 。就是中断不太明白, 谢谢你啊。。

追答

其实 只要 把你的 T1 中断, 分成 T0 和 T1 两个中断,
原来的 T1 把定时 时间 修改一下,直接用来 调用显示程序,其它程序 放到 T0 中,
原来的 T1 把定时 复制一个 ,改成 T0 , 去掉 显示程序,
T0 T1 初始化一下 就可以了,
如:
void T1_time()
{
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
TH1=0x3c;
TL1=0xb0;
TR0=1;
TR1=1;
}
void T1_zd()
{
EA=1;
ET0=1;
ET1=1;
}
void T0_interrupt()interrupt 1
{
static uint16 j=0;
TH1=0x3c;
TL1=0xb0;
y++;
if(y==20)
{
j++;
y=0;
a[0]=j%10;
a[1]=j/10%10;
a[2]=j/100%10;
a[3]=j/1000%10;
}
}
void T1_interrupt()interrupt 3
{
TH1=0x0c; // 5 mS
TL1=0x77;
smg_led();
}

本回答被提问者和网友采纳
第3个回答  2012-11-13
stc的用T1可能出错,我有遇到过,还是用T0,别的人家跟你说了
相似回答