我们通常使用AD或者EDA去画一块电路板,它的整体思路是:
选择芯片、搭建元件图库
搭建最小系统原理图
搭建外设原理图
PCB、打印信息送厂、测试芯片稳定性
要知道怎么搭建外设,首先要知道单片机IO口的工作原理。
在上一小节当中,我们已经成功地搭建出了一个单片机的最小系统原理图,这意味着现在你已经能够正常烧录并且对你的单片机进行开发,让某个引脚实现它的功能。
能够看出的是,最小系统的原理图中电路引脚连接哪个脚基本都是固定的,而到了这一节,剩下的就是功能引脚了,也被称为普通IO口,你可以从任何引脚引出,实现任何你想实现的功能(前提是你的编程能力足够好)。
但是你会有疑问,在你第一次看到芯片原理图的时候,你会发现每个引脚背后都会有不同的注释,这不应该是代表了这个芯片不同引脚有不同的功能吗?那为什么还说任何引脚都能够引出呢?这其实就是单片机一直在进步以及STM32能够被广为接收的原因之一。
如下图,红色部分是我们搭建好的固定的最小系统电路引脚,蓝色部分是功能引脚,也称为普通IO口(当然像下载接口那一类其实也是普通IO口写出来的功能,这里面说的固定引脚可以不包含下载电路的引脚,因为之间说下载电路的时候,其实是可以通过外接模块来下载的):
可见,STM32功能性引脚即普通IO口从PA一直到PG,一共七组,按我之前说的,如果任何普通IO引脚都可以实现任何功能的话,选择是很多的,事实的确是这样,你确实可以用任何IO口实现你想实现的外设功能,比如中断、定时器、串口、IIC、SPI、CAN等等,那么原理图上每个引脚后的注释的意义是什么呢?
关键在于模拟/非模拟:
你会发现当你去按例程或者看视频导入文件时,特别在学习初期,会导入很多STM32F4xx_XXX.c的文件,基本上全部导入。以STM32F4xx_tim.c为例,这个.c文件中实际上是写好了定时器的功能,事实上,你也只需要在你需要用到定时器的时候导入这个.c文件即可。
好了,当你导入了这个文件之后,你就可以在你自己新建的.c文件中去调用定时器那个.c文件对应的.h文件(因为.c文件的所有函数是被声明在.h文件中的)、初始化对应比如定时器1的所有功能,当你不懂上网搜的时候,就会有很多代码例程,会说某一句是配置某个定时器寄存器的某个模式,使能某个功能的语句等等,最终就可以使用某个功能了。但是这个功能最后的输出通道(也就是输出引脚)是固定的,这个时候你往往会去看原理图,找到这个功能对应是输出是在哪个引脚上的,然后你才能用导线连接到你的传感器或者一些驱动元件上。
以上的例子我相信你应该已经经历过,通俗点说,这相当于你是正点原子,比如你写了一个如何计算圆的面积的.c文件,然后用户现在想要计算圆的面积。他在导入了你写的.c和对应的.h文件后,就只需要初始化圆的半径,使能一下那个计算面积的通道就行。现在比如最终的结果会通过高低电平从引脚输出出来。
那么当他使用你的这个函数时,他想要知道最终的结果就得去找你当时是把输出结果的通道写在了哪个IO口上(哪个引脚上),最直接的办法就是去查你的原理图。
那么你是如何要让他知道原理图上哪个引脚是这个输出面积的功能呢?显然,你肯定会在你给他发货的原理图上,在对应的那个引脚后面加上类似于“mianji”的注释。
同理这也就是为什么你购买的正点原子开发板原理图上引脚后面会有那么多注释的原因。这意味着你只用导入相关功能的头文件,初始化即可使用对应引脚的功能。
我们通常说模拟IO口,所谓模拟,顾名思义就是这个IO口上并没有某种功能,而是你自己写的。比如PA1和PA2没有串口的功能,而你现在没有串口可用或者没有多余的引脚可用了。那么你就只能自己写一个串口协议的发送函数给PA1,写一个串口协议的接收函数给PA2,然后自己调用自己写的函数,最终也能实现串口的功能。同理对于单片机上任何功能都是如此,只要你编程能力足够强大,对这款单片机底层认识足够深,你可以直接模拟定时器、中断等等功能。
其中圈出的部分就是厂商对自己已有功能的描述,这意味着他告诉你他已经写好了哪些函数,也就是说你可以直接调用、初始化使能他对应的功能。而广义上来说,就连普通IO口也是一个引脚的功能之一,51单片机的“reg51.h”头文件就定义了IO口的位置,而IO口的功能就是输出高低电平的。对于STM32来说,普通IO的功能都被放到了STM32F4XX_gpio.c文件中,事实上,STM32对普通IO口电路上的改造使IO口的功能变得更为强大,远远不是高低电平变换那么简单。
显然对于简单的单片机,比如下图的51来说,功能就很少了,比如只有串口、中断、定时器的功能,而且就那几个引脚有。这就导致我们有的时候需要某个功能的时候只能去模拟出那个功能来。这就是为什么说STM32足够强大,被很多人接收的原因之一,他的功能远超51等单片机。
至此你知道了单片机原理图上每个引脚上的注释代表了那个引脚拥有的功能,所以你就可以需要什么功能就把对应引脚在原理图上引出来即可,如果你需要外接一个CAN口或者IIC接口的话,就直接把对应的引脚拉出来吧。这也就是当时选择画主控的优势的体现,你可以将学习板上多余的功能去掉,变成你想要的任何接口。
比如你想要外接一个2.4G的无线通信模块,它的接口原理图如图所示:
你能发现引脚MISO、MOSI、SCK、CSN决定2.4G模块是用SPI通信协议(SPI通信一共使用4根线)连接到单片机的,这就意味着最简单的办法就是找到单片机上具有SPI功能的引脚相连即可。
当然你要是觉得外接模块这种做法太低级,也可以直接将2.4G模块本身画到电路里:
其中红圈内是刚刚提到的2.4G模块接口,旁边大块就是2.4G模块本身,其核心是2.4G的芯片,将其与2.4G模块接口接好,再接入单片机对应的引脚即可。
当然你需要去查看2.4G的芯片手册和SPI通信协议的内容,来搞清楚具体如何判断,使用这块芯片,我在这只是给你如何连接外设的思路。
很多时候我们需要在通信线上串联上小电阻,一般为22、27、33/100欧姆:
原因主要有两种情况:
①如果是在高速信号线上放上小电阻,往往是用来做阻抗匹配的,以此来减少信号的反射,避免振荡。一般传输线的特征阻抗为50欧姆左右,而TTL电路输出电阻大概为13欧姆左右,在源端串一个33/22欧姆的电阻,13+33=46大致和50相当,这样就可以抑制从终端反射回来的信号再次反射。
②如果是在GPIO口上串联小电阻,因为GPIO引脚是要引入单片机的,所以是用来防止短时间插拔导致过压损害单片机的情况出现,一般为100欧姆。
上拉电阻的作用就是在某个线路空闲时拥有高电平的状态,比如IO口防止单片机工作不稳定。通信线上加上拉电阻来防止通信错误。
上拉电阻的选择,主要是参照你所用的MCU和你外接的电路来选择。比如说有的MCU,是5V供电,他的I0口在低电平状态时能够通过的电流为2MA,IO口的低电平是小于0.5V 。
如果你选择的是10k,当MCU为低电平时,通过的电流为0.5MA,IO口端的电压为0.1V,那么这个状态很好,满足要求。如果选择的是1k,单片机内部是有内阻的,电阻过小,会导致通过IO口的电流过大烧坏单片机,因为单片IO内部是有内阻的,电流大了分得的电压就越大,有可能导致IO口末端的电压大于0.5V,单片机认为不是低电平,数据出现错误。
总之,上拉电阻越大,功耗越低,但要保证通过的电流能驱动外设和IO口。上拉电阻越小,功耗越大,但要保证为低电平时,IO口不会误读。
综上,一般5.6K到10K之间的上拉电阻是比较好的。
电容因为其滞后性的特点,最大作用就是滤波,稳压,在电源和读取电路中发挥了很大作用。以按键电路为例,加入电容可以有效防止按键抖动。将抖动的波形变成了平滑、稳定的上升沿或下降沿波形,这样对于IO口的识别就很容易、很稳定了。
通常,我们在设计原理图时,要同时考虑到做出来之后呈现的效果,也就是要考虑到人机交互的部分。你要知道此刻这个板子是否是通电状态,或者某个模块是否在工作状态,最直接的办法就是在电路上加上一个LED灯(最好不要用程序去代替电路)。
PS:设计整块电路板的时候,需要考虑很多事情,而且需要不断地积累,上文所说的一些电阻的选择也是我仅有的一点经验之谈,你需要不断去查资料,去尝试才知道最好的效果或者为什么要加那个电容、电感等元件。