这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 如何从快速51单片机转战STM32?(2)

共7条 1/1 1 跳转至

如何从快速51单片机转战STM32?(2)

高工
2019-10-20 15:56:11     打赏

学习方法的区别

学习51 用寄存器,学习STM32 用库。

以前我们在学习51 的时候,用的是寄存器编程的方法,想要实现什么效果,直接往寄存器里面赋值,优点是直观,简单粗暴,知道自己具体干了啥,心里踏实。

直接操作寄存器之所以在51 上可行,究其原因,我想有两点:

▶▶1 51 主频不高,资源有限,必须注重程序执行的效率,只能直接操作寄存器。关键的地方还得用汇编,不适合用固件库。

要知道当初我们学习51 单片机的时候用的还是汇编,连现在的C 编程都不是,就更别说什么库函数编程。

▶▶2 51 功能简单,寄存器不多。以国内普及最广的STC89C52 为例,寄存器全部加起来不到30 个。按照功能区分来记的话,可以把每个寄存器背的滚瓜烂熟,并且寄存器每一位的功能都可以记得住,在编程的时候做到了然于胸。

现在从51 过度到STM32 的学习,很多人还是喜欢沿用51 的学习方法。接受不了库,在学习库的时候陷入迷糊之中,来回几个月下来,都不知道到底有没学会STM32,因为在这一路的学习中都是在调用库函数,压根就没有操作过寄存器,心里面很不踏实。

其实大家在调用库函数的时候心中难道就没有疑问,库的底层是怎么实现的?难道就没有勇气对库的底层一探究竟。可最后当我们开始跟踪库函数底层的时候,看到一堆的宏定义、结构体、指针、各种的文件包含,而且注释全部都是英文的,是不是又心生忌惮。

鉴于此,我想用两个原因来总结下很多初学者畏惧库不愿意用库的原因。

▶▶1 C 语言知识点的欠缺库在实现寄存器映像时使用的宏定义,强制类型转换,在定义寄存器时使用的结构体,在外设初始化函数时使用的指针,在组织头文件时使用的条件编译等C 语言知识,在大学课程中很少涉及,大多数老师也基本是不讲。在一些简单的51 单片机编程中又很少会用到这些知识。学单片机,做嵌入式开发其实80%的工作都跟C 语言编程相关,剩下的20%的工作就是阅读各种数据手册,熟悉各种硬件外设。所以掌握这些基本的C 语言知识,是嵌入式学习中一道迈不过去的坎,STM32 的库则给了我们一次提升C 的机会。凡是可以从书本中找到的,相信我们基本都可以学会,很多初学者并不是不够聪明或者勤奋,只是缺少方向性的指导罢了。对于这欠缺的知识点我们稍微花点时间就可以掌握,剩下的就是不断地实践调试。这里我为大家推荐一本C 语言的书籍《C 和指针》。

▶▶2 程序架构设计思想的欠缺

这个比较难搞,很多C 语言学习得挺好好的人,也比较难掌握。还好我们遇到了STM32 的库,这给了我们一个学习和提升C 语言绝佳的机会。库的整个架构是如何搭建起来的,代码上是如何如何一步一步写出来的:从寄存器映像开始,到寄存器的封装,然后到函数的编写,到每个外设函数对应的驱动文件,这里面涉及到了大量的条件编译,文件包含的思想,对应刚写过几行51 单片机的初学者来说简直就是噩梦。但是,如果你把这一系列的关系弄明白了,那么对库的整个架构也了解的差不多了,以后你就不用嚷嚷着说要操作寄存器了。如果你一开始不喜欢用库,对库开发很忌惮,那么请自问:是不是我的C 语学得不够好。库是一种全新的学习方法,是一种潮流,我更把它看做是与C 语言的又一次历练和提升。是否用库,只差你一个闪亮的回眸。

用寄存器点亮LED

为了顺利过渡到库开发,在STM32 编程的开始,我们对照51 点亮一个LED 的方法,给大家演示一下STM32 如何用操作寄存器的方法点亮一个LED,然后再慢慢讲解到底什么是库,让大家知道库跟寄存器的关系。

1、用51 点亮一个LED

在用STM32 点亮一个LED 之前,我们先来复习下用51 如何点亮一个LED。

硬件上我们假设51 单片机的P0 口的第0 位接了一个LED,负逻辑亮。如果我们要点亮这个LED,代码上我们会这么写:

image.png


这里面我们用的是总线操作的方法,即是对P0 口的8 个IO 同时操作,但起作用的只是P0^0。

除了这种总线操作的方法,我们还学习过位操作,利用51 编译器的关键字sbit,我们可以定义一个位变量:

image.png

那么LED = 0;就点亮了LED,LED = 1;就关闭了LED。为了让程序看起来见名知义,我们定义两个宏:


image.png

点亮和关闭LED 的代码就变成了:

image.png

image.png

上面总线和位操作的的方法,学过51 的朋友是非常熟悉的,也很容易理解。

那么我们再说一下大家容易忽略的几个知识点。

▶▶1 什么是寄存器

在点亮LED 的时候,我们都是用操作寄存器的方法来实现的,那大家是否想过,这个寄存器到底是什么?为什么我们可以直接操作P0 口?

解答上面的问题之前,我们先简单介绍下51 单片机的主要组成部分,这对我们学习其他单片机也有好处。

我们以国内的STC89C51 为例,该单片机主要由51 内核、外设IP、和总线这三大部分组成。内核是由Intel 公司生产的,外设IP 就是STC 公司在内核的基础上添加的诸如定时器、串口、IO 口等这些东西,总线就是用来连接内核和外设的接口单元。Intel 在这里属于IP 核设计公司,STC 属于IC 设计公司。世界上能设计IP 核的公司屈指可数。我们非常熟悉的ARM 公司就属于IP 核设计公司,ARM 给其他公司授权,其他IC 公司就在ARM 内核上设计出各具特色的MCU,我们后面要学习的STM32 就是属于一中基于ARM 内核的MCU。

寄存器则是内置于各个IP 外设中,是一种用于配置外设功能的存储器,就是一种内存,并且有想对应的地址。学过C 语言我们就知道,要操作这些内存就可以使用C 语言中的指针,通过寻址的方式来操作这些具有特殊功能的内存—寄存器。比如P0 口对应的地址是0X80,那么我们要修改0X80 这个地址对应的内存的内容的话,按照常理可以这样操作:

image.png

可当我们编译的时候,编译器会报错,在51 里面只能通过SFR 和SBIT 这两个关键字来实现寄存器映像,不能直接操作寄存器对应的地址,这是51 相较于STM32 不同的地方。51 单片机的这些寄存器位于地址80H~FFH 中,对应着128 个地址,但不是每个地址都是有效的,51 系列的单片机有21 个,52 系列的则有26 个,其他的都是保留区。

image.png

▶▶2 寄存器映射

实际上我们在编程的时候并不是通过指针来操作寄存器的,而是直接给P0、P1 这些端口寄存器赋值。那么这些外设资源是如何与地址建立一一对应的关系(寄存器映射定义),这得益与51 特有的两个关键字:SFR 和sbit,其他单片机没有,只能用其他的方式来实现寄存器映射。这两个关键字帮我们实现了所有寄存器的定义,所以我们才可以像操作普通变量一个来操作寄存器。其实我们一开始提到的点亮LED 的代码,全貌应该是这样的:

image.png

为了方便起见,我们可以把寄存器映射全部写好封装在一个头文件里面,不用每用一个寄存器就定义一次。其实这方面的工作不用我们做,我们在编程的时候都会在开始的地方添加一个头文件:

image.png

这个头文件已经实现了全部寄存器的定义,该文件是keil 自带,在安装目录:Keil\C51\INC 下可以找到。这个文件实现了字节寄存器和位寄存器的定义。

11.jpg

。。。

▶▶3 启动文件—STARTUP.A51

还有一个就是启动代码,这个也是很多初学者容易忽略的地方,对于这部分我们主要总结下它的功能,不详解讲解里面的代码。

单片机在上电复位后,首先执行的是启动文件—STARTUP.A51,而不是我们通常看到的main 函数。我们新建51 工程的时候会有一个提示:是否拷贝启动代码到当前的工程,我们一般选择是。

QQ图片20191020155253.png

启动代码用汇编语言编写,主要实现了以下功能:清除内部数据存储器、清除外部数据存储器、清除外部页储存器、初始化small 模式下的可重入栈和指针、初始化large 模式下可重入栈和指针、初始化compact 模式下的可重入栈和指针、初始化8051 硬件栈指针、传递初始化全局变量的控制命令或者在没有初始化全局变量时给main 函数传递命令。然后程序就跳转到main 函数,来到我们熟知的C 世界。

▶▶4 总结

在讲解用51 点亮LED 的时候,我们补充了什么是寄存器、寄存器映射、启动代码这三部分的内容,这三部分内容本来是放到STM32 里面讲解的,但考虑到大家已经有51 的基础,并且对51 比较熟悉,那我再添加点内容,大家自然没有那么抗拒,并且可以根据上面讲的内容亲自实践,学习得也会更深入。那当我再在STM32 讲解这几个内容的时候,大家就会对比着学习,对STM32 也就没有那么忌惮。

转帖自网络



工程师
2019-10-24 18:51:18     打赏
2楼

学习一下


高工
2019-10-26 23:24:51     打赏
3楼

支持一下


工程师
2019-10-27 23:02:07     打赏
4楼

多向楼主学习


助工
2019-11-04 22:28:38     打赏
5楼

C语言还是很重要 


工程师
2019-11-07 22:07:17     打赏
6楼

支持一下


工程师
2019-11-11 22:25:01     打赏
7楼

说的很不错


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]