STM32学习笔记初学者快速入门Word文件下载.docx
《STM32学习笔记初学者快速入门Word文件下载.docx》由会员分享,可在线阅读,更多相关《STM32学习笔记初学者快速入门Word文件下载.docx(24页珍藏版)》请在冰豆网上搜索。
就很重要在我相当熟练之前肯定不会用到IAR如果真的有一天不得不用I
AR相信学起来也很容易因为这个时候硬件部分我肯定很熟了再加上有ke
il的基础所以应该很容易学会了
调试工具JLINKV8这个不多说了价格便宜又好用就是它了
二热身
网上选购的付了款就是等了拿到包裹端详良久起身沐浴
更衣焚香
总得先吃晚饭洗澡再点个电蚊香什么的吧
拆包
细细端详做工精良尤其那上面的32吋屏越看越喜欢接下来就是一阵折
腾了装JLINK软件给板子通电先试试JLINK能不能与电脑和板子通信上
了真顺一点问题也没有于是准备将附带的程序一个一个地写进去试一试
一检查大部分例子的HEX文件并没有给出这要下一步自己生成但是几个
大工程的例子都有HEX文件如MP3如UCCGI测试等写完以后观察程序
运行的效果因为之前也做过彩屏的东西知道那玩艺代码量很大要流畅地显
示并不容当时是用AVR做的在18吋屏上显示一幅画要有一段时间现在
看起来用STM32做的驱动显示出来的画面还是很快的不过这里显示的大部
分是自画图并没有完整地显示一整幅的照片所以到底快到什么程度还不好说
看来不久以后这可以作为一个学习点的
一个晚上过去了下一篇就是要开始keil软件的学习了
STM32学习笔记2
本想着偷点懒的没想到竞被加了精没办法啦只能勤快点啦
硬件调通后就要开始编程了
编程的方法有两种一种是用st提供的库另一种是从最底层开始编程网上
关于使用哪种方法编程的讨论很多据说用库的效率要低一些但是用库编程非
常方便所以我还是从库开始啦库是ST提供的怎么说也不会差到哪里再
说了用32位ARM的话开发的观念也要随之改变一点了
说说我怎么学的吧
找个例子如GPIO可以看到其结构如下
SOURCE文件夹
-APP文件夹
-CMSIS文件夹
-STM32F10x_StdPeriph_Driver文件夹
Lis文件夹
OBJ文件夹
其中SOURCE中保存的是应用程序其中又有好多子文件夹而CMSIS文件
夹中和STM32F10x_StdPeriph_Driver文件夹中是ST提供的库这样如果要
做新的工程只要将这个文件夹整个复制过来就行其中APP中保存自己的代码
因为我们用51单片机时一般比较简单有时就一个文件所以通常不设置专
门的输出文件夹而这里做开发通常会有很多个文件加入一个工程中编译过
程中会产生很多中间文件因此设置专门的文件夹LIS和OBJ用来保存中间文
件
下面就将设置简单描述一下
将复到过来的GPIO根目录下的所有文件删除因为我们要学着自己建立工程
用菜单Project--NewuVisionPorject建立新的工程选择目标器件为STM3
2103VC这个过程与建立51单片机的工程没有什么区别这里就偷点懒不
上图了接下来看一看怎么设置
点那个品字形打开对话框
这里就给个图了相信有一定操作基础的人应该会用顺便提一下原来用VC
或者IAR时总觉得它们的一个功能就是建立一个是Debug组和Release组
这个功能挺好的从这个图可在Keil里也是一样可以建的
将刚才那个文件夹图中CMSIS中的文件加入CMSIS组一共3个其中\Sour
ce\CMSIS\Core\CM3有两个C语言源程序文件全部加入另外还有一个在
\Source\CMSIS\Core\CM3\startup\arm文件夹中这个文件夹中有4个s文
件我们选择其中的startup_stm32f10x_hds文件这是根据项目所用CPU来
选择的我们用的CPU是103VC的属于高密度的芯片所以选这个
至于LIB中的文件就在这儿\Source\STM32F10x_StdPeriph_Driver\src啦
这里有很多个文件把什么文件加进去呢怕麻烦的话把所有文件全部加进去
这并不会增加编译后的代码量但会增加很多的编译时间
接下来设定目标输出文件夹上面这个图怎么出来的就不说啦单击SelectFo
lerforObjects在弹出来的对话框中选择OBJ文件夹
同样方法选择List文件的输出文件夹
设置好后如果直接编译是不行的会出错还需要提供头文件所在位置单击
cC标签页
第一次进入时IncludePaths文本框中是空白的点击其后的按钮打开对话框
增加相应的路径
这样路径就设好了单击OK回到上一界面然后再单击OK退出设置即
可编译链接
下一会要试一试新的312版的库效果如何了
STM32学习笔记3
升级库
光盘中所带的例子是310的另外还有一个312的我试着将312的库替代
原来的库还真有问题下面就简述问题及解决方法
1将库文件解压
库文件名是stm32f10x_stdperiph_libzip解压后放在任意一个文件夹中
2由于原作者做了很好的规划每一个项目中都分成三个文件夹并且在s
ource文件夹中又做了3个文件夹其中APP文件夹是放自己写的文件的其
他的两个是从库中复制过来的因此想当com版本中相同的两个文件
夹
CMSIS和STM32F10x_StdPeriph_Driver直接复制过来以为一切OK结果
一编译出来一堆错误
其中有错误
Source\App\mainc7error20identifier"
GPIO_InitTypeDef"
isundefin
ed
还有大量的警告
Source\STM32F10x_StdPeriph_Driver\src\stm32f10x_flashc130warnin
g223-Dfunction"
assert_param"
declaredimplicitly
看了看在APP文件夹中还有一些不属于自己的东西
stm32f10x_confhstm32f10x_ithstm32f10x_itc打开一看果然是310
版本的没说的换找到STM32F10x_StdPeriph_Licom\Proje
ct\Template文件夹用里面的同样的文件替换掉这几个文件这回应该万事大
吉了吧
再一看依然如故没办法了只好细细研究了通过观察发现原来可以编
译通过的工程在mainc下面挂满了h文件而这个通不过的则少得很
这是编译能通过的工程
这是编译通不过的工程
显然有些文件没有被包含进来一点一点跟踪发现大部分的头文件都包含在
stm32f10x_confh中而这个文件又出现在stm32f10xh中其中有这样的一行
ifdefUSE_STDPERIPH_DRIVER
include"
stm32f10x_confh"
endif
看来是这个USE_STDPERIPH_DRIVER没有被定义啊于是人为地去掉
条件
再次编译果然就OK了可是可是也不能就这么去掉啊怎么办呢万能
的网啊一搜果然就有了
到设置CC页面
在那个define中加入USE_STDPERIPH_DRIVERSTM32F10X_HD
当然去掉条件编译前面的注释回到原样
再次编译一切顺利可是原来的工程例子也没有加这个啊怎么回事呢再
次打开原来的例子找到stm32f10xh可以看到有这么一行
而新的stm32f10xh中则是这样的
原com版的stm32f10xh被人为地修改了一下所以不在define中定
义也不要紧而新com则不行了
至此简单的升级搞定
本文见于好多地方但查询后未能确定其原始出处及作者故这里说明是转贴
但作者和原始出处信息就无法提供了如果原作者看到请跟贴说明知情者也请
跟贴说明
ARM中的RORW和ZIDATA
一直以来对于ARM体系中所描述的RORW和ZI数据存在似是而非的理解
这段时间对其仔细了解了一番发现了一些规律理解了一些以前书本上有的但
是不理解的东西我想应该有不少人也有和我同样的困惑因此将我的一些关于
RORW和ZI的理解写出来希望能对大家有所帮助
要了解RORW和ZI需要首先了解以下知识
ARM程序的组成
此处所说的ARM程序是指在ARM系统中正在执行的程序而非保存在ROM
中的bin映像image文件这一点清注意区别
一个ARM程序包含3部分RORW和ZI
RO是程序中的指令和常量
RW是程序中的已初始化变量
ZI是程序中的未初始化的变量
由以上3点说明可以理解为
RO就是readonly
RW就是readwrite
ZI就是zero
ARM映像文件的组成
所谓ARM映像文件就是指烧录到ROM中的bin文件也称为image文件以
下用Image文件来称呼它
Image文件包含了RO和RW数据
之所以Image文件不包含ZI数据是因为ZI数据都是0没必要包含只要程
序运行之前将ZI数据所在的区域一律清零即可包含进去反而浪费存储空间
Q为什么Image中必须包含RO和RW
A因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样无中
生有的
ARM程序的执行过程
从以上两点可以知道烧录到ROM中的image文件与实际运行时的ARM程序
之间并不是完全一样的因此就有必要了解ARM程序是如何从ROM中的image
到达实际运行状态的
实际上RO中的指令至少应该有这样的功能
1将RW从ROM中搬到RAM中因为RW是变量变量不能存在ROM中
2将ZI所在的RAM区域全部清零因为ZI区域并不在Image中所以需要
程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零ZI中也是变
量同理变量不能存在ROM中
在程序运行的最初阶段RO中的指令完成了这两项工作后C程序才能正常访问
变量否则只能运行不含变量的代码
说了上面的可能还是有些迷糊RORW和ZI到底是什么下面我将给出几个
例子最直观的来说明RORWZI在C中是什么意思
1RO
看下面两段程序他们之间差了一条语句这条语句就是声明一个字符常量因
此按照我们之前说的他们之间应该只会在RO数据中相差一个字节字符常量
为1字节
Prog1
include
voidmainvoid
Prog2
constchara5
Prog1编译出来后的信息如下
CodeRODataRWDataZIDataDebug
948600960GrandTotals
TotalROSizeCodeROData1008098kB
TotalRWSizeRWDataZIData96009kB
TotalROMSizeCodeRODataRWData1008098kB
Prog2编译出来后的信息如下
948610960GrandTotals
TotalROSizeCodeROData1009099kB
TotalROMSizeCodeRODataRWData1009099kB
以上两个程序编译出来后的信息可以看出
Prog1和Prog2的RO包含了Code和ROData两类数据他们的唯一区别就
是Prog2的ROData比Prog1多了1个字节这正和之前的推测一致
如果增加的是一条指令而不是一个常量则结果应该是Code数据大小有差别
2RW
同样再看两个程序他们之间只相差一个已初始化的变量按照之前所讲的
已初始化的变量应该是算在RW中的所以两个程序之间应该是RW大小有区
别
Prog3
Prog4
chara5
Prog3编译出来后的信息如下
Prog4编译出来后的信息如下
948601960Grand
Totals
TotalRWSizeRWDataZIData97009kB
可以看出Prog3和Prog4之间确实只有RWData之间相差了1个字节这个字
节正是被初始化过的一个字符型变量a所引起的
3ZI
再看两个程序他们之间的差别是一个未初始化的变量a从之前的了解中
应该可以推测这两个程序之间应该只有ZI大小有差别
chara
948600960Grand
948600970Grand
编译的结果完全符合推测只有ZI数据相差了1个字节这个字节正是未初始
化的一个字符型变量a所引起的
注意如果一个变量被初始化为0则该变量的处理方法与未初始化华变量一样
放在ZI区域
即ARMC程序中所有的未初始化变量都会被自动初始化为0
总结
1C中的指令以及常量被编译后是RO类型数据
2C中的未被初始化或初始化为0的变量编译后是ZI类型数据
3C中的已被初始化成非0值的变量编译后市RW类型数据
附
程序的编译命令假定C程序名为tstc
armcc-c-otstotstc
armlink-noremove-elf-nodebug-infototals-infosizes-map-listaamap
-otstelftsto
编译后的信息就在aamap文件中
ROM主要指NANDFlashNorFlash
RAM主要指PSRAMSDRAMSRAMDDRAM
继续学习中先把开发板自带一个例子做了些精简以免看得吓人
就是这个让PORTD上接的4个LED分别点亮
开始研究代码
intmainvoid
Init_All_Periph
看到这一行开始跟踪于是又看到了下面的内容
voidInit_All_Periphvoid
RCC_Configuration
继续跟踪
voidRCC_Configurationvoid
SystemInit
这行代码在system_stm32f10xc中找到了
voidSystemInitvoid
ResettheRCCclockconfigurationtothedefaultresetstatefor
debugpurpose
SetHSIONbit
RCC-CRuint32_t0x00000001
ResetSWHPREPPRE1PPRE2ADCPREandMCObits
ifndefSTM32F10X_CL
RCC-CFGRuint32_t0xF8FF0000
else
RCC-CFGRuint32_t0xF0FF0000
endifSTM32F10X_CL
ResetHSEONCSSONandPLLONbits
RCC-CRuint32_t0xFEF6FFFF
ResetHSEBYPbit
RCC-CRuint32_t0xFFFBFFFF
ResetPLLSRCPLLXTPREPLLMULandUSBPREOTGFSPREbits
RCC-CFGRuint32_t0xFF80FFFF
Disableallinterruptsandclearpendingbits
RCC-CIR0x009F0000
ResetPLL2ONandPLL3ONbits
RCC-CRuint32_t0xEBFFFFFF
RCC-CIR0x00FF0000
ResetCFGR2register
RCC-CFGR20x00000000
ConfiguretheSystemclockfrequencyHCLKPCLK2andPCLK1pres
calers
ConfiguretheFlashLatencycyclesandenableprefetchbuffer
SetSysClock
这一长串的又是什么如何来用呢看来偷懒是不成的了只能回过头去
研究STM32的时钟构成了
相当的复杂
系统的时钟可以有3个来源内部时钟HSI外部时钟HSE或者PLL锁相
环模块的输出它们由RCC_CFGR寄存器中的SW来选择
SW10系统时钟切换
由软件置1或清0来选择系统时钟源在从停止或待机模式中返
回时或直接或间接作为系统时钟的HSE出现故障时由硬件强制选择HSI作为系
统时钟如果时钟安全系统已经启动
00HSI作为系统时钟
01HSE作为系统时钟
10PLL输出作为系统时钟
11不可用
PLL的输出直接送到USB模块经过适当的分频后得到48M的频率供USB模
块使用
系统时钟的一路被直接送到I2S模块另一路经过AHB分频后送出送往各
个系统其中直接送往SDIFMSCAHB总线8分频后作为系统定时器时钟
经过APB1分频分别控制PLK1定时器TIM2TIM7经过APB2分频分别控制PLK
2定时器TIM1TIM8再经分频控制ADC
由此可知STM32F10x芯片的时钟比之于51AVRPIC等8位机要复杂复多
因此我们立足于对着芯片手册来解读程序力求知道这些程序代码如何使用
为何这么样使用如果自己要改可以修改哪些部分以便自己使用时可以得心
应手
单步执行看一看哪些代码被执行了
debugpurpose