当前位置:编程学习 > C/C++ >>

请教单片机控制数码管显示数字C语言程序问题,满意加分

先上程序
#include <reg51.h>
main()
{
int i;
char j=0;
while(1)
{
P0=0x01<<(j++);
switch(P0)
{
case 0x01: P2=0x0;break;
case 0x04: P2=0x0;break;
case 0x02: P2=0x1;break;
case 0x08: P2=0x1;break;
case 0x10: P2=0x1;break;
case 0x40: P2=0x1;break;
case 0x20: P2=0x2;break;
case 0x80: P2=0x2;break;
}
for(i=0;i<10000;i++);//延时时间随意写的
if(8==j) j=0;
}
}
我的想法是P0口由1开始左移,逐个点亮数码管,然后用switch语句控制显示的数字:P0=1时第一个数码管显示0,P0=2时第二个数码管显示1,依次类推。但程序实际运行时只有第一次P0=1时才会进入switch语句进行选择,而后就无法进入,数码管的显示结果就全部显示0。请问程序错在哪里?为什么无法选择?
追问:首先先感谢您的热心回答,但有几处错误,严格说不是错误,而是误区。

首先if(8==j) j=0;这一句并没有错误,他和if(j==8){j=0;}是等价的。这样写是为了防止将j==8误写成j=8,不可否认,这是新手经常出现的错误,编译器是无法发现的,即使写错也可以正常编译。如果写成8==j就不会出现这种情况,写成8=j编译器无易做图常编译,会报错的。而对于{},当if后面只有一句语句的时候可以省略,我是从电脑编程转行到单片机编程的,而以前用的就是C语言,所以对于语法还算是合格。

对于P0=0x01<<(j++);一句,初始化时j=0,j++是先运算再自增,该句可以解释为1左移0位后将植赋给P0,然后j+1,等价于P0=0x01<<j;j=j+1;所以switch语句的确是从P0=0x1进入的,这一点我在keil上软件仿真调试上已经证实了,只是在第二次执行到switch时程序直接跳过,不执行P0=0x2后面的语句。而这才是我这次问题的根本所在。

对于数码管,我用的是普通共阳数码管,只是加了一个74LS247译码器,直接向译码器输出8421码就可以在数码管上显示相应的十进制数。

功能我已经用定义数组的方法成功实现了,只是想不通为什么switch语句就不行,原因错在哪里。

答案:if(8==j) j=0;
错在这里

if(j==8){j=0;}

还有就是你的程序也有问题,程序运行时P0=0x01的情况不会出现,因为P0=0x01<<(j++);后进入switch的P0只会从0x02开始~粗心了吧~还有就是你用的什么数码管?不是用的那种共阳、共阴8位数据端的数码管?是8421那种?

下面修改后的程序(数码管采用的是共阳的数码管)

#include <reg51.h>

#define uchar unsigned char

uchar led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
main()
{
int i;
char j=0;
while(1)
{
switch(P0)
{
case 0x01: P2=led[0];break;
case 0x04: P2=led[1];break;
case 0x02: P2=led[2];;break;
case 0x08: P2=led[3];;break;
case 0x10: P2=led[4];;break;
case 0x40: P2=led[5];;break;
case 0x20: P2=led[6];;break;
case 0x80: P2=led[7];;break;
}
for(i=0;i<10000;i++);//延时时间随意写的
if(j<7)

{

j++;

P0=0x01<<j;

}

else

{

P0=0x01;

j=0;

}
}
}

如果还有问题~就留给邮箱~我发仿真和程序给你~上面的程序是随手打的~可能有错哈~不过思路是对的~


 

上一个:如何在最短的时间内,简单学会C语言?
下一个:C语言运算的优先级别和结合方向表是什么的?

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,