要求如下:
http://【金山文档】 12db091b33a652e606b9d924fa70e609 https://kdocs.cn/l/cc2DDpSOMCvN
代码如下:
#include <regx52.h>
int a=0;
int b=0;
int count2=0;
int count4=0;
int q=0;
int i=0;
unsigned int cnt = 0;定时器计数
unsigned char table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0 1 2 3 4 5 6 7 8 9
void Delay(unsigned int xms)//延时函数
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void Timer1_ISR(void) interrupt 3 //中断
{
TH1 = 0xFC;
TL1 = 0x18;
cnt++;
}
void nixie(unsigned char loc,num){
switch(loc)//选择显示的数码管位置
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0 =table[num];//选择显示的数字
}
void main()
{
TMOD = 0x10;//定时器
TH1 = 0xFC;
TL1 = 0x18;
TR1 = 1;
ET1 = 1;
EA = 1;
//mode 1
if(P3_1==0){
Delay(5);
while(P3_1==0);
while(1)
{
Delay(2);
P2_4=1;P2_3=1;P2_2=1;P0=0x3E;//选择第一个位置显示字母U
Delay(2); //第二位显示1
nixie(2,1);
Delay(2);
nixie(7,0); //第七位显示0,第八位显示1
Delay(2);
nixie(8,1);
Delay(2);
if(!P3_0||!P3_2||!P3_3)break;//有其他按键被按下时,结束本模式,执行被按下按键控制的模式
}
}
//mode 2
if(P3_0==0){
Delay(5);
while(P3_1==0);
Delay(5);
while(1)
{
Delay(2);
P2_4=1;P2_3=1;P2_2=1;P0=0x3E;//选择第一个位置显示字母U
Delay(2); //第二位显示2
nixie(2,2);
Delay(2);
nixie(7,a); 第七,八位显示a,b,a,b初始值为0,0.
Delay(2);
nixie(8,b);
Delay(2);
count2++;
while(count2==100) //计时1s
{
count2=0;
if(a==1){a=0;b=-1;} //b从0到9,b等于9后将a设为1,b设为0,最后a,b,都重置为0
if(b<9)b++;
else{b=0;a=1;}
}
if(!P3_1||!P3_2||!P3_3)break;//有其他按键被按下时,结束本模式,执行被按下按键控制的模式
}
}
//mode 3
if(P3_2==0){
Delay(2);
while(P3_1==0);
Delay(2);
while(1)
{
Delay(2);
P2_4=1;P2_3=1;P2_2=1;P0=0x3E;//选择第一个位置显示字母U
Delay(2); //第二位显示3
nixie(2,3);
Delay(2);
nixie(7,0);
Delay(1);
nixie(8,3);
Delay(1);
if(cnt>=492){ //500MS定时器
P2_4=0;P2_3=1;P2_2=1;P0=0x40;//第七位显示-
Delay(5);
P2_4=0;P2_3=1;P2_2=0;P0=0x40;//第八位显示-
cnt = 0;
}
if(!P3_0||!P3_1||!P3_3)break;//有其他按键被按下时,结束本模式,执行被按下按键控制的模式
}
}
//mode4
if(P3_3==0){
while(1)
{
Delay(2);
P2_4=1;P2_3=1;P2_2=1;P0=0x3E;//选择第一个位置显示字母U
Delay(2); //第二位显示4
nixie(2,4);
Delay(2);
nixie(7,q); //第七,八位都为q,初始值为0
Delay(2);
nixie(8,q);
Delay(2);
if(!P3_3){ //按键被按下松开后q++
while (!P3_3);
Delay(2);
q++;
if(q==10)q=0;
}
if(!P3_0||!P3_2||!P3_1)break;//有其他按键被按下时,结束本模式,执行被按下按键控制的模式
}
}
}
思路如下:
1.首先main函数由一个外部while循环和四个并列的while循环构成。四个循环代表四个模式,进 入循环的条件是按对应的机械按键,离开的条件是按其他三个按键,同时也进入其他循环,实现 四个模式的任意切换。
2.其次需要调用四个按键P3_0,P3_1,P3_2,P3_3。方法是通过读取对应引脚的状态(0 or 1) 来检测机械按键的按下情况
3.接着调用八位数码管。首先数码管的显示是动态扫描的,一次扫描只能显示一个位置。选择位置 靠3-8译码器三个引脚P2_2,P2_3,P2_4的状态(0 or 1)来选择显示位置Y0~Y7,对应八个数码 管。因为三个引脚的状态刚好可以对应八个二进制数(000~111),所以不同的组合可控制不同 的数码管。调用位置的函数时nixie()的第一个参数,通过输入数字(0~7)来选择一次扫描时 显示的数码管位置。
4.选中数码管位置后就要设计要显示什么图案了。一个数码管由8个LED灯构成”8.“,分别是dp, g,f,e,d,c,b,a.也是也是通过控制每一个LED灯对应引脚的状态(0 or 1)来控制亮灭。此时是通 过字节操作来控制哪些灯亮或不亮。相当于一个引脚控制着八个引脚。观察单片机核心右上部分 的P0区域可以知道P0~P7分别控制着dp,g,f,e,d,c,b,a.如:P0=0x3F,转化为二进制就是0011 1111,也就是dp,g灭,f,e,d,c,b,a亮,此时显示的就是数字0.对 P0赋值:unsigned char table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//0 1 2 3 4 5 6 7 8 9,所以 函数nixie()的第二个参数就是显示的数字。
5.延时函数Delay()由stc-isp生成
6.定时器也是由stc-isp生成
7.四个模式差不多都是函数nixie()和Delay()反复调用(粗暴),写了一些注释,应该不是很 乱吧。