您的位置:首页 > 其它

STM32学习之路:day1-arm内核结构 下载编译程序和keil的使用

2016-08-21 22:15 489 查看
写之前:最近在学习stm32系列的单片机的使用,之前在学校接触的一直51系列的单片机,对32不是很熟悉,所以打算在学习的过程中,记录下学习过程,以便以后回顾,以及希望可以给同样在学习的同学一些帮助。

在此次学习的过程中,主要用到的工具是keil5。安装软件以及破解地址:(稍后补上- -)

开启学习之路,骚年~

在第一天里,主要学习了如何使用编译工具keil5,了解arm结构,stm32的初步认识。

arm处理器本身是32位设计,但也配备16位指令集,所以等价32位代码节省达35%,却能保留32位系统的所有优势。

STM32F103XXXX中的第二个X表示FLASH容量,4 = 16K, 6 = 32K, 8 = 64K, B = 128K,



寄存器组:有R0~R1213个通用寄存器,R13是两个堆栈指针,主堆栈指针(MSP),进程堆栈指针(PSP),同时只能用一个;R14是连接寄存器(LR),保存返回地址,在子函数调用时会保存函数返回地址;R15是程序计数器(PC),保存当前指令的下一条指令地址

;特殊功能寄存器:程序状态字寄存器(xPSR),中断屏蔽寄存器,控制寄存器(CONTROL)

Cortex-M3的三级流水线:PC代表程序计数器,流水线使用三个阶段,因此指令分为三个阶段执行:1.取指(从存储器装载一条指令);2.译码(识别将要被执行的指令);3.执行(处理指令并将结果写回寄存器)。而R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三条指令。 三个阶段同时执行

STM32中外部中断与外部事件:



存储结构:



SRAM:即静态随机存取存储器。它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据。与之相对应的是DRAM(动态随即存取存储器),每隔一段时间,要刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,功耗较小,但是SRAM也有它的缺点,即它的集成度较低,相同容量的DRAM内存可以设计为较小的体积,但是SRAM却需要很大的体积。

SRAM主要用于二级高速缓存

位带操作:

首先要了解一个基本的概念:STM32单片机的一个地址(如:0x20000000)是一个字节,即8bit。STM32的位带操作简单的说就是把一个地址A的8个位,分别单独的重新定义8个地址, 操作一个地址等同于操作一个位,形象的理解即为取别名。

位带区中的地址除了可以同RAM一样使用外,还带有自己的“位带别名”。 将每个位拓展为32位的字,既成了位带别名。

如:0x20000000(一个字节)拓展到32位可得8个32位的字分别是: 0x220000000 x220000040 x220000080 x2200000c 0x220000100 x220000140 x220000180 x2200001c

由此可得“位带区” 上任意地址的 “位带别名地址” SRAM :0x22000000 +((A‐0x20000000)*8+n)*4

FLASH :0x42000000 +((A‐0x40000000)*8+n)*4

既:0x22000000+ (A‐0x20000000)*32 + n*4 0x42000000+ (A‐0x40000000)*32 + n*4

别名区地址 = 位带别名区起始地址+偏移量

“位带地址+位序号” 转换别名地址

通过定义宏,进行强制类型转换,转换成指针类型,就可以进行相应的运算

GPIO口的使用:

在使用GPIO口时,第一步要先使能GPIO口的时钟,时钟使能寄存器RCC_APB2ENR,2-8位分别控制A,B,C,D,E,F,G端口的时钟使能。可以直接对寄存器进行位运算,也可以用库函数进行使能。第二步是要配置模式设置,因为配置一个IO口需要4位Bit, 所以配置16个口需要两个32位寄存器,分为高8位(GPIOx_CRH),低8位(GPIOx_CRL)。两个数据寄存器:数据读入寄存器GPIOx_IDR和数据输出寄存器GPIOx_ODR。一个32位置位/复位寄存器(GPIOx_BSRR)还有复位寄存器和锁定寄存器,每个配置寄存器的地址为(基地址 + 偏移量)。

各口配置寄存器基地址:



为什么IO口需要时钟:因为寄存器是幼D触发器组成的,只有送来了时钟,触发器才能被改写值。

任何外设都需要时钟,为了节省空耗,只有在需要使用时才打开端口时钟。

关于一些基本的汇编知识:

BL Next ;把Next的下一个指令地址存入LR,但地址的最后一个bit位要置1,表示返回时是进入thumb状态,如果是0表示是arm状态,所以在查看寄存器值的时候往往会发现,LR中存放的值会比实际的地址加1。

BX LR ;把LR的内容赋给PC 会检查最后一个BIT位,为1是thumb状态,为0是arm状态

LDR r0,=10000 ;将某个内存里的数加载到寄存器中,如果是立即数,会先找到存有这个数的内存地址,以pc+偏移量的形式 [pc,#8]表示当前的pc值加8个偏移量为存有这个数的内存地址。

LDR r0,[r3] ;r0 = *r3

STR r0, [r3] ; *r3 = r0 把寄存器的数写回内存。

R14(LR),使用BL进行函数调用时,会将下一条要执行的指令地址存入LR,在异常发生时,会把返回地址存入LR

常用的伪指令:EQU 定义常量 AREA DCD END

BIC R0, R0, #0x00F00000 ;;位清除,后面哪一位为1,前面对应位清零

虽然代码大部分是用C来写,但在进入main函数之前,需要汇编程序,既启动代码。

首先对栈和堆的大小进行定义,并在代码区的起始处建立中断向量表,其第一个表项是栈顶地址,第二个表项是复位中断服务入口地址。然后在复位中断服务程序中跳转到C/C++标准实时库的__main函数,完成用户堆栈等的初始化后,跳转.c文件中的main函数开始执行C程序。

假设STM32被设置为从内部FLASH启动(这也是最常见的一种情况),中断向量表起始地位为0x8000000,则栈顶地址存放于0x8000000处,而复位中断服务入口地址存放于0x8000004处。当STM32遇到复位信号后,则从0x80000004处取出复位中断服务入口地址,继而执行复位中断服务程序,然后跳转__main函数,最后进入mian函数。

在烧写程序时注意BOOT脚的选取:开发板BOOT脚的连接区别:BOOT1 = x BOOT = 0 从用户闪存启动,这是正常的工作模式,上电运行程序或者JTAG方式下载程序时使用;BOOT1 = 0, BOOT0 = 1 从系统存储器启动,(用于下载工具下载hex)。

好了,第一天的内容大概就学了这么多,主要是一些基本知识的理解和掌握,千里之行,始于足下~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stm32