在之前的文章中,我们介绍了51单片机的IO口、编写语言、三种中断方式(外部、定时器、串口)和常见外设的应用(LED灯、数码管、按键、显示屏、AD、基于I2C协议通信的EEPROM),同时简要介绍了μC/OS-II嵌入式实时操作系统。51单片机结构简单,成本低廉,代码编写也较为容易,因此适宜初学者入门。但在实际的研究和生产领域,低性能的8位51单片机往往无法满足我们对高速、高效硬件控制和处理的需求,在许多情况下,我们需要使用更好的32位单片机平台。
目前主流的嵌入式设备大多基于ARM架构平台。ARM,全称Advanced RISC Machine,即进阶精简指令集机器,其产品在我们的生产生活领域广泛应用。目前所有的手机CPU几乎均基于ARM平台,比如最新款的骁龙888CPU采用的就是1个2.84GHz的ARM最新Cortex X1核心,3个2.4GHz的Cortex A78核心和4个1.8GHz的Cortex A55核心。ARM Cortex系列产品主要分为A、R和M三大系列(最新的X系列基于A系列),手机端的CPU使用的是ARM Cortex A系列,而单片机则普遍选用了ARM Cortex M系列。ARM Cortex R系列是面向实时应用的高性能内核,针对大型工业控制设备,此处不表。下面我们主要介绍一下ARM Cortex M系列。
ARM Cortex M系列目前总共有八款产品,分别为M0、M0+、M1、M3、M4、M7、M23和M33。其中M0、M0+、M1、M23面向低功耗使用。从架构上而言,M0、M0+、M1采用ARMv6架构、M3、M4、M7采用ARMv7架构,M23和M33则采用最新的ARMv8架构。通常情况下,我们使用比较多的是基于M3和M4内核开发的单片机。在众多基于ARM CortexM系列的单片机中,知名度最高,应用最广泛的,就是ST意法半导体公司生产的STM32系列单片机,其中M和32分别表示Cortex M系列和32位。
STM32系列按内核结构分为以下几类:

  • 主流产品:STM32F0及其升级版G0(基于Cortex-M0)、STM32F1(基于Cortex-M3)、STM32F3及其升级版G4(基于Cortex-M4)
  • 超低功耗产品:STM32L0(基于Cortex-M0+)、STM32L1(基于Cortex-M3)、STM32L4、STM32L4+(均基于Cortex-M4)、STM32L5(基于Cortex-M33))
  • 高性能产品:STM32F2(基于Cortex-M3)、STM32F4(基于Cortex-M4)、STM32F7、STM32H7(均基于Cortex-M7)
    -无线产品:STM32WB和STM32WL(均基于Cortex-M4)
    其中,市面上最常见、最主流的入门级产品,是属于STM32F1系列的增强型STM32F103单片机。根据引脚数、Flash和RAM大小、封装和工作温度范围,STM32F103单片机又有许许多多的子产品。详细命名规则如下:
  • 引脚数:T:36、C:48、R:64、V:100、Z:144、I:176
  • Flash和RAM大小:4:16K/6K、6:32K/10K、8:64K/20K:B:128K/20K、C:256K/48K、D:384K/64K、E:512K/64K、F:768K/96K、G:1M/96K(Flash和RAM对应不适用STM32所有产品,具体型号请参考ST官网)
  • 封装:H:BGA封装、T:LQFP封装、U:VFQFPN封装
  • 工作温度范围:6:-40-85℃,7:-40-105℃
    如我们常见的STM32F103ZET6,就表示144引脚,512KFlash,64KRAM,LQFP封装,工作允许温度在-40-85℃。
    由于ARM单片机较为复杂,通常需要调取大量的系统库来进行开发操作。因此STM32系列单片机开发主要采用的是库开发的方式,通过库开发。
    下面,我们以STM32F103C6的仿真为例,演示一下基于库开发的基本开发过程。

    (在Proteus中仿真STM32F103C6需要注意配置供电网,将VDDA连接到GND,VSSA连接到VCC,然后将频率由默认改为72MHz。)
    首先启动Keil选择设备为STM32F103C6。

    然后配置运行需要的库环境。首先选择启动库Startup,然后由于我们用到GPIO口,选择StdPeriph Drivers里面的GPIO。然后根据下方的提示将相应依赖项全部选完。

    添加主函数内容如下
#include "stm32f10x.h"
//引用STM32头文件即可,已自动配置需要包含的其他硬件驱动文件
void LED_Init()//LED相关GPIO端口初始化
{ 
	GPIO_InitTypeDef  GPIO_InitStructure;
	//STM32的GPIO初始化配置需要配置一个结构体
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	//需要使能所用到的PB端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	//设置所需要配置的端口,此处仅配置GPIO_Pin_0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	//设置GPIO口模式推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//设置GPIO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//根据配置结构体初始化GPIOB
	GPIO_SetBits(GPIOB,GPIO_Pin_0);
	//PB.0 输出高电平
}
void delay_ms(u16 n)
{
	u16 i = 0;  
	while(n--)
	{
		i = 12000;	//约运行12000次耗时1ms
		while(i--);    
	}
}
int main(void)
{ 
 	LED_Init();							//LED端口初始化
	while(1)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_0);	//PB.0 输出高电平
		delay_ms(10);					//延时10ms(仿真很慢,10ms即可)
		GPIO_ResetBits(GPIOB,GPIO_Pin_0);//PB.0 输出低电平
		delay_ms(10);		
	}	 
}

GPIO的工作方式有8种,包括4种输入模式和4种输出模式:

  • GPIO_Mode_IN_FLOATING 浮空输入(无上下拉电阻)
  • GPIO_Mode_IPU 上拉输入
  • GPIO_Mode_IPD 下拉输入
  • GPIO_Mode_AIN 模拟信号输入
  • GPIO_Mode_Out_OD 开漏输出(带上拉或者下拉)
  • GPIO_Mode_AF_OD 开漏复用功能(带上拉或者下拉)
  • GPIO_Mode_Out_PP 推挽输出(带上拉或者下拉)
  • GPIO_Mode_AF_PP 推挽复用功能(带上拉或者下拉)
    GPIO有3种最大输出速度:
    2MHZ、25MHZ、50MHZ。

    如图为按键控制灯光开关。PA0设置为GPIO_Mode_IN_FLOATING 浮空输入模式。按键检测函数如下:
u8 KEY_Scan()
{	 	  
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
	{
		delay_ms(1); //去抖动,实际使用中可略高
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
			return 1;
	}	    
 	return 0;//未按下
}

主函数中设置变量open,每次检测按键按下后取反。如果open为1则拉低PB0,LED熄灭。

if(KEY_Scan()) open = !open;
if(open) GPIO_ResetBits(GPIOB,GPIO_Pin_0);
else GPIO_SetBits(GPIOB,GPIO_Pin_0);
delay_ms(10);

以上就是基于库开发的STM32单片机开发基本介绍。STM32的内容十分复杂,需要通过实践不断磨砺才能熟练运用。掌握库开发方法可以节约相当的时间,更容易掌握。