遇到的问题
这几天在写51动态数码管的时候遇到一个问题,无论我用for循环还是定时器都无法装填被调用函数的形参。
原理图
这里用的是三脚控八脚的译码器,74HC245的OE接口已经接地。
代码
Main.c
#include "reg52.h"
#include "Delay.h"
#include "Digital_tube.h"
unsigned char num,counter;
void main()
{
num = 60;
counter = 0;
TMOD = 0x01;
TH0 = 15536 / 256;
TL0 = 15536 % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
while(1)
{
Count_2(num);
}
}
void T0_timer() interrupt 1
{
TH0 = 15536 / 256;
TL0 = 15536 % 256;
counter++;
if(counter == 20)
{
counter = 0;
num--;
}
if(num == 0)
{
num = 60;
}
}
Digital_tube.c
#include "reg52.h"
#include "Delay.h"
#include "Digital_tube.h"
unsigned char code table[] = {0x3f, 0x06, 0x5b, 0x4f,
0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71};
void Digital_way1(unsigned char num)
{
switch(num)
{
case 1: P2 = 0x00;break;
case 2: P2 = 0x04;break;
case 3: P2 = 0x08;break;
case 4: P2 = 0x0c;break;
case 5: P2 = 0x10;break;
case 6: P2 = 0x14;break;
case 7: P2 = 0x18;break;
case 8: P2 = 0x1c;break;
}
}
void Moved_tube(unsigned char mode,unsigned char index)//模式1为连续的数码管,模式2为单选数码管
{
if(mode == 1)
{
while(1)
{
unsigned char i;
for(i = 1; i < index + 1; i++)
{
Digital_way1(i);
Delayms(1);
}
i = 0;
}
}
else if(mode == 2)
{
Digital_way1(index);
}
}
void Count_2(unsigned char number)//实现倒数的两位数码管,十位和个位
{
while
{
unsigned char shi,ge;//十位和个位
shi = table[(number / 10)];
P0 = shi;
Moved_tube(2,2);
Delayms(5);//停留5ms后
P0 = 0x00;//消影
ge = table[(number % 10)];
P0 = ge;
Moved_tube(2,1);
Delayms(5);
P0 = 0x00;
}
}
运行的结果
尝试解决的方案
验证被调用函数的可行性
结果:被调用函数Count_2()在指定参数下显示没有问题,其他函数没有问题
用volatile
在用各种循环和各种不同的定时器之后,结果依旧不如愿,于是尝试在全局变量前加volatile,结果还是没有变化
用for循环
while(1)
{
for(num = 60;num > 0; num--)
{
P2 = ~P2;
Count_2(num);
Delayms(100);
}
if(num == 1)
{
num = 60;
}
数码管还是无动于衷。
思考
1.当时想到我要调用的函数在while里面一直被使用着,会不会是因为参数一直在被主程序占用,你可以在中断函数中改变全局变量的值,但你要确保该值没有在主程序中被占用斜体字引用这里,也就有了上文的volatile,资料参考这里。
2.之后各种百度谷歌了别人的见解 点这里。
最终的解决方案
在查阅了csdn及相关博客后,既然不是定时器的问题,不是主函数的问题,那锅可能在被调用函数身上。
void Count_2(unsigned char number)
{
while(1)
{
unsigned char shi,ge;
shi = table[(number / 10)];
P0 = shi;
Moved_tube(2,2);
Delayms(5);
P0 = 0x00;
ge = table[(number % 10)];
P0 = ge;
Moved_tube(2,1);
Delayms(5);
P0 = 0x00;
}
}
注意到,之前为了让它显示单个数字,所以加了一个while循环,然后我猛然发现在main里面也加了一个循环,会不会是两层循环导致的无法改变变量了,果然,在删去被调用函数里的while之后,数码管死而复生。
结论
两个while嵌套可以保护变量。