基于蓝桥杯的单片机模块练习——LED跑马灯
功能概述
8个LED首先以一秒为间隔闪烁三次,然后从左到右依次点亮,蜂鸣器叫1秒后,LED从右到左依次关闭,继电器打开1秒。
C代码
#include "reg52.h"
void Delay_1ms(unsigned int t)
{
unsigned int x,y;
for(x = t; x > 0; x--)//注意,此循环的x,y判断条件为>0,绝不能写成>=
for(y = 900; y > 0; y--); //此处900为在晶振12MHZ的1T条件下测试的近似
//值,延时并不精准。
} //可以看到x,y的值都定义成了uint,
//如果这个数据类型改变,那么这个900便不准确了,
//得另行测试。
void SelectHC573(unsigned char n)
{
switch(n)
{
case 4 : P2 = (P2 & 0x1f) | 0x80;//打开LED锁存器
break;
case 5 : P2 = (P2 & 0x1f) | 0xa0;//打开继电器(蜂鸣器)锁存器
break;
case 6 : P2 = (P2 & 0x1f) | 0xc0;//打开数码管位选锁存器
break;
case 7 : P2 = (P2 & 0x1f) | 0xe0;//打开数码管段选锁存器
break;
case 0 : P2 = (P2 & 0x1f) | 0x00;//关闭以上所有锁存器
break;
}
}
//函数:P0口任意位赋值0(1),而其他位不变
void P0_Output(unsigned char channel,unsigned char BIt,unsigned char dat)
{
SelectHC573(channel);
switch(dat)
{
case 0 : P0 &= ~ (0x01 << BIt);break;
case 1 : P0 |= (0x01 << BIt);break;
}
SelectHC573(0);
}
void InitSystem()
{
SelectHC573(5);
P0 = 0x00;
SelectHC573(0);
P0 = 0xff;//由于单片机复位后的P0口默认为0xff,所以在关闭蜂鸣器之后,最好
} //再把P0口转为0xff。
void LEDRunning()
{
unsigned char i;
for(i=0;i<3;i++)
{
SelectHC573(4);
P0 = 0X00;
Delay_1ms(1000);
P0 = 0XFF;
Delay_1ms(100);
}
for(i=1;i<=8;i++)
{
SelectHC573(4);
P0 = 0XFF << i;
Delay_1ms(100);
}
P0_Output(5,4,1);
Delay_1ms(1000);
P0_Output(5,4,0);
for(i=1;i<=8;i++)
{
SelectHC573(4);
P0 = ~(0xff>>i);
Delay_1ms(100);
}
P0_Output(5,6,1);
Delay_1ms(1000);
P0_Output(5,6,0);
}
void main()
{
InitSystem();
while(1)
{
LEDRunning();
}
}
知识点总结
P2 = (P2 & 0x1f) | 0x80;
含义:
先通过&运算,把P2口的高三位清0,而其他位值不变。然后通过|运算,使前三位得到确定的值,来控制具体锁存器的使能,而其他位值不变。
对74HC138的控制:
对照138译码器的真值表,通过控制P2口的值来打开关闭某固定锁存器。
由于IO模式编程下,J13要通过跳线帽把WR和GND连接,那么四个或非门的WR就为0,如果Y4的值也为0的话,Y4C就会输出1,而Y4C连接的就是相应锁存器的使能端,这样便打开了相应的锁存器。(其他相应锁存器的控制一样)