由于在嵌入式学习笔记那个系列的所有开发都是用的寄存器,而实际工作中使用更多的还是库函数,为了完善一下,笔者就想着先整个基础库笔记,但是又像之前那样记录又觉着太麻烦了,所以就打算自己做个板子,综合使用一下之前的东西,然后围绕着这个板子的硬件来做一些记录,于是就有了此系列。
有了这个打算后,51假期就试着画了这个板子;功能大约包括如下内容:
序号 | 需要使用到的外设 | 功能 | 备注 |
---|---|---|---|
1 | 普通GPIO | 控制继电器 | 推挽输出 |
2 | 普通GPIO | 控制WS2812B | 推挽输出 |
3 | 普通GPIO | 控制74HC138译码器 | 推挽输出 |
4 | 普通GPIO | 按键输入 | 输入模式 |
5 | 定时器比较输出 | 控制直流电机转速 | 复用功能 |
6 | 定时器比较输出 | 控制SG90舵机角度 | 复用功能 |
7 | 定时器输入捕获 | 获取红外输入 | 复用功能 |
8 | 硬件SPI | 控制0.96OLED屏幕 | 复用功能 |
9 | USART 1 | 与电脑通信 | 复用功能 |
10 | USART 2 | 联网 | 复用功能 |
11 | USART 3 | 与语音识别模块通信 | 复用功能 |
12 | 模拟IIC | 与AT24C02通信 | 推挽、开漏 |
13 | ADC | 通过电阻分压实现按键检测 | 复用功能 |
14 | PWM | 红外发射 | 这个还未验证 |
15 | 步进电机 | ULN2003达林顿管 | 设计出问题了需要修改 |
16 | DHT11温湿度 | 温湿度采集 | 开漏输出 |
整个板子的功能已经验证的差不多了,中间遇到了几个问题,后面介绍时也会说到。
其实根据上面的需求表,已经有很多东西都固定型号了,比如WS2812B、74HC138、AT24C02、ULN2003这些,然后为了实现对应的功能必须选用合适的单片机,综合统计一下上面需求表用到的外设内容,3个串口、一组SPI、一个ADC、定时器至少3个,还需要足够数量的GPIO,根据这些需求暂时选定了两款单片机,一个是STM32F401,一个是STM32F103
统计了一下所需的GPIO数,35个GPIO就可以完成整个项目了。也就是说选用48脚的型号就可以了。
最终选择了103C8t6,原因嘛,有以下几点:
1.在401的封装介绍部分可以看见,是没有LQFP-48封装的,只有WLSP-49和UFQFPN-48的两种封装,这两种封装的好处是体积小,占用板子空间小,但是,笔者手头只有一把黄花,面对这俩,属实显得有些无力,虽然立创那边有价格相对美好的贴片,但也是一笔额外开支啊
而STM32F103就有LQFP-48的四面表贴型封装,这种封装一个刀头的烙铁还是可以拿下的。
2.前面的嵌入式学习笔记一直用的都是M4的单片机,这次想换一个,换成M3来,虽然性能比M4差一点,但是对于这个小项目是完全够用的。
3.最后一个原因当然是103的价格了,过去那段20+买一块C8T6的时期终于过去了,现在的价格终于可以稍微放心造了,而且选C8t6的话,不出意外,还可以拿GD的来替代使用,这样主控的价格就有可以下来差不多一半,当然截止到此时,笔者还没试过用GD替换,虽然买了一块,但是还没焊,GD大约4块钱一块,ST差不多8块钱一块。
整个板子都是3.3V和5V的电平,这里笔者使用的的是之前参加立创的训练营还剩的Typec以及友顺的UZ1084LDO芯片来实现供电方案的。当然,这颗友顺的LDO用在这里显得有些屈才了,而且对比常用的AMS117-3.3的价格也是差了将近十倍,不过自己做了玩,问题不大。
给大家一个建议啊,当你想要一个电路但是又不知道该怎么做时,去立创的开源广场逛一逛,里面有很多类似的设计,把他们已经验证过的电路cv过来就可以了,就像这个直流电机的驱动,如果你不知道该用啥芯片就去开源广场搜,由于智能小车是必要用到直流电机的,那么也肯定有对应的驱动方案。
这里笔者一共捞了三个芯片方案,1是立创那边自己做的的例程小车板用的驱动芯片是RZ7889,另外一个是L9110S还有一个是比较好的TI的DRV8833;这里我选择了最便宜的L9110S,主要是这里就模拟一个风扇的转速,实在是没必要整这些好的芯片方案。
但是,这里有必要强调一下TI(德州仪器)的芯片贵是贵了点,不过它芯片的资料绝对是学习硬件以及PCB设计的一个宝藏资料。就拿这个DRV8833的数据手册来说,最直观也是后面layout最重要的一个参考,L9110S是没有layout的指南的,RZ7889有,DRV8833也有,但是其他的描述DRV8833无疑是最全的。
而且,如果你有兴趣去深挖一下的话,在TI的官网你可以找到同一系列的很多资料,比如下面的电机驱动的布局、电流配置方案。
除此之外,TI的产品还有现成的评估板,而且大部分是可以直接下来的,里面有原理图,PCB的Gerber文件甚至是AD工程的源文件都是有的。有兴趣的可以自己去查看。
https://www.ti.com.cn/tool/cn/DRV8833EVM
和电机一样,舵机的驱动也是需要比较大的电流的,为了避免反冲单片机,这里笔者用了一个光耦的隔离电路来驱动,光耦也是用的手头现成的FOD817C。
为了更方便的实现板子与电脑的通信,这里我打算是将USB转TTL的电路放到板子上,在这里也是有很多种方案可以选择,常见的有CH340C、CH340G、CH340N,其实为了电路更简洁的化选用CH340N是最好的选择,因为它内置晶振,且只保留了通信得数据脚,将其他的脚舍弃了。但是笔者这里还是用了CH340G,就是那个需要外接晶振的,电路在这仨中最复杂的,别问,问就是手头现成的只有它,不像再花钱买了。
剩下的就是一些比较常见的芯片或者模块了,联网方面选用的是ESP8266、语音识别用的是笔者多次提到的鹿小班、红外发射管和接收管是IR333和HS0038B、OLED是中景园子的0.96 7脚OLED、温湿度采集用的是DHT11、按键用的是五向开关。
在搞定器件以及模块的选择后,接下来就是原理图的绘制了。在原理图的绘制过程中,要有一个自己的思路,然后按照思路分模块的进行绘制,这样才能尽可能降低出错率。
这里分享一下笔者的思路:
1.首先要解决TM32的最小系统,包括电源、晶振、复位以及boot选择电路;
2.解决了最小系统,要搞定电源输入以及电脑与MCU通信的部分;
3.参照芯片手册的管脚功能为GPIO分配对应的功能;
4.检查。
关于STM32的最小系统的原理图,网上一搜一大把,而且如果你是用立创EDA绘制的话,甚至可以直接copy过来,而且立创官方也给我们提供了参考的样板工程。
当然,有归有,抄归抄,咱还是来瞜一眼那些具体的元器件参数到底是怎么确定的。
在每一款STM32的板子上,都可以在芯片附近看见一个100nf的电容,这个电容的容值就是芯片手册中的要求,它们的主要作用也就是对输入电源进行一个滤波的作用。
注意上图红框中写着5*100nf可不是在同组个VDD和VSS两端并联5个电容;这里的5是分别对应的5组电源输入,观察具体的封装引脚定义,可以发现,STM32F103C8T6的四个面分别有一组VSS和VDD除此之外还有一个VBAT,刚好5组,每组各一个。
在之前的嵌入式学习笔记中,提到过,STM32的外部时钟源,也就是晶振,有两组一个是HSE外部高速时钟,一个是LSE外部低速时钟,关于晶振的频率大小,在数据手册中也已经给出了,其中HSE的晶振范围是0-25MHZ,典型值是8Mhz也就是我们最常见的晶振值。注意,0的时候,也就是没有外部高速时钟,此时编程时要将单片机的时钟源设置为内部高速时钟。同时,数据手册中还给出了典型值的负载电容30pf与反馈电阻的值200kΩ。
外部低速时钟也是同理,使用一个32.768Hz的晶体振荡器,也给出了典型值的负载电容15pf与反馈电阻的值5MΩ。
于是根据这些,我们可以搞定晶振部分的原理图了。
当然实际使用过程中也有使用其他晶振值的,只是要根据官方的指导设置对应的参数即可。在数据手册中也有对应的提示:让我们去ST的官网查看AN2867这个名为“Oscillator design guide for ST microcontrollers”(ST微控制器的外部时钟设计指南)的文件。
这里把链接贴给大家———ST微控制器外部时钟设计指南,纯英哈谁有译文的话可以给我丢一份。
同样的,与TI一样ST官网也是有大把值得学习的资料的,就比如说这里的各类指南,还有中文版,读起来相对轻松一点。网址也贴给大家——ST官网资料
尤其是这个AN1709的ST为控制器EMC设计指南,后面的PCB画板是值得参考的。
关于复位电路,数据手册中也做了介绍的,通过这个表可以看出,NRST的管脚内部是有一个弱上拉电阻的,但是实际是使用过程中,为了保险,还是会再在这个管脚上上拉一个电阻。以保证硬件复位和上电复位的稳定。
然后就是BOOT选择电路,在C8T6的48个IO中有两个管脚是用来配置STM32的启动模式的,分别是BOOT0和BOOT1。
具体的模式如下,一般默认配置为从主闪存存储器启动,为了方便用户使用,会使用拨码开关或者按键来实现模式的切换。
ST官方对于BOOT的模式选择也出了对应的手册工开发者查看,这里还是将链接给大家提出来—— AN2606应用笔记。
除了上面的四个电路以外,还需要搞定一个下载电路,笔者手头有st-link,所以找到对应SW下载所需的管脚SWDID和SWCLK即可,具体的查询还是在数据手册中。
直接在数据手册搜索即可查找到。
为了保证下载的稳定性,一般会在这两个管脚上上拉一个上拉电阻。
至此,一个STM32的最小系统电路就搞定了。
在搞定最小系统后,接下来就是电源部分以及USB转TTL的电路,这里笔者选用了16pin的Type-C作为接口,主要是其他接口我手头没有现成的,而且现在Type-C接口的很常见,比较方便。既然提到了Type-C,这里就再啰嗦两句,对弈第一次使用Type-C的同学来说,需要注意一些内容:
1.在大多数的这种开发板电路中是没有专门的USB管理芯片的,所以需要在Type_C的CC1和CC2脚分别下拉一个5.1k的电阻,以保证你的电脑能够识别到设备并给它供电;
2.16pin的接口并不是所有管脚都用用,我们使用时需要它的两个功能,一是供电,需要使用到VBUS和GND,另外一个就是使用到它的USB通信功能,需要使用到它的D+和D-;由于Type-C是支持两面插拔的,所以上述的管脚都是有两组的,在实际使用过程中要对应连接上。
下图截取自——一文读懂USB TypeC与USB-PD。TypeC引脚定义-24P 16P 6P,CC1、CC2的作用,USB-PD介绍,USB2.0/3.0接口类型一览感兴趣的同学可以去拜读一下。
好了,弄清楚Type-C的接口使用方法后,就可以搞定电源和USB转TTL了;其中电源部分很简单,将5V接入对应的LDO,输出3.3V即可;然后是USB-TTL的部分,这里直接参考CH340G的数据手册绘制原理图即可——文档链接给大家贴出来当然,如果你觉得看手册没把握,也可以像之前电机驱动一样,在立创的广场上去找一找别人用过的电路。
接下来就是具体的功能部分的原理图了,这里也要有一个优先级的思路,对于像串口、硬件SPI、PWM、输入捕获、ADC的这些需要固定映射关系的引脚要先定下来,而模拟IIC、1-wire以及一些使用IO口模拟模拟通信时序的功能优先级放到最后。
好理清思路,那就开干。
首先,根据需求表,我们需要使用到3个串口,所以第一步得通过芯片手册查到每个串口对应的具体的管脚,在管脚功能表一搜就可以发现串口1就有两组管脚,这个再M4中也提到过,同一个外设控制器,是可以通过不同的映射指定到不同的管脚的,只是在代码配置中需要重新映射,为了降低后面编程的复杂度,这里我们都选择默认的管脚。
通过用户编程手册可以一次性查到三个串口默认指定管脚。
由于串口通信的双方是需要交叉连接TX和RX的,所以在原理图连接时要注意:
PA9是MCU的USART1_TX要连接到CH340的RXD上,而USART1_RX(PA10)要连接到CH340的TXD上。
至于剩下的两个串口,因为笔者手头的是模块,所以外接排针接出来就可以了。
功能 | 管脚 |
---|---|
USART1_TX | PA9 |
USART1_RX | PA10 |
USART2_TX | PA2 |
USART2_RX | PA3 |
USART3_TX | PB10 |
USART3_RX | PB11 |
C8T6一共有4个定时器,舵机角度和电机速度控制可以使用同一个定时器来实现,而红外的输入捕获需要单独的一个定时器来实现,而且为了保证机智云的稳定运行,它也需要单开一个定时器提供心跳检测,而且除此之外,整个系统运行时还需要一个定时器来实现时间片的功能。根据具体的需求,进一步划分,
最终决定TIM1作为机智云的心跳产生;TIM2做输入捕获,用来获取红外接收头接收到的数据;TIM3用来做比较输出,产生PWM波形控制舵机和电机;TIM4用来做时间片的产生。
确定好各个定时器的功能后,就可以分频管脚了,同样的,为了避免复用功能重映射,我们尽量选用默认的管脚。最终,根据复用表,选择了定时器3进行部分重映射,然后使用它的通道1和通道2分别对电机和舵机进行控制,定时器2就是用默认模式的通道2来作为红外的输入捕获。
选定管脚后,就根据对应的芯片选型,在芯片手册或者网上找对应的使用电路,有关的驱动电路如下:
这里需要注意L9110S是一个集成了H桥的芯片,控制部分需要有两个输入信号,这里笔者选用的是一路PWM加一路普通GPIO的控制方案,另外一个GPIO选择的是PB3.
至于红外输入的电路也是根据芯片手册参考电路进行绘制即可。
功能 | 管脚 |
---|---|
红外输入捕获 | PA1 |
电机控制PWM MOTOR-A | PB4 |
电机控制IO MOTOR-B | PB3 |
舵机控制PWM | PB5 |
C8T6一共有两组硬件SPI,这里我们选一组来作为和0.96的OLED屏幕通信的接口,这里需用的是SPI2的一组管脚来实现,7脚的OLED一共有5个脚需要我们编程进行控制,其中,MOSI、SCLK用的是硬件SPI2的管脚,剩下的CS、RES、D/C这三个脚使用普通的GPIO口就可以解决实现效果,这里需要注意,原本是SPI2的片选NSS的PB12还有MISO的PB14这里没有复用到SPI上,只是作为普通的GPIO来进行使用。
因此最终的引脚使用如下:
功能 | 管脚 |
---|---|
OLED_MOSI | PB15 |
OLED_SCK | PB13 |
OLED_CS | PB14 |
OLED_DC | PB12 |
OLED_RES | PB6 |
根据需求表,还需要使用一个ADC来作方向按键的电压采集,C8T6的ADC一共有两组10个通道,只要规避掉前面已经用掉的那些GPIO即可,所以这里笔者用了PB0,也就是ADC1或者ADC2的通道8来作为按键电压的采集。
原理图如下:注意WACK_UP并不是使用ADC采集的,是作为普通按键来使用的,占用的是PA0管脚。
功能 | 管脚 |
---|---|
ADC_IN | PB0 |
WACK_UP | PA0 |
至此,需要使用到特定功能的GPIO就已经定下来了,接下来就是搞定其他的使用时序模拟的模块。
然后就是给DHT11整个GPIO来获取温湿度,这个传感器使用的是单总线的协议,随便找一个GPIO口来模拟时序就可以了,这里笔者选择了PA15。提示一下,如果是自己买的四脚的模块的话,DHT11的数据脚记得接一个上拉电阻,笔者是因为手头有一个现成的模块,模块上集成了上拉电阻,所以整个只留一个3pin的排母接口。
功能 | 管脚 |
---|---|
DHT11_DATA | PA15 |
再之后就是WS2812B的RGB灯模块了,WS2812B也是很火的一个外设了,它可以通过一个脚实现多个灯的串行控制,常见的驱动方式有DMA+SPI,PWM+DMA的驱动方式,这两种方案当然是驱动这个灯的最优解,但是笔者这里的定时器都有自己的专用功能,而且SPI的脚位也被用了,所以采取了一个最最原始的驱动方案,使用GPIO延时模拟时序,虽然效果比不上那个前面两种,但也能用。这里笔者使用的是PA8。然后灯条我也是用的模块,8个灯串联的。
功能 | 管脚 |
---|---|
WS2812B_DATA | PA8 |
还有一个继电器的控制电路,继电器的本质是一个电磁铁的导通与关断,但是由于线圈本身等效是一个大电感,不做保护直接驱动的一方面是驱动不了,另一方面有可能烧毁单片机的IO管脚,所以一般会采用三极管的开关电路、或者是用ULN2003这类的达林顿管来驱动,也有使用直接加一个光耦隔离来实现的。这里笔者手头NMOS,所以弄了个用NMOS的开关控制继电器的电路,虽然目前能用,但大家在继电器驱动时都没怎么用过NMOS,这个是有啥坑吗,有佬知道答案的话麻烦解答一下。
下图中的D1是一个肖特基的二极管,作用是当NMOS截止时,用于与继电器的线圈形成回路消耗储存的能量,避免线圈里面的电烧毁击穿MOS。然后R24这个下拉电阻的作用就是避免NMOS的误导通。
这里选用的管脚是PA12。
功能 | 管脚 |
---|---|
继电器控制 | PA12 |
红外发射管的使用也是通过GPIO来控制红外管的导通和关闭来实现的,而具体的实现方案,最常见的也是用PWM来实现,但是需要一个专用的频率,所以笔者这里智能退而求其次,准备使用软件模拟的方案来实现,红外发射的模拟代码,技小新在立创上有过一个例程,这个到此时笔者还在调试,理论上是可行的。至于驱动电路,和上面的继电器一样,笔者选用了一个NMOS的开关电路实现。
为了避免IO模拟用不了,我这里选择了PB7作为红外发射的驱动管脚,实在不行,利用定时器4的PWM应该也是可以搞定的。
功能 | 管脚 |
---|---|
红外发射电路 | PB7 |
看了一下,整个板子,前面已经用到了USART、SPI、1-wire等协议,还有一个常用的IIC没用上,那必然是不能缺少的,于是整了个AT24C02的eeprom,由于模拟IIC随便找俩GPIO都可以搞定,所以这个电路的优先级也放的比较低,排除上面已经用过的GPIO后,笔者选用了PB8、PB9作为IIC的通信引脚,iic的器件一定要注意做好上拉电阻,芯片本身的上拉能力有限,需要使用上拉电阻来提供高电平。然后是A0-A2这三脚是用来设置IIC器件地址的,由于这里就接了一个IIC器件,直接给它都拉低就完事儿了。
详细的介绍可以去看它的芯片手册,这里把链接贴给大家——AT24C02
功能 | 管脚 |
---|---|
IIC_SCL | PB8 |
IIC_SDA | PB9 |
整个系统一直到这里都还算成功,程序也都调通了,使用也都正常,但是这138的电路可以说是一个滑铁卢,原本笔者是打算,利用138译码器,实现3个GPIO控制4个LED以及一个42步进电机的,由于画原理图的时候没太过脑子,闹了一个乌龙,42步进电机是用不了了。具体啥原因呢,这里我把原理图给大家贴过来大家就明白了。
如上图,74HC138使用ADD0-ADD2来实现8种不同的输出,由于138本身的驱动能力是很弱鸡的,所以给他加了个74HC245的三态门,也叫缓冲器,它可以解决138驱动能力弱鸡的问题。这里缓冲器输出的B4-B7四个脚接了LED4到LED7的四个LED,这四个LED也可以正常驱动,没毛病。
但是B0-B3这四个计划用来驱动42步进电机的电路就有毛病了,首先,步进电机需要大电流,加一个ULN2003的达林顿管来驱动这是一个正确的操作,但是问题在于经过138译码器输出的B0-B3在同一时刻,永远只有一个是低电平,经过达林顿管的反向后,真实输出到1C-4C的电平也就是同一时刻只有一个高电平,而步进电机是需要按照节拍表对线圈进行轮流供电才能驱动。
而此电路的A A- B+ B-的输出状态永远只有1 0 0 0;0 1 0 0;0 0 1 0;0 0 0 1这四种状态,所以步进电机是无法驱动的,做个普通的开关控制还行。
设计时不过脑子,整出了这么一个尴尬的电路,有时间的话笔者会将这个板子再修改一版。
在开发板电路中,多多少少都会看见一些保护电路的,目的是保护单片机或者说是保护电脑接口,这里笔者用了三个保护措施
1.在5V电源和3.3V电源端使用各使用了一个稳压管,这样当输入电压超出5.7V时,D10会雪崩导通,将这个超出5V的电压直接通过D10接地,当然,这个时候,稳压二极管是保不住了,会看见稳压二极管冒烟,但是后面的电路不会受到这个高电压的冲击。
2.在电源输入的地方给了个自恢复的保险,这样做的主要目的是因为板子中有电机,有舵机这俩玩意儿万一堵转了,会有一个很大的电流,如果不加保护,很有可能直接干废整个电路,加一个自恢复的保险,可以一定程度上防御这种突发状况。
3.给电机设置了模拟5V和模拟地中间使用0欧姆电阻连接,这样做的主要目的也是防止电机的驱动对整个电路造成干扰。
除此之外,在Type-C的D+和D-也加了一丢丢保护措施,加了个TVS瞬态电压抑制二极管在USB+、USB-和 GND之间,可以预防浪涌或者是静电以及防止过电压。
原理图绘制完毕后,一定要仔细检查,如果有条件的话一定要找专业老辣的人帮你瞅一眼再进行下一步的操作。
确认原理图没毛病后,就可以开始规划PCB了,关于PCB的布局、具体的走线规则这些,如果不熟悉的同学可以去B站找找凡亿的免费课程,跟着把那几个免费课程的板子画了,基本上自己画一些这种小东西的还是没问题的。尤其是他们的整体处理思路、快捷键的设置、规则的设置这些。而且最近凡亿还给出了一个PCB设计的白皮书,虽然是RK3588但是很多东西是通用的,布局思路、电源、晶振、USB的差分处理,这些都是可以借鉴和参考的。
例如外部晶振的包地、尽可能接近主控,走线尽可能短这些都是可以借鉴的。
当然,除了凡亿的这个白皮书,前面提到过的TI的芯片的layout指南也可以借用过来:
还有官方的——ST微控制器EMC设计指南(AN1709)这些都是PCB设计和layout时的重要法宝
以下是笔者的PCB布局,说实话,毕竟毕业后没有干过硬件,整个板子还是有很多的不足的,欢迎各位佬批评指正哈。
对于焊接呢,整个焊接过程遵循先小后大,先焊接电源部分
检查无误后再整最小系统,最小系统可以正常烧录代码后再焊接外界的驱动模块,记得焊接完上电前一定 一定 一定要把助焊剂,锡珠这些用工业酒精洗干净后再上电,别问我为啥刻意提醒,上电冒烟的感觉是真的提心吊胆。
138驱动4个LED
WS2812
DHT11采集温湿度,OLED显示
方向按键调节电机转速
红外遥控控制WS2812B灯条显示不同的颜色
关于整个板子的原理图PCB的介绍就记录到此,文中有不足之处欢迎指出,提出修改意见或者建议既可以免费获取这个项目的硬件工程以及代码工程,代码目前还没编写完,还有机智云、红外发射没弄,其他的都基本实现了。