大家好,怀着激动地小心,激动地小手,我们来了。
今天我想给大家分享一个我自己的错误点。来警示大家。
刚才写我按键例程程序的时候,我自己来写的,发现启动不了,终于找到了原因,大家一起来看下。
while(i)
{
if(Key_Scan(GPIOA,GPIO_PIN_0)==1)
{
LED_Red_Toggle;
}
}
上面的是例程。
while(Key_Scan(GPIOA,GPIO_PIN_0))
{
LED_Red_Toggle;
}
下面是我自己写的,在我百思不得其解之时,我终于找到了原因。
原因:是判断一次Key_Scan的返回值,如果是0直接跳出跳到下一个。
所以,直接跳出了。。。。很尴尬,所以我嗯了半天按键没有用。好了
继续今天的学习吧
指令是由 编译工具链(ToolChains)来完成的。
芯片上电以后会触发复位异常。
复位异常触发后,会去一个中断向量表。
这个中断向量表一般在储存器的0地址位置。
上电之后就会触发这个复位异常
并且会跳转到中断向量表特定偏移位置。
获取里面的内容,执行。
修改异常内的内容,就可以让处理器去执行我们指定的操作。
存储器采用固定的存储器映射,代码区域起始地址为 0x0000 0000(通过 ICode/DCode 总线访问),而数据区域起始地址为 0x2000 0000(通过系统总线访问)。
Cortex™-M4FCPU 始终通过 ICode 总线获取复位向量,这意味着只有代码区域(通常为 Flash)可以提供自举空间。 STM32F4xx 微控制器实施一种特殊机制,可以从其它存储器(如内部 SRAM)进行自举。
这是开发板BOOT原理图
可以设置BOOT引脚的不同电平来初始化开发板的不同状态。
复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。复位后,用户可以通过设置BOOT1 和 BOOT0 引脚来选择需要的自举模式。
BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应GPIO 引脚即进入空闲状态,可用于其它用途。
器件退出待机模式时,还会对 BOOT 引脚重新采样。因此,当器件处于待机模式时,这些引脚必须保持所需的自举模式配置。这样的启动延迟结束后, CPU 将从地址 0x0000 0000 获取栈顶值,然后从始于 0x0000 0004 的自举存储器开始执行代码。
对于一个中断向量表而言,我们是从0地址开始获取的,我们可以通过不同的映射,我们可以将FLASH和系统存储器的位置给他映射到0地址这个位置。假设FLASH地址是0x08000000,系统存储器地址是0x1FFFB000。
内核就是针对不同的存储器来访问,因为这些系统存储器也是有相对应的0地址
由于这个映射机制,我们可以把这个中断向量表放在FLASH里面或者系统存储器或者是SRAM里。
通过这种机制我们就可以来更改中断向量表了。
嵌入式闪存就是FLASH。
FLASH:可以长期保持数据的器件。
Flash 结构如下:
● 主存储器块分为多个扇区。
● 系统存储器,器件在系统存储器自举模式下从该存储器启动
● 512 OTP(一次性可编程)字节,用于存储用户数据。
● 选项字节,用于配置读写保护、 BOR 级别、软件/硬件看门狗以及器件处于待机或停止
模式下的复位。
嵌入式SRAM就是静态随机存储器。
特性就是掉电数据丢失。
现在我们打开一个工程文件。
这个.s文件就是来启动STM32单片机的,不能是.c.h文件只能是.s
Set the initial PC == Reset_Handler 这个是设置PC指针的值
Set the vector table entries with the exceptions ISR address
设置中段向量表的入口
Branches to __main in the C library (which eventually
;* calls main()).
调用C库函数 __main初始化初始化堆栈工作,最终会跳转到我们自己编写的main函数中。