浅谈STM32和51单片机的寄存器编程异同
2021-05-10杨宇
杨 宇
(昆明冶金高等专科学校电气与机械学院,云南 昆明 650033)
0 引 言
现在市面上常用的单片机可以分为两大类:基础性能单片机和高性能单片机。基础性能单片机中最常用的就是51单片机,它是众多单片机学习者进行入门学习的首选。但随着社会的发展、科技的进步,单片机需要具备更强的性能和更低的功耗,51单片机已经不能满足一些新的要求。高性能单片机的出现弥补了51单片机的不足,在众多的高性能单片机中,STM32凭借其在开发方式、技术支持、性价比等方面的优势,成为了市场占有率最高的一种高性能单片机。
对于许多具有51单片机基础的学习者,继续学习STM32可以说是一种必然趋势。但由于种种原因,很多人的STM32学习之路都半途而废,因为普遍认为学习STM32难度太大。究其原因,笔者认为他们只是单纯地学习STM32,而没有将51单片机和STM32结合起来学习。本文正是以此为出发点,将STM32的基本开发方式——寄存器编程,与51单片机的寄存器编程进行比较和分析,使学习者能更好地理解STM32的寄存器编程。
1 实例硬件原理图
本文主要阐述51单片机和STM32对GPIO(General Purpose Input Output,通用型输入输出端口)的操作原理,以分别用这2种单片机点亮一个LED(发光二极管)为实例来比较和分析2种寄存器编程方式的异同。本实例中51单片机采用的型号为AT89C51, STM32采用的型号为STM32F103R6。AT89C51通过引脚 P 2.0 连接发光二极管,输出低电平点亮发光二极管,如图1所示;STM32F103R6通过引脚 PC 0 连接发光二极管,输出低电平点亮发光二极管,如图2所示。
图1 AT89C51驱动LED原理图 图2 STM32F103R6驱动LED原理图Fig.1 Schematic diagram of AT89C51 Fig.2 Schematic diagram of STM32F103R6
2 实例编程异同分析
AT89C51和STM32F103R6的程序开发都是以创建项目的形式来完成,AT89C51驱动发光二极管的项目文件如图3所示,STM32F103R6驱动发光二极管的项目文件如图4所示。2个项目都包括3种文件:启动程序文件、主程序文件和头文件。本文首先对2个项目的启动程序文件和头文件进行比较,再对主程序文件进行对比。
图3 AT89C51驱动LED项目文件 图4 STM32F103R6驱动LED项目文件Fig.3 Project files of AT89C51 Fig.4 Project files of STM32F103R6
2.1 启动程序文件异同分析
2个项目都具有启动程序文件,AT89C51的启动程序文件名称为STARTUP.A51, STM32F103R6的启动程序文件名称为startup_stm32f10x_hd.s。两者的作用相同:当单片机上电启动时,首先会执行启动程序,从而建立起执行主程序的运行环境。并且两者都采用汇编语言编写,但文件后缀名不同。两者的主要区别是,STARTUP.A51文件是单片机开发软件(比如Keil c51)自带的;而startup_stm32f10x_hd.s文件是单片机制造商ST(意法半导体)官方提供的,用户需要从官方固件库中找到该文件,并添加到自己的编程里。
2.2 头文件异同分析
2个项目都具有头文件,AT89C51的头文件名称为reg51.h, STM32F103R6的头文件名称为stm32f10x.h。两者的作用相同:用于存放寄存器映射的程序,为主程序中对寄存器编程做准备;并且两者都采用C语言编写,文件后缀名也相同。两者的主要区别是,reg51.h文件是单片机开发软件(比如Keil c51)自带的,而stm32f10x.h文件需要用户创建。
2.3 主程序文件异同分析
图5 AT89C51驱动LED主程序Fig.5 Main file of AT89C51
图6 STM32F103R6驱动LED主程序Fig.6 Main file of STM32F103R6
2个项目中的主程序文件名称均为main.c,AT89C51驱动发光二极管的主程序如图5所示,STM32F103R6驱动发光二极管的主程序如图6所示。2个主程序的作用相同:都是对单片机的GPIO进行操作,使单片机输出相应的信号。它们的主要区别在于STM32F103R6对GPIO的操作比AT89C51对GPIO的操作更复杂。从图5可以看出,AT89C51对GPIO的操作很简单,只需要直接对端口寄存器P2赋值就可以使单片机的 P 2.0 引脚输出低电平。STM32F103R6对GPIO的操作需要开启端口时钟以及配置端口寄存器CRL和ODR,如图6所示,首先开启GPIOC端口时钟,接着对GPIOC_CRL寄存器中的相关位清零;然后设置GPIOC_CRL寄存器将PC0引脚配置为推挽输出;最后设置GPOIC_ODR寄存器让PC0引脚输出需要的电平。此外,STM32F103R6对GPIO操作还需要编写系统初始化函数,如图4中的SystemInit(),用于初始化系统时钟,AT89C51对GPIO的操作则不需要该函数。
3 结 语
由于51单片机的寄存器编程和STM32的寄存器编程既有相同点又有差异性,所以将两者结合起来对比学习比单纯学习STM32更容易理解STM32的寄存器编程原理。STM32的编程方式分为基础的寄存器编程和高阶的固件库编程,固件库编程也是STM32领先于其他高性能单片机的一大优势,很多人想学但学不好STM32的固件库编程,其实是没有打好寄存器编程的基础。通过本文的方法对理解STM32的寄存器编程及后续学习固件库编程会有很大帮助。