为了准备蓝桥杯我们首先要弄清楚蓝桥杯指定的CT107D平台的原理图,这样才能在编程上面得心应手。刚开始看到原理图的时候,大家一定会有点感觉蒙,没关系的,因为是编程的比赛,因此在硬件上面我们只需要熟悉硬件的各种操作就行了,不需要去详细理解和设计硬件。
首先我们来认识一下蓝桥杯上面会用到的基础门电路和各种标识的意思
一 必须要知道的一些基础
(1)或非门(这个门电路是组合式,也就是或门和非门组合,先进行或操作,再进行非操作)
(2)这种带有J的是跳帽的意思(跳帽就是将两个针脚连接的工具)
(3)74HC138(俗称38译码器)
此器件是蓝桥杯板子上进行操作的基础,因为各种对外设的操作大多需要从它开始,接下来就详细说一下这个器件,大家可以上网搜一下它的datasheet或者中文手册,我通俗说一下它的功能,听懂了就好
上面标识的ABC是它的输入管脚,下面的G1、G2A、和G2B不用管,这是让器件工作的部分,右边的Y0-Y7则是它的输出。我们需要了解的是它的真值表,下面看表
我们可以看到CBA组成了一个3位二进制的数,例如当CBA是101的时候(也即十进制的5),右边的Y5为0,其它都为1,当为111的时候(十进制的7)右边Y7为0,其它都为1。因此我们懂得了P25、P26、P27管脚输入的电平是控制选择Y0-Y7谁为0的功能。
(4)38译码器+或非门+跳帽
我们可以看到图上这种有同样名称的线,这种表示它们是电气连接的,也就是连接起的。好的,接下来说一下这部分的意义。
我们可以在板子上面找到J13的这部分,上面标着有IO和MM,这是两种不同的编程方式,IO就是我们操作IO来进行各种操作,而MM是就是通过存储器映射来编程,它是操作外部扩展RAM的一种编程方式。两种方式都可以,不过,我推荐用IO,因为现在的蓝桥杯比赛都开始硬性要求用IO来进行编程了,有兴趣的同学可以选择MM编程。
如果选择了IO编程,则上面J13图片上的跳帽则是WR和GND是相连的
因此现在或非门的一个输入引脚已经定死了是GND低电平,如果另外一个输入引脚为高的话,则输出为低电平;如果另一个引脚为低电平的话,则输出为高电平。现在的或非们已经变成了一个非门了。
再看连接,我们可以看见我们只使用了Y4、Y5、Y6、Y7这四个38译码器引出来的引脚。那么我们接下来试一下操作P25-P27
比如CBA输入101,则Y5为0,其他Y某都为1,看右边,则Y5C为高,其他Y某C都为低电平。
那么最终总结就是P25-P27就是操作Y5C-Y7C谁为高电平的功能,并且其中一个为高电平的时候,其余都为低电平(如果还不能理解,只记住这一句就行了)
(5)74HC573(俗称锁存器)锁存器,它的名字已经把它的功能说出来了,就是锁定数据的意思。那么为什么我们需要用到锁存器呢?这是因为我们进行单片机的硬件设计的时候,经常用到很多的硬件,这个时候大量的硬件当然就有大量的引脚去进行连接,但是单片机的引脚最多就只有这么多,怎么进行连接呢?锁存器就可以很好的解决这个问题。
下面来通俗说一下这个器件的功能。VCC和GND不用管,左边的P00-P07连接的是单片机的P0口。最重要的是左边的Y4C,这是74HC573这个器件的是否数据选通控制端口,也即是如果Y4C为高电平的话,则将左边的P00-P07的端口状态传到右边的对应Q1-Q8端口,如果Y4C为低电平的话,则将当前Q1-Q8端口的状态锁定,左边的P00-P07的变化不会对右边的Q1-Q7端口状态产生影响。
我们可以通过原理图看见对应的Y4C-Y7C都连接有一个74HC573设备,并且这四个器件的数据输入端都连接的单片机的P0口,那么用意就很明显了,结合之前的138译码器。
我们再做一个总结就是38译码器的CBA(即P25-P27)其实最终是确定这四个74HC573器件,哪一个拥有获取P0端口数据的权利,并且在确定后,其它的74HC573器件都处于锁定状态!而每一个74HC573器件右边都连接的外设(即各种功能器件),所以通过对P25-P27的选择,然后对P0端口进行数据赋值,我们就可以完成用一个P0端口(P00-P07)来完成操作它4倍的数据端口,这种思想就是分时复用的思想,可以好好体会一下
-----------------------------------------------2019-12-30后面继续更
锁存器控制
在有了上述的介绍后,蓝桥杯中一个最为关键的一行代码就可以写出来了,那就是外设的操作(为了方便调用,写成宏的方式)
#define Select( x ) P2 = ( P2 & 0x1f ) | ( x << 5 ); P2 = ( P2 & 0x1f )
这是一个非常关键的代码,先来对这行代码进行分析,请务必搞懂。P2 & 0x1f (0x1f也即0x00011111)在前面我们已经说了"与"的含义了,这句话就是将P2端口的高3位(P27 P26 P25)给置零,然后P2 & 0x1f | ( x << 5 ),也即将X左移5位和刚才高三位置零的P2的值相或,比如x如果等于4,那么流程如下(注:x为任意电平) (假如P2为xxxxxxxx)
P2 & 0x1f 的值为 000xxxxx
P2 & 0x1f | ( x << 5 )值为 100xxxxx
然后再将这个值赋值给P2,那么就实现了通过不同的x来操控P2的高三位的值,也即能够操作锁存器的开关了,这个非常重要。
P2 = ( P2 & 0x1f ) 这个和前面的代码不是同一句,可以看见它前面是有分号的,这句话是为了在操作完成后,锁定该锁存器!这个也是非常关键的,如果不锁住,后面的操作就可能会对其造成干扰!
那么在程序的开始,我们就可以这样写
//设备映射
enum{ LED = 4 , EXT , DIGSEL , DIGCODE };
#define Select( x ) P2 = ( P2 & 0x1f ) | ( x << 5 ); P2 = ( P2 & 0x1f )
sbit BEEP = P0^6; sbit RELAY = P0^4;
关于enum的用法,这里程序的意思是创建这些枚举变量,并且只要给出了第一个起始的值,那么后面的值就会递增的(这里LED = 4 , EXT = 5 ,DIGSEL = 6..... ),为什么我要用这个呢?我是为了方便看并且写起来也快,当然是可以写为一下宏定义
#define LED 4
这里这个4还有5这些是根据锁存器来的,比如
这里就可以看到这个Y4C就是它的标号了,因此4是操控LED的。这个标号我建议是自己背住,为自己写程序节约时间。那么我们现在就来写一下蓝桥杯经常写的初始化程序----上电关闭蜂鸣器和继电器!
void main()
{
//外设初始化
BEEP = 0;
RELAY = 0;
Select( EXT ); //大致步骤就是先准备好要放在P0上的数据,然后打开对应锁存器,然后马上关闭!
P0 = 0xff; //最好不要先打开锁存器,放上数据,再关闭,这样在打开的时候会有未知的干扰!
Select( LED );
}
怎么样,是不是很简单?没错就是这么简单,每当我看其他教程长长的一部分我就觉得有点误导,因为有很多重复的部分会占据大部分空间,让程序写起来很烦。有人会说,没事啊,我可以复制粘贴就行了.......完全没必要,我们写程序,就是要将程序中变得部分找出来,想用的部分找出来,而不变、重复的内容便可以加以总结而简单给出,也能使整个程序界面变得更加简单明了。
到这里为止蓝桥杯很重要的关于锁存器的操作一项就告一段落了,据说每次比赛还有不会关蜂鸣器的同学......,好像关个蜂鸣器也有获得省三的......
------------2020/5/18
这里关于基础部分就好了,后面会出关于外设等操作的相关知识,希望参加蓝桥杯的朋友能够关注!