标题:
单片机定时器数码管程序调试卡着了,求指教
[打印本页]
作者:
qjyvi2
时间:
2023-4-29 23:50
标题:
单片机定时器数码管程序调试卡着了,求指教
利用动态扫描和定时器0在数码管上显示出从543210开始以1%秒的速度往下递减直至543111并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,同时蜂鸣器发声,当数码管上数减到停止时,实验板上流水灯全部闪烁4次,数码管全熄灭。单片机进入休眠状态。
我写的单片机程序:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit ledla=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
sbit laba=P2^3;
uint num,n,e;
uchar b,i,c,d;
display();
delay(uchar);
void main()
{
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1; //开中断
num=999; //项目 只有后三位变化。我就给999;
b=7; //用来给八个流水灯循环用
laba=0; //蜂鸣器开
d=0; //自己写的数码开始保持543111标志位
while(1)
{
display();//数码管显示
P1=~(1<<b);//流水灯显示
if(i==8)
{
i=0;
b=7;
}
if(d==1)//数码管保持在543111后d=1,进入以后操作
{
for(c=0;c<3;c++)
{
P1=0x00;
for(e=0;e<65535;e++);
P1=0xff;
for(e=0;e<65535;e++);//流水灯全亮并亮灭三次
}
laba=1; //关蜂鸣器
P1=0xff; //关流水灯
P0=0xff;
wela=1;
wela=0;
P0=0xff;
dula=1;
dula=0; //关数码管
PCON=0x02; //进入休眠
}
}
}
delay(uchar x) //延时
{
uchar a,b;
for(a=x;a>0;a--)
for(b=200;b>0;b--);
}
void t0() interrupt 1
{
n++;
if(num>111) //num数码管的后三位
{
num--;
d=0;
}
if(num==111)
{
d=1;
}
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
if(n==50)
{
i++;
b--;
n=0;
}
}
display()
{
P0=0xff;
wela=1;
wela=0;
P0=table[6];
dula=1;
dula=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=0xff;
wela=1;
wela=0;
P0=table[5];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=0xff;
wela=1;
wela=0;
P0=table[4];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=0xff;
wela=1;
wela=0;
P0=table[num/100];
dula=1;
dula=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=0xff;
wela=1;
wela=0;
P0=table[num%100/10];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=0xff;
wela=1;
wela=0;
P0=table[num%100%10];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
以上是单片机代码
下面是问题:
惟一的出错的在于。没办法保持543111;运行到最后数码管前五个不亮,第六个保持亮1到结束。
if(d==1)下面这些内容不要。确实可以保持在543111;有了if(d==1)下面这些就会最后一个管亮1.
请各位大神指教。十分感谢。
作者:
qjyvi2
时间:
2023-4-30 10:04
找出来了。DISPLAY()要放中断函数里面才是一直运行,不然停下后。只能最后一个数码管显示1
作者:
wulin
时间:
2023-4-30 10:33
楼主的意图本身就存在逻辑问题 ,“543210开始以1%秒的速度往下递减直至543111” 其过程就是990ms,在此区间以500mS速度进行流水灯从上至下移动???
运行到最后数码管前五个不亮,第六个保持亮1到结束。是因为流水灯全亮并亮灭4次期间数码管停止扫描。
给你改了:把543210递减至543111的时间改为9.9s以便观察。重点是要理解数码管动态显示函数的运行方式。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit buzzer=P2^3;
uchar code table[]={//共阴数码管段码"0~f-."
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40,0x80};
uchar data dis_buf[6]; //缓存数组
uchar b,c;
uchar count,num;
bit stop,mark,sign;
void Timer0Init() //1毫秒@11.0592MHz
{
TMOD= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void display()//数码管动态显示函数
{
static uchar i;
P0=0x00; dula=1;dula=0;//消隐
P0=~(0x01<<i);wela=1;wela=0;//送位码
P0=dis_buf[i];dula=1;dula=0;//送段码
i=++i%6;//循环计数
}
void main()
{
Timer0Init();
dis_buf[0]=table[5];//固定显示部分
dis_buf[1]=table[4];
dis_buf[2]=table[3];
P1=0xfe;
buzzer=0;
num=210;
while(1)
{
if(mark)//周期100ms
{
mark=0;
if(stop==0)//流水灯
{
P1=P1<<1|0x01;
if(P1==0xff)
P1=0xfe;
}
else //闪烁灯
{
if(++b==5)//500ms
{
b=0;
P1=~P1;
if(++c==8)//闪烁4次结束运行,全部复位
{
c=0;
EA=0;
buzzer=1; //关蜂鸣器
P1=0xff; //关LED
P0=0xff; //关数码管
dula=1;
wela=1;
_nop_();
_nop_();
PCON=0x02;//进入休眠
}
}
}
}
dis_buf[3]=table[num/100%10];
dis_buf[4]=table[num/10%10];
dis_buf[5]=table[num%10];
}
}
void Timer0Interrupt() interrupt 1
{
TH0 = 0xFC; //1毫秒@11.0592MHz
TL0 = 0x66;
if(++count==100)//100ms
{
count=0;
mark=1;//100ms标志
if(!stop)
{
num--;
if(num==111)
{
stop=1;//计数结束
P1=0xff;//流水灯结束
}
}
}
display();//数码管动态显示函数
}
复制代码
作者:
qjyvi2
时间:
2023-4-30 17:07
wulin 发表于 2023-4-30 10:33
楼主的意图本身就存在逻辑问题 ,“543210开始以1%秒的速度往下递减直至543111” 其过程就是990ms,在此区 ...
哈哈。是的。动态扫描理解的不到位。你这代码写的太漂亮了。很感谢。我好好消化一下。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1