本帖最后由 xiatianyun 于 2018-6-4 09:42 编辑
刚看到有前人发布自己学习中的持续更新贴作为鞭策自己不断学习的方法,我也做个学习笔记,把过程中的点点滴滴写下来。
其实写笔记我一直使用复制粘贴保存在电脑里,但最近我喜欢上了用笔写在笔记本上,觉得更有价值更有效率。
--------------------------
先来谈谈STM32的常识。
ARM公司其实不生产芯片,靠什么赚钱呢?靠授权。ARM研发内核然后授权给各个芯片厂家,靠授权费用赚钱,这个是个好注意。毕竟研发和生产在环节上很不同,一家科技公司很难占据产品的各个环节,占据了也就作茧自缚了,就像昔日的诺基亚。
但毕竟内核只是芯片的一部分,内核之外叫做片上外设,意思就是芯片上的相对于内核而言的外部设备,比如GPIO。
芯片厂家根据内核自己设计相关的片上外设成为单片机,如果没有统一的标准那么各个厂家的芯片就不能通用。
意法半导体公司就是其中一家授权生产ARM的公司,当然意法的产品不只ARM芯片。
芯片内核也是升级换代的,我以前知道的ARM其实是比较早的内核产品。精英版的STM32是比较新的内核,叫Cortex-M3,手机上的叫Core-A,A7、A8之类,是很先进的东西。
微控制器芯片Cortex-M3、M4、M7,一个比一个先进。
-------------------------------
事实上使用汇编编写程序已经变得很难了,51时代就有使用C来设计51程序了。学校里面曾看到高年级同学使用手操器来下载程序,那种是在纸上写好汇编程序然后自己手动通过手操器(不知道叫什么合适)一条条下载到试验机里面的,连个电脑软件都没有。想来那种手操器兼具汇编和烧制的功能。我是学PLC的,我以前也是这么学习PLC的。C语言是比较底层的语言,用来编写单片机程序就理所当然了。单片机的C语言采用的编译器和普通的C语言不同,可以把单片机的C语言看作是C的一个子集,并不是所有C的特性均支持。
要想用C来写单片机程序当然要做些底层封装,可以自己封装,事实上芯片公司提供了标准封装,ST公司提供的STM32库函数就是这样的封装。
------------------------------
Keil公司是另外一家公司,是软件公司,提供开发单片机的工具,从51到ARM均有。
ST公司也有自己的开发工具,为什么我们都用Keil呢?业有所专嘛。
Keil 提供的STM32开发工具似乎换了个名字,叫MDK,不过装好后还是叫Keil。
Keil不是免费的,以前很难找到破解的Keil,现在我们使用Keil,所以我们都懂了。
Keil是个IDE工具,除了编辑程序外还提供编译器,并且通过简单选择就配置好了开发链路,不用自己配置,类似与其他专有语言开发工具,比如微软的VS。
换句话说如果开发者要自己配置开发链路的话也是可以的,只要够专业。通过查看,安装好的Keil在目录下的ARMARMCCin里就是编译工具,其他 目录里面提供单片机的include、lib。
为什么还要从ST官网下载库呢?官网的比较新嘛。Keil提供的库我想也是ST提供的,不过可能不会同步更新。
Keil的编辑器不好用,不过keil提供从其他编辑器来操作的可定制菜单,看来Keil还是知道自己的短板的。
现在比较不错的编辑器有gvim/sublime text/vs code,不过这些都是普通编辑器,如果要在开发中实现跳转、自动完成的话需要插件,这些都是学习成本,就看值不值了。
补充:
其实开发STM32除了在windows平台外还有Linux平台和Mac平台也可以,这对于极客来说是个好消息。具体看ST公司提供的开发套件,从我了解的信息看是集成在Eclipse的开发环境。
----------------------------------
学习STM32除了软件外其实很重要的还有硬件,电子工程这类。我学习STM32纯属偶然,我在PLC设计中需要使用一块带Modbus RTU通讯的中继板来做扩展,这块中继板设置通讯奇偶校验时只能使用固定的无校验,这让我很郁闷,系统中其他站都要设置成无校验才行。所以有了我是不是可以修改下的冲动。电子工程没弄过,这个是个拦路虎,我想我以后如果中断学习了可能是因为这个。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
从目前了解的看,STM32的操作其实就是对内部存储器的操作,寄存器是映射到存储器地址空间上的。
但这些存储器地址可不像普通内存空间一样可以按照自己的需要来操作,它需要遵循硬件特性,先操作哪个再操作哪个。
首先需要了解的是存储器地址映射。
STM32自然是32位机,存储器可寻址空间为4GB,即0x0000,0000~0xFFFF,FFFF。
这里有个通常所说的1024问题,其实这是为了在数字上好用16进制来表示才规定的,说是规定不如说是约定俗成。1k=1024,表示成16进制刚好是0x400,如果1k=1000表示成16进制就是0x3E8,那么2k=0x7D0就不如表示成1024时2k=0x800好表示:2k=2*0x400=0x800。看,刚好是400的2倍。
这些地址空间被粗略地分成了8个块,每块512MB,其中第0、1、2块最重要。
block0:是内部Flash,用于储存用户程序代码和其他必须的工厂代码。可是芯片并非全提供这么多的实体Flash给我们用,比如精英版的STM32F103ZET只有512kB可以用来编程就已经是大容量了。第0块大量的是预留空间,其实是为了将来芯片升级不用再重新设计才预留的,预留就是在该芯片上不提供的意思。
block1:是内部SRAM,也就是我们说的内存,易失性。这512M也只有部分可用,精英版的STM32F103ZET是64kB。片上内存总是很贵的。
block2:是以后学习的重灾区了,片上外设映射到此。
片上外设分两种:低速和高速。低速外设用到APB1总线,或者说APB1就是低速外设,映射到存储器地址是:0x4000,000~0x4000,77FF.
高速外设又分两种:APB2和AHB总线。APB2映射地址为:0x4001,000~0x4001,3FFF。AHB地址为:0学4002,000~0x5003,FFFF。看来是AHB总线的地址范围大。
block2的512MB也没有全部提供使用,使用到的空间也不是全都连续。功能不同的总线间有预留空间。
------------------------
为什么是总线映射而不是直接寄存器映射呢?寄存器是设备的控制单元,而设备是挂载在总线上的,无论是外设还是核内设备都如此。总线天然地有地址,这对于有一点点51常识的我来说还是比较好理解的。
可以这么理解:总线上的设备和存储器(Flash/SRAM)是统一编址的。
大声说出来,让别人知道你在做什么,自己才能有学习的动力。
学习STM32一开始就点亮LED等就如同学习高级语言一开始总是从“Hello World!"开始一样,不过这似乎避开了一个重要的知识点,就是系统时钟。STM32要想工作离不开时钟,不同于51单片机,STM32有多个时钟,主要是因为它复杂嘛。
时钟源其实就四个:内部时钟源两个HSI和LSI、外部时钟源两个HSE和LSE。PLL叫做锁相倍频器,不是一个物理独立的时钟源,但通常也把PLL作为一个时钟源看待,这样就有了 5个时钟源。
高速和低速时钟当然是时钟频率不同了,精英版的外部高速时钟HSE是8MHz而低速外部时钟LSE是32.768kHz。内部时钟是芯片内自带的。
这么多时钟都是用来服务应用的,有这么几个时钟应用:
首先是独立看门狗IWDG时钟,它只能从内部低速时钟LSI配置。
其次是实时时钟RTC,它可以由三种时钟来配置:内部低速时钟LSI、外部低速时钟LSE、外部高速时钟HSE的128分频。
然后是USB时钟,来自于PLL的预分频。
更多的应用,比如总线更多的和系统时钟有关。
系统时钟可以由三种时钟源配置:HSI、HSE和PLL。
内部高速时钟HSI更多地是作为外部高速时钟HSE的冗余时钟出现,一旦HSE失效就自动由HSI接替。
------------------------------
系统时钟是内核CPU工作的时钟,开发STM32更多地关注外设总线:AHB、APB1、APB2。
外设总线时钟都是由系统时钟经由AHB的预分频得到。
-------------------------------
时钟是个拦路虎,看似复杂,不过我想无外乎就是为了适应不同的需求而设立的,为的是以逸待劳,以不变应万变,作为学习没必要太过纠结这些内容。
不过时钟是如何被配置的呢?
当系统上电后不是一来就执行main(),而是有个初始化过程,这个初始化就是startup文件的内容。
也就是说startup是独立于main的程序,学习阶段把它看作是ST公司提供的不变的东西吧。
库里面的startup 是由汇编设计的,看不懂,主要是进行系统堆栈分配、中断向量分配和时钟配置,然后交由用户的main()。
这些内容其实在51单片机里面也有,不过似乎没有时钟分配。
在没有进行时钟配置前系统执行启动程序是用的什么时钟呢?有内部时钟嘛。
一旦配置好时钟后系统就开始执行用户程序了,记住一点:所有外设如果要工作除了需要配置好时钟外(在main()前就已经就绪了)还要使能。
装载的时间周期非常短,
只是数个指令周期而已,基本在us就完成了。
但装载定时器周期时,
无论是ms量级还是us量级的,
都是统一要求减一的,
所以认为:减一是考虑到装载时间的想法是不合适的。
一周热门 更多>