关于中断程序中改变全局变量的思考到两层while循环保护。

遇到的问题

这几天在写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嵌套可以保护变量。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值