- 先简单看一下蓝桥杯板子相关的电路图,如下
2.电路分析
74HC573、74HC02、74HC138这三个数字芯片作为LED灯的前置驱动电路
要想操作led需要先操作74HC138芯片,通过74h02,打开74HC573锁存器,然后在向P0口写入相应的值。
分析初始化代码
/*******板子初始化******/
void banzi_init()
{
P2=((P2&0X1F)|0XA0);P0=0X00;P2&=0X1F;
P2=((P2&0X1F)|0X80);P0=0XFF;P2&=0X1F;
P2=((P2&0X1F)|0XC0);P0=0XFF;P2&=0X1F;
P2=((P2&0X1F)|0XE0);P0=0XFF;P2&=0X1F;
}
- (P2&0x1f) -》P2高三位置零 第五位不变,高三位对应138译码器的 A B C 三个io口
- ((P2&0X1F)|0XA0) -》给P2高三位赋值为110; 则对应的y6锁存器打开
- ;P0=0X00; -》打开锁存器后向锁存器写入初始值,
- P2&=0X1F; -》138写入000 关闭所有锁存器
数码管初始化代码
方案一:
//数码管码值
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x40,0x79,0x24,0x30,0x19,
0x12,0x20,0x78,0x00,0x10,
0xbf,0xff};//0123456789 0.1.2.3.4.5.6.7.8.9.- 灭
uint yi,er,san,si,wu,liu,qi,ba;
//函数初始化
void dispaly12(uchar yi,uchar er)
{
P2=((P2&0X1F)|0XC0);
P0=0x01;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[yi];
P2&=0X1F;
delay200um(10);
P2=((P2&0X1F)|0XC0);
P0=0x02;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[er];
P2&=0X1F;
delay200um(10);
}
void dispaly34(uchar san,uchar si)
{
P2=((P2&0X1F)|0XC0);
P0=0x04;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[san];
P2&=0X1F;
delay200um(10);
P2=((P2&0X1F)|0XC0);
P0=0x08;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[si];
P2&=0X1F;
delay200um(10);
}
void dispaly56(uchar wu,uchar liu)
{
P2=((P2&0X1F)|0XC0);
P0=0x10;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[wu];
P2&=0X1F;
delay200um(10);
P2=((P2&0X1F)|0XC0);
P0=0x20;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[liu];
P2&=0X1F;
delay200um(10);
}
void dispaly78(uchar qi,uchar ba)
{
P2=((P2&0X1F)|0XC0);
P0=0x40;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[qi];
P2&=0X1F;
delay200um(10);
P2=((P2&0X1F)|0XC0);
P0=0x80;
P2&=0X1F;
P2=((P2&0X1F)|0XE0);
P0=tab[ba];
P2&=0X1F;
delay200um(10);
}
- 函数分析
- 入口参数,数码管显示的码值
- 返回值 无;
- 譬如:dispaly78 对应的是数码管的七八位
方案二:
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar yi,er,san,si,wu,liu,qi,ba,shumaguan_num[8];
/******数码管one******/
void dispaly_one()
{
shumaguan_num[0]=tab[yi];
shumaguan_num[1]=tab[er];
shumaguan_num[2]=tab[san];
shumaguan_num[3]=tab[si];
shumaguan_num[4]=tab[wu];
shumaguan_num[5]=tab[liu];
shumaguan_num[6]=tab[qi];
shumaguan_num[7]=tab[ba];
}
/*******数码管tow*****/
void dispaly_tow()
{
uchar i;
for(i=0;i<8;i++)
{
P2=((P2&0X1F)|0XC0);P0=(1<<i);P2&=0X1F;
P2=((P2&0X1F)|0XE0);P0=shumaguan_num[i];P2&=0X1F;
Delay1ms(1);
}
P2=((P2&0X1F)|0XC0);P0=0XFF;P2&=0X1F;
P2=((P2&0X1F)|0XE0);P0=0XFF;P2&=0X1F;
}
-
这种方法更为简洁,方便理解,直接在主函数里面调用
-
方案三
在中断里实现数码管
每进入中断里一次,显示一位数码管
/******定时器函数******/
void Timer0Init(void) //1微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x33; //设置定时初值
TH0 = 0xBF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
/*****定时器执行函数*****/
void timer0() interrupt 1
{
tt++;
/*
if(tt>=1000)
{
if(SHAN_flag){SHAN_flag=0;}
else if(!SHAN_flag){SHAN_flag=1;}
tt=0;
if(naoling_flag!=0)//闹铃
{
naoling_flag--;
if(naoling_flag%2)
{
P2=((P2&0X1F)|0X80);P0=~(P0&(0x01));P2&=0X1F;
}else {P2=((P2&0X1F)|0X80);P0=0xff;P2&=0X1F; }
}
}*/
/*******上面这一部分和数码管关系不大先注释*******/
/**数码管显示单元*****/
SMG_tt++;
if(SMG_tt==8)
{
SMG_tt=0;
SMG_num[0]=tab[yi];
SMG_num[1]=tab[er];
SMG_num[2]=tab[san];
SMG_num[3]=tab[si];
SMG_num[4]=tab[wu];
SMG_num[5]=tab[liu];
SMG_num[6]=tab[qi];
SMG_num[7]=tab[ba];
}
P2=((P2&0X1F)|0XC0);P0=(1<<SMG_tt);P2&=0X1F;
P2=((P2&0X1F)|0XE0);P0=SMG_num[SMG_tt];P2&=0X1F;
if( SMG_tt==8)
{
SMG_tt=0;
P2=((P2&0X1F)|0XC0);P0=0XFF;P2&=0X1F;
P2=((P2&0X1F)|0XE0);P0=0XFF;P2&=0X1F;
}
}
在蓝桥杯后期我更喜欢用方案三,因为对输出PWM的干扰最小。
在此鸣谢 :@缒夢著(李好)对我按键部分的错误纠正。