这个道题要注意的地方是:要避免锁存器中P0口复用的问题,每次用了之后都要把P2口前三位置零,等到下一次要用时再重新打开。
void SELECT_HC138(unsigned char n,unsigned char dat)
{
P2=(P2&0x1f)|0x00;
P0=dat;
switch(n)
{
case 4: P2=(P2&0x1f)|0x80; break;
case 5: P2=(P2&0x1f)|0xa0; break;
case 6: P2=(P2&0x1f)|0xc0; break;
case 7: P2=(P2&0x1f)|0xe0; break;
}
P2=(P2&0x1f)|0x00;//将前三位置1
}
其余的就是很基础的问题,参考代码如下:
#include <STC12C5A60S2.H>
sbit L1 = P1^0;
sbit L2 = P1^1;
sbit L8 = P1^7;
unsigned char dat1 = 0xff;
unsigned char code smgduanma[18]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x80,
0xc6,0xc0,0x86,0x8e,0xbf,0x7f
};
void smgDisplay();
unsigned char lightnum=0;
unsigned char lednum=0;
void SELECT_HC138(unsigned char n,unsigned char dat)
{
P2=(P2&0x1f)|0x00;
P0=dat;
switch(n)
{
case 4: P2=(P2&0x1f)|0x80; break;
case 5: P2=(P2&0x1f)|0xa0; break;
case 6: P2=(P2&0x1f)|0xc0; break;
case 7: P2=(P2&0x1f)|0xe0; break;
}
P2=(P2&0x1f)|0x00;//将前三位置1
}
void Delay(unsigned int t)
{
while(t--);
}
void Delaysmg(unsigned int t)
{
while(t--)
{
smgDisplay();
}
}
void Display(unsigned char value,unsigned char pos)
{
SELECT_HC138(6,0x01<<pos);
SELECT_HC138(7,value);
}
void DisplayAll(unsigned char value)
{
SELECT_HC138(6,0xff);
SELECT_HC138(7,value);
}
void running()
{
dat1 &= ~0x80;
SELECT_HC138(4,dat1);
Delaysmg(100);
dat1 |= 0x80;
SELECT_HC138(4,dat1);
Delaysmg(100);
lightnum++;
if(lightnum == 100)
{
lightnum = 0;
}
if((dat1 & 0x03) == 0x03)
{
dat1 &= ~0x03;
}
else
{
dat1 |= 0x03;
}
SELECT_HC138(4,dat1);
lednum++;
if(lednum == 10)
{
lednum = 0;
}
}
void smgDisplay()
{
Display(smgduanma[lightnum%10],7);
Delay(200);
Display(smgduanma[lightnum/10],6);
Delay(200);
Display(smgduanma[lednum],0);
Delay(200);
DisplayAll(0xff);
}
void InitSystem()
{
SELECT_HC138(0,0x00);
SELECT_HC138(4,0xff);
SELECT_HC138(5,0x00);
SELECT_HC138(7,0xff);
}
void main()
{
InitSystem();
while(1)
{
running();
smgDisplay();
}
}