查看原文
其他

【连载】通过"库文件"学单片机驱动编程(1)

bug菌 最后一个bug 2021-01-31

1、跟大伙简单聊一聊

    首先非常感谢大家关注我的公众号,关注的各位亲可能60%来自于QQ群阅读我的相关文章然后加入的,其他的应该大部分来自于我的一个好朋友的公众号推荐吧,这个好朋友可能生活上压力太大已经不再写文章转行去做兼职工程师了。我也是前些天跟他聊天他突然告诉我的,我当时非常意外,因为毕竟我是第一次开通公众号而且还没有运营太久,很多运营方面的经验都是他帮忙的,于是跟他开始了一段长达2个小时的主题聊天。

    这两个小时的聊天大体总结了一下:这个位朋友技术不错而且非常有思想,目前公众号2W粉丝,说实在的对于我而言还是个非常漫长的数字,可是他不再花太多精力在这个上面了,原因大概是每天的更文花了很多心血,公众号的收益暂且不说,连续1个月的认真写作都没有获得任何的给他带来成就感的事情,于是他决定放弃写作了。现在公众号每天都是推文转发。他说了一句让我印象很深刻的话:当你千言万语却得不到只字片语的时候就放弃吧。

    这几天好好想了一想:每个人的经验和想法都需要每个人亲身去经历了才能够做好自身的决定,其他的时候均是"他以为","他认为"。所以我会继续好好的把属于自己的公众号做好,坚持自己的初衷,让大家远离bug,直到"最后一个bug"!

2、库文件

    这里作者开辟一个系列文章供大家阅读,通过"库文件"来学习单片机驱动编程,前面作者写了几篇编程框架的文章,于是很多小伙伴私信给我说怎么写好单片机程序?有什么好的资料和视频来进行学习?我这里给大家一个我个人的观点吧。读人家的代码,你会学到很多,这就是为什么很多小伙伴参加工作了以后技术上就会有质的飞跃的原因之一吧。同时还要注意的一点的是一定要读大牛写的代码

    好了,那一些小伙伴们会问我还没有参考工作怎么弄到大牛的代码呀?其实大牛一直都在你们身边,那些源代码,固件库都是大牛写的,我们应该从中获得启发为我们所用。所以本系列文章我将从非常火的"stm32固件库"中获得我们必备的学习和编程经验。(作者以STM32F4xx_StdPeriph_Driver此标准驱动为例为大家讲解)

3、stm32启动文件分析

    基本每个用C语言进行开发的单片机IDE(集成开发环境,如KEIL)都会有一个类似于startup的启动文件,就比如说51单片机也会有启动文件如:STARTUP.A51文件,只说大部分初学者由于刚入手单片机并不会太关注该启动文件,其实启动文件的主要的作用是为我们进入C语言开发环境做准备的,所以说我们非常要明确的一点是我们单片机最开始进入的并不是main函数。下面我以stm32为例为大家介绍单片机的启动过程,其他单片机是想类似的做法。我们首先找到后缀为.s的如下文件:

    我们可能就一脸迷茫了,不过不要慌张,下面我为大家一一解析,力求每个人都能看懂,同时也不会讲得太细,因为网络上挺多人总结得比我要好,这里仅仅只是一个小小的知识,大家有个概念就行了下图是stm32F4启动的主要工作:

1)代码片段1

    解析:该部分类似于C语言中的宏定义定义了堆和栈的大小以及起始终止地址标识

2)代码片段2


    解析:中间省略中断向量表内容,我们看69行向量表(Vectors)会从Flash的0x0地址开始放置,以4个字节为一个单位,地址0存放的是栈顶地址(Top of Stack),

3)代码片段3

    解析:注意当我们程序复位以后PC指针会指向复位中断向量位置(程序的运行都是根据PC指针来的,启动程序也是一样的),然后跳转到复位中断服务函数(即如上代码所示位置),然后分别调用系统时钟初始化函数SystemInit(该函数是C语言写的,我们可以在库文件中找到),然后执行__main,值得注意的是这里的__main并没我们平时主函数里面的main函数,而是位于C library中,他的具体实现大家可以上网查阅,或者仿真单步运行了解,下面对其功能总结了一下。

__main的主要工作

1)完成变量的初始化变量(包括.data、.bss段的数据初始化);

2)初始化堆栈;

3)库函数调用的初始化,比如说我们的printf函数等;

4)跳转到我们真正的main函数

4)代码片段4

    解析:这是.s启动文件中最后一点代码,这部分是初始化堆栈,在__main中处理。

4、总结

    该总结一些了,今天的文章主要是以stm32单片机为例进行了一个单片机比较通用的启动过程的了解,了解这个启动过程的目的:

    1)让我们对启动文件的基本过程有个感性的了解,在以后的项目中我们可能会存在在main函数之前就需要进行处理完的一些事情,这样不至于摸不着头脑。

    2)在工作中我们会开发BootLoader程序,作为整个系统的引导程序,这样就需要我们对单片机的执行过程有个比较全面的理解。

    3)对于大部分单片机或者是DSP等都会有类似的启动文件,启动过程大同小异

    好了,这里是公众号:"最后一个bug",下期我们将带来固件库中对我们编程带来极大提升的编程和框架!感谢各位的关注,我们下期见。

推荐阅读

嵌入式编程之动态接口技术(经验干货)

嵌入式编程之"重构"代码(C语言版本)

嵌入式编程必备之多方法测定程序运行时间(经验篇)

单片机常用程序框架之分时轮询(详注代码)

看门狗你确定会用了?(经验干货满满)

单片机开发之节省内存大法(C语言版本)

一种 “ 超强 ” 队列的C语言实现(附代码)

一文搞定通信协议中CRC校验(附代码)

【连载】嵌入式测试驱动开发(9)

C语言数值常量的“那些事”(细节分析)

向Modbus协议说"So easy!"

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存