第2章 STM32单片机I/O端口与伺服电机控制

本章教你如何用STM32单片机的输入/输出端口来控制发光二极管的闪烁,以及控制机器人小车伺服电机,让它运动。为此,你需要理解和掌握用STM32输入/输出端口的配置方法,控制伺服电机方向、速度和运行时间的相关原理和编程技术。

2.1 STM32单片机的输入/输出端口

控制机器人伺服电机以不同速度运动是通过让单片机的输入/输出(I/O)口输出不同的脉冲序列来实现的。STM32-M3单片机有5个16位的并行I/O口:PA、PB、PC、PD和PE。这5个端口,既可以作为输入,也可以作为输出;可按16位处理,也可按位方式(1位)使用。图2.1是基于ARM Cortex-M3内核的STM32F103xx单片机引脚定义图,这是一个标准的100引脚LQFP封装的芯片。

图2.1 基于ARM Cortex-M3内核的STM32F103xx单片机引脚定义图

LQFP也就是薄型QFP(Low-profile Quad Flat Package),是指封装本体厚度为1.4mm的QFP。QFP封装的中文含义叫方型扁平式封装技术(Quad Flat Package),该技术实现的CPU芯片引脚之间距离很小,引脚很细,一般大规模或超大规模集成电路采用这种封装形式,其引脚数一般都在100以上。该技术封装CPU(如STM32F103xx)时操作方便,可靠性高,而且其封装外形尺寸较小,寄生参数减小,适合高频应用。该技术主要适合用SMT表面安装技术在PCB上安装布线。本书所用教学开发板上还有SOT封装的稳压电源芯片,SOP封装的RS-232通信芯片,0603封装的电阻和电容,这些都是SMD表面贴装器件。

任务一 认识封装

封装就是指把硅片上的电路管脚用导线接引到外部接头处,以便与其他器件连接。封装形式是指安装半导体集成电路芯片用的外壳。它不仅起着安装、固定、密封、保护芯片及增强电热性能等方面的作用,而且还通过芯片上的接点用导线连接到封装外壳的引脚上,这些引脚又通过印制电路板上的导线与其他器件相连接,从而实现内部芯片与外部电路的连接。芯片内部必须与外界隔离,以防止空气中的杂质对芯片电路的腐蚀而造成电气性能下降。另外,封装后的芯片也更便于安装和运输。由于封装技术的好坏还直接影响到芯片自身性能的发挥和与之连接的PCB(Printed Circuit Board,印制电路板)的设计和制造,因此它是至关重要的。

封装主要分为DIP(Dual ln-line Package,双列直插式封装)和SMD(Surface Mounted Devices,表面贴装器件封装)两种。其中,SMD是SMT(Surface Mounted Technology,表面贴片技术)元器件中的一种。当代集成电路的装配方式从通孔插装(Plating Through Hole,PTH)逐渐发展到表面组装(SMT)。从结构方面,封装经历了最早期的晶体管TO(如TO-89、TO92)封装发展到了双列直插封装,随后由PHILIP公司开发出了SOP小外型封装;从材料介质方面,包括金属、陶瓷、塑料、塑料等。目前很多高强度工作条件需求的电路,如军工和宇航级别仍用大量的金属封装。封装大致经过了如下发展进程:

结构方面:TO→DIP→PLCC→QFP→BGA→CSP;

材料方面:金属、陶瓷→陶瓷、塑料→塑料;

引脚形状:长引线直插→短引线或无引线贴装→球状凸点。

几种常用封装

TO:Transistor Out-line,晶体管外形封装。这是早期的封装规格,如TO-92、TO-220等都是插入式封装设计。

SIP:Single In-line Package,单列直插式封装。引脚从封装一个侧面引出,排列成一条直线。当装配到印制基板上时封装呈侧立状。如一般的三极管就是SIP3封装。

DIP:Dual ln-line Package,双列直插式封装,引脚从封装两侧引出,封装材料有塑料和陶瓷两种。DIP是最普及的插装型封装,应用范围包括标准逻辑IC,存储器等。

PLCC:Plastic Leaded Chip Carrier,带引线的塑料芯片载体。表面贴装型封装之一。

QFP:Quad Flat Package,四侧引脚扁平封装。表面贴装型封装之一,引脚从四个侧面引出呈海鸥翼(L)型。基材有陶瓷、金属和塑料三种。QFP的缺点是,当引脚中心距小于0.65mm时,引脚容易弯曲。为了防止引脚变形,出现了几种改进的QFP品种。如BQFP(Quad Flat Package with Bumper),带缓冲垫的四侧引脚扁平封装。在封装本体的四个角设置突起(缓冲垫)以防止在运送过程中引脚发生弯曲变形。

QFN(Quad Flat Non-leaded Package),四侧无引脚扁平封装。表面贴装型封装之一。现在多称为LCC。QFN是日本电子机械工业会规定的名称。封装四侧配置有电极触点,由于无引脚,贴装占有面积比QFP小,高度比QFP低。但是,当印刷基板与封装之间产生应力时,在电极接触处就不能得到缓解。因此电极触点难于做到QFP的引脚那样多,一般从14~100。材料有陶瓷和塑料两种。当有LCC标记时基本上都是陶瓷QFN。

BGA:Ball Grid Array,球形触点阵列,表面贴装型封装之一。

SOP:Small Out-line Package,小外形封装,是从SMT技术衍生出的,表面贴装型封装之一。引脚从封装两侧引出呈海鸥翼状(L字形)。材料有塑料和陶瓷两种。SOP封装的应用范围很广,后来逐渐派生出SOJ(Small Out-line J-lead,J型引脚小外形封装)、TSOP(Thin SOP,薄小外形封装)、VSOP(Very SOP,甚小外形封装)、SSOP(Shrink SOP,缩小型SOP)、TSSOP(Thin Shrink SOP,薄的缩小型SOP)及SOT(Small Out-line Transistor,小外形晶体管)、SOIC(Small Out-line Integrated Circuit,小外形集成电路)等,在集成电路中都起到了举足轻重的作用。

CSP(Chip Scale Package),是芯片级封装的意思。CSP封装是最新一代的内存芯片封装技术,可以让芯片面积与封装面积之比超过1:1.14,已经相当接近1:1的理想情况,绝对尺寸也仅有32平方毫米,约为普通的BGA的1/3,仅仅相当于TSOP内存芯片面积的1/6。CSP封装线路阻抗显著减小,芯片速度随之大幅度提高,而且芯片的抗干扰、抗噪性能也能得到大幅提升,这也使得CSP的存取时间比BGA改善15%~20%。CSP技术是在电子产品的更新换代时提出来的,它的目的是在使用大芯片替代以前的小芯片时,其封装体占用印刷板的面积保持不变或更小。正是由于CSP产品的封装体小、薄,因此它的手持式移动电子设备中迅速获得了应用。

STM32F103引脚

STM32F103系列微控制器随着后缀的不同,引脚数量也不同,有36、48、64、100、144引脚。图2.1所示的STM32F103Vx系列共有100根引脚,其中80根是I/O端口引脚,而STM32F103Rx系列有64根引脚,其中51根是I/O端口引脚。这些I/O引脚中的部分I/O口可以复用,将它配置成输入、输出、模数转换口或者串口等。

与标准51单片机比较,一些高级的单片机或者微处理器,如基于ARM Cortex-M3的STM32系列单片机、基于ARM9的S3C2410/2440等都需要进行I/O口功能的配置。

对于STM32F103xxyy系列:

第一个x代表引脚数:T代表36引脚,C代表48引脚,R代表64引脚,V代表100引脚,Z代表144引脚。第二个x代表内嵌的Flash容量:6代表32K,8代表64K,B代表128K,C代表256K,D代表384K,E代表512K。

第一个y代表封装:H代表BGA封装,H代表LQFP封装,U代表QFN封装。第二个y代表工作温度范围:6代表-40~85℃,6代表-40~105℃。

你现在明白F103VB、VC、VE等的含义了吧。这种组合不是任意的,如没有STM32F103TC等。更详细的STM32系列单片机的编号说明见附录。

说到这里,你或许马上就会问:处理器的这些引脚端口是什么作用,是作为输入、还是输出、或者是其他什么功能呢?这与处理器各I/O端口的内部结构有关。后面的章节会根据不同的任务逐步介绍它们的原理和使用方法。本章主要介绍如何用PA~PE口来完成发光二极管的闪烁、机器人小车伺服电机的控制。如果将PA~PE口作为输出时,需要进行相关的配置,配置好后,只需向该端口的各个位输出你想输出的高低电平信号即可。

任务二 单灯闪烁控制

为了验证某个端口的输出电平是不是由你编写的程序输出的电平,可以采用一个非常简单有效的办法,就是在你想验证的端口位接一个发光二极管。当你输出低电平时,发光二极管亮;输出高电平时,发光二极管灭。电路图如图2.2所示。

图2.2 发光二极管电路图

在本任务中,使用PC13来控制发光二极管以1Hz的频率不断闪烁。

例程:Led_Blink.c

● 接通板上的电源;

● 输入、保存、下载并运行程序Led_Blink.c(整个过程请参考第1章);

● 观察与PC13连接的LED是否周期性的闪烁。

    #include "stm32f10x_heads.h"
    #include "HelloRobot.h"
    int main(void)
    {
      BSP_Init(); //开发板初始化函数
      USART_Configuration();
      printf("Program Running!\n");
      while (1)
      {
        GPIO_SetBits(GPIOC,GPIO_Pin_13);  //PC13输出高电平
        delay_nms(500);                   // 延时500ms
        GPIO_ResetBits(GPIOC,GPIO_Pin_13);// PC13输出低电平
        delay_nms(500);                   // 延时500ms
        }
    }

Led_Blink.c是如何工作的?

先看while(1)逻辑块中的语句,两次调用了延时函数,让单片机微控制器在给PC13引脚端口输出高电平和低电平之间都延时500ms,即输出的高电平和低电平都保持500ms,从而达到发光二极管LED以1Hz的频率不断闪烁的效果。

头文件HelloRobot.h中定义了两个延时函数:void delay_nms(unsigned int i)与void delay_nus(unsigned int i)。

    void delay_nus(unsigned long n)  //延时n us:n>=6,最小延时单位6μs
    {
      unsigned long j;
      while(n--)                    // 外部晶振:8M;PLL:9;8M*9=72MHz
      {
        j=8;                        // 微调参数,保证延时的精度
          while(j--);
      }
    }
    void delay_nms(unsigned long n) //延时n ms
    {
      while(n--)                    // 外部晶振:8M;PLL:9;8M*9=72MHz
        delay_nus(1100);            //1ms延时补偿
    }

无符号长整型数据unsigned long

与长整型数据long相比,无符号长整型数据unsigned long只有一个区别:数据的取值范围从-2147483648~+2147483647变为0~4294967295,也就是说它只能取非负整数。基于ARM内核的微处理器(S3C2410/2440)或者单片机(STM32系列)是32位的,所以Keil MDK开发环境中整型int数据与长整型long数据相同,占用4字节;若在Keil uVision3中开发8位的51单片机程序,则整型int数据占用2字节,与短整型short数据相同。注意它们的范围有所不同。

delay_nus( )是微秒级的延时,而delay_nms( )是毫秒级的延时。如果你想延时1s,可以使用语句delay_nms(1000);1ms的延时则用delay_nus(1000)来完成。

注意:上述的延时函数是在外部晶振为8MHz,内部锁相环(Phase Lock Loop,PLL)设置为9 倍频的情况下设计的,这两个函数所产生的延时都经过示波器测试过。如果外部晶振频率不是8MHz,调用这两个函数所产生的真正延时就会发生变化。晶振电路如图2.3所示。图2.3(a)是系统晶振电路。

图2.3 晶振电路

晶振的作用

单片机要能工作,就必须有一个标准时钟信号,而晶振就是为单片机提供标准时钟信号。晶振的作用类似人的心跳,只有晶振起振了,嵌入式系统中的处理器才能工作、执行代码、实现特定功能,完成应用程序任务。因此,如果系统不工作应注意查看晶振是否起振了。可以用示波器测量晶振引脚处是否有信号。

如果将晶振比喻为人的心跳,那么电源输出电流就类似于流经人全身的血液。因此晶振和电源在嵌入式系统中的作用,就相当于心脏和血液对于人的作用,你说重不重要!晶振不稳定就相当于心率不齐。没有电源,电源不能输出电流,就相当于没有血液,或血液不流动。在后面的实时时钟章节中,将会更详细的介绍晶振。

注意STM32上电默认是使用内部高速RC时钟(HIS),因此,判断STM32单片机最小系统是否工作用示波器检查OSC引脚是否有时钟信号是错误的。

如何选择晶振

对于一个高可靠性的系统设计,晶振的选择非常重要,尤其设计带有睡眠唤醒(往往用低电压以求低功耗)的系统。这是因为低供电电压使提供给晶振的激励功率减少,造成晶振起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因是上电时电路有足够的扰动,很容易建立振荡。在睡眠唤醒时,电路的扰动要比上电时小得多,起振变得很不容易。在振荡回路中,晶振既不能过激励(容易振到高次谐波上)也不能欠激励(不容易起振)。晶振的选择至少必须考虑谐振频点、负载电容、激励功率、温度特性、长期稳定性。

如何选择晶振电容

(1)因为每一种晶振都有各自的特性,所以最好按芯片制造厂商所提供的数值选择外部元器件。

(2)电容值小,容易起振;但过小,振荡器容易不稳定。电容值大,有利于振荡器的稳定;但过大,将会增加起振时间,不容易起振。一般选择合适的中间值。