一.LED的点亮
蓝桥杯
一.LED以及锁存器的跟随模式,io模式vcc或非门,keil新建项目文件以及第一个程序
led有八个灯珠,右边vcc为正极供电,因此,只需要控制左边负极为低电平,即可控制led。
但是在led左边有一个M74hc573锁存器。
简单来说,就是由输入引脚D1-D8,来控制输出引脚Q1-Q8,OE和LE的取值会影响输入数据控制输出数据。
当OE为L(低电平0v)时,LE为高电平H,为跟随模式,即输出数据=输入数据。
OE为L时,LE为低电平L时,为锁存模式,即输出数据=上一个时刻的输入数据。
我们这个锁存器的OE已经接了地,也就是说已经接了低电平,那我们只需要控制LE为高电平即可。
但是,这里LE接了一个”Y4C”,我们使用全局搜素,在原理图下面找到了另一个Y4C.
这是一个或非门,蓝桥杯比赛中,WR和GND是接在一起的,也就是说,WR固定为0,如果Y4(12)为0,Y4C则输出高电平,反之则低电平。
74HC02的Y4口又和U24接在一起,这个东西叫做74HC138译码器,
左边从上到下,如果为000,换为二进制则Y0口输出为低电平,Y1-Y7为高电平。
001,Y1口0其余1。
010,Y2口0其余1
011,Y3口0其余1….
100,Y4口0其余1
新建项目文件::
代码开始:
1 | #include <reg52.h> |
LSAbc为锁存器部分,P0为LED部分,另外一定要在程序里加上while,确保单片机的程序可以重复运行。
延时函数:
在isp烧录软件里找到延时函数,选择12mhz,定时长度为1s
先把整个复制下来,
1 | void Delay_ms() //@12MHz |
在此之前,为了方便起见,宏定义两个快捷操作
1 |
把延时函数变量改为
1 | void Delay_ms(uint xms) |
我们希望它延时多少毫秒,就把它循环几次
1 | for ( ; xms > 0; xms--) |
于是,延时函数就变成了
1 | void Delay_ms(uint xms) //@12MHz |
这里的部分我们放到所以sbit下面,作为自定义函数。
如果在程序内需要引用,这样使用:
1 | delay_ms(500);//将延时函数循环执行500次,即延时500ms |
于是,我们的主函数就变成了
1 | void main() |
每次都要把L1到L8都写一遍。是不是这样写太麻烦了?还有一个更简单的写法。
把L1到L8对应的数字改写成16进制,
主函数部分更改为
1 | while(1) |
另外需要注意的一点是,每次LED的初始状态需要为熄灭状态。
所以我们这样写:
1 | void init()//init函数为初始化LED |
注:我后续写程序的思路是模块化编程,每个功能尽量使用一个函数来实现。
例如:刚刚写的LED程序,改成如下:
1 | void led() |
那我们的主函数就变为了:
1 | void main() |
逻辑运算符
通过取反操作符,我们还能简化led的程序
1 | void led() |
可以这么做的原因的我们在init()中已经把P0全部熄灭了,在led的程序中我们使用取反操作符就刚好能把0x00全部取反为0xff,也就是把熄灭变为点亮。
流水灯
讲完上面最麻烦的方法,逐一定义每个灯可以实现,不过,我们有运算符,那么,我们流水灯的代码也就不复杂了。
1 | void main() |
这样的话,程序的循环体每次执行一次,我们的P0的值就会从11111变为01111,00111,00011…..从而达到流水灯的效果。
PS:从左到右