学了stm32一阵子,知道了有两种方法设置时钟。一个是用systemInit(),里面打包好了rcc设置的东西,另外一种途径就是使用st提供的各种RCC函数,一个个rcc寄存器去操作。两种方法最终目的都一样。但这两种方法当中,都有对中断向量表进行配置的语句
#ifdef VECT_TAB_RAM
MY_NVIC_SetVectorTable(0x20000000, 0x0);
#else
MY_NVIC_SetVectorTable(0x08000000,0x0);
#endif
}
以及
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
因此我假定对这个中断向量表的操作在正常启动和配置rcc时钟的过程中是必须的。
但今天下午看了一网友自己写的RCC配置函数:(我黏贴上来)
ErrorStatus HSEStartUpStatus; RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS) { RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
FLASH_SetLatency(FLASH_Latency_2); //flash操作的延时 //Flash 2 wait state FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08) { } }
大家看一下,这里面并没有任何语句提到向量表的配置,那这程序好使吗?我个人的理解,有些人是先调用systemInit再进行自己写的RCC函数进行二次时钟配置,那这样我可以理解,因为在systemInit里面已经将vector table给配置好了,接下来再二次修改RCC各寄存器的时候,不去理会也没事。但是如果他压根就没有调用systemInit呢?压根没有调用systemInit的情况下,他的时钟配置function里面也不出现向量表配置的操作,那就可以理解为他没有配置过向量表。。这样的话这程序应该就不好使了。。。或者要在这段程序里面把配置中断向量表的语句给加上才可以了。我想知道我这样的理解有没有错啊,如果有的话恳请各位告诉我错在哪了。小弟在此谢谢大家了。
Jonny,你好
系统启动复位时,会自动调用systemInit。这部分是在Reset_Handler中进行的,在startup_stm32fxxxx.s文件中可以找到这部分代码(路径:Drivers\CMSIS\Device\ST\STM32Fxxx\Source\Templates\arm\)。
所以只要你不去修改这部分代码,systemInit肯定会被调用到的。
Amanda
amanda你好,
很高兴收到你的回复,那如果我把LDR R0,=systemInit和BLX R0删掉的话程序那就直接进入main了,这样的话我就要在mian里面进行vector的配置了,要是既没有让其自动调用systemInit,在main里面也没有配置,这样的话应该是跑不起来的。能这样理解吗?我不是在死抠,我是想了解得透彻一点。因为我暂时还在入门RCC的学习,编不出完整的程序下,没法下载到stm32里看它能不能跑起来。
Hi JonnyVTOR寄存器配置的是中断向量表的偏移位置。也就是程序在运行时产生了中断,要知道到哪里去找中断服务程序的地址。
如果VTOR寄存器的值和实际中断向量表的位置不一样,程序会启动,但中断的执行会有问题。
另外再多说一点,ARM的核启动时总是从0地址开始执行,默认VTOR是放在0地址开始的位置的。
STM32的Flash起始地址从0x08000000开始,所以你会看到在systemInit中把VTOR的值设置成了FLASH_BASE(0x08000000)。
但是STM32的BOOT模式配置成从片上FLASH启动的模式后,会把从0x08000000开始的存储空间重映射到0地址开始。所以这时候,你去看0地址开始的内容和0x08000000开始的内容是一样的。
也就是说,这时候即使你没有配置VTOR也没有关系。
上面的东西可能涉及好些方面,建议你可以到我们本地的网站上去看看“Cortex-M系列内核和STM32讲座”,链接在这里设计资源专区-意法半导体(ST)微控制器
另外,VTOR和RCC的配置没有关系。
如果你怀疑是RCC配置的问题。我们有一款图形化配置工具CubeMX(官网可以下载)可以帮助你配置RCC,并生成代码。上面所说的网站上也有培训的资料。
说得太好了。我想请问一下您当初是怎么学习这个stm32的,了解的这么透彻您是怎么做到的?
Hi Jonny,
你的问题很好,我想amanda_s有一个很大的优势就在于她的日常工作中会使用到STM32,而且她会碰到各种各样的有关STM32的问题,这会帮助她成长为一个专家。
另外你初学这款MCU产品,可以多动手做一些实验,会有所帮助,个人认为如果你能用STM32实际做一个项目会更好。
期待amanda_s给你更好的答案
Best Regards,
Ben
Hi 宋斌,
我现在才接触这块芯片没多久,我学习单片机的时候是学51的,他俩差别挺大的。造成了现在不时都会有理解上的疑惑,我去别的论坛上提问,大多数得到的回复就是:别管为什么,照用就行了。我个人认为作为一个工科学生,是一定要追问为什么的。我现在先把一些基础的东西学到手,然后自己打算做一个用2.4G无线模块进行通信的实验,我是广州的,离深圳近,买电子元器件挺快就到了。祝你工作生活愉快。
非常好,如果你能把问题的原因分析清楚的话,我想你的基础会很扎实,今后也有更多的机会能够触类旁通,把理论和实际应用结合起来,比纯靠经验有价值的多,方法很正确。也祝你学业进步
同意Song bin的说法,找一些实际的例子,动手做些实验,会有帮助。
知其然,还要知其所以然。这种学习方法也值得鼓励。
刚接触ARM的话,很多地方一开始确实理解有点困难。其实我倒建议不一定非要一下子把所有的东西都弄清楚,这样可能会让你陷入太多的问题,反而前进的速度太慢。
很多时候,我们会在做项目的过程中,一下子想通以前很久没明白的事情,这也是积累的过程。
如果你是初学的话,可以看一下ARM-CortexM3权威指南,理解ARM-Cortex-M的整个结构,存储器的映射,中断等内容。
再结合一款STM32芯片,具体的操作实验一下。
STM32的每个芯片系列都提供有有标准外设库和cube库
才发现ctrl+s,就自动回帖了。:)
STM32的每个芯片系列都有标准外设库,Cube库。每个外设在里面基本都能找到例程。你也可以参考这些例程来学习。
amanda_s讲的很有道理,我也学习了