原创文章,欢迎转载,转载请注明出处
这个星期进度比较慢哈,只有周末和晚上下班回来才能做,事件不连续,琐碎的事情又比较多,挺烦的,有多琐碎呢?
1.本人有点小强迫症哈,虽然RTT将文件夹已经分类的很好了,但是在一个项目跟目录下这样放着看起来还是很不舒服的哈,于是强迫症范了,要整理下它。按照以前做项目的习惯,将程序分为四个层次,硬件层,驱动层,系统层和应用层,我们就整理下,对三个文件夹,其中硬件层和驱动层放在BSP文件夹里面,BSP文件里面再分硬件和驱动的文件夹,同时添加一个库文件夹。系统层就是RTT了,里面有components,include,libcpu,src文件夹,这些都是RTT比较紧密相关的文件夹。最后是应用层, 文件名是applications,applications和库文件文件夹都是从官方下下来的RTT里面分出来的。外面还加一个Prj文件夹,用来放keil的工程项目文件,和一个cfg文件夹,这个文件夹专门放置一些配置代码。这样分都是看各人喜好了。如图:
清爽很多。。哈。。SI用来放source insight的项目文件。
2.系统时钟的配置。
刚拿到一个新单片机的时候,往往第一个需要会的就是I/O口控制了,也就是流水灯了。可是还有一个关键的需要最开始就弄名清楚的就是系统里面各种时钟的配置。51比较简单,不需要配置,晶振是多少就是多少,一条指令运行的事件是晶振的12分之一。AVR的时候就已经复杂一点了,I/O口需要配置下,时钟也需要配置, 可以选择外部的内部的,然后时钟速度级别等等。到了430的时候,时钟配置就更为复杂了,系统里面就不止一个时钟源了,有好几个,分别分频了可以。还是说407吧,这个时钟比430的还复杂,哈。。
这个图有够唬人的哈,从左边开始说,没用过STM32增强系列单片机的以太网模块哈,这里就不说了。整个系统时钟可以有四个来源,外部高频,外部低频,内部高频和内部低频。选择好时钟源后,然后用设置PLL进行倍频,送到SYSCLK处,这也是系统运行的速度,然后配置AHB桥上的APB1和APB2上外部设备的时钟,其中APB1上挂的是一些低速设备,APB2上挂的是高速设备,下一面一张图会更得更清楚一些:
说了这么多,代码到底怎么配置呢。哈。。代码设置在系统startup里面已经设置过了哈,在main之前就设置好了,在startup_stm32f40xx.s里面可以看到这样一段汇编:
1 LDR R0, =SystemInit 2 BLX R0 3 LDR R0, =__main 4 BX R0
可以看到线调用了Systeminit函数,然后才进入我们通常的main函数的哈,为什么要先调用Systeminit函数呢,我也不是很清楚哈,不过好像CMSIS(ARM公司规定的什么标准)规范规定系统初始化函数名字必须为SystemInit.我们看看这个函数做了什么,首先对FPU做了下设定,然后就是开外部晶振端口,通过PLL_M、PLL_Q、PLL_N、PLL_P设置倍频等等。通过上面的图可以清楚看到分频和倍频的设置。至于怎么配置这里就先不说了,下面的库升级会说的比较清楚,就不重复说了。
3:标准库升级
我们下的是RTT1.2.1稳定版本,没下2.0.0(Alpha)内测版本(α(Alpha)版:内测版,β(Beta)版:公测版γ(Gamma)版:相当成熟的测试版,),这可不开玩笑啊,飞机飞着飞着当机了,那炸鸡了损失可不小,而且2.0.0里面的库也是1.0.0的。
说说我为什么要将标准库更新到1.3.0,据说IIC有bug,应该好多人都是用1.0.0的时候有bug,而且是30-September-2011的时候出的,已经比较久远了,中间还出现过1.0.1,1.0.2版本,说明小更新挺平凡的,应该还是有不少缺陷的,最新的1.3.0是08-November-2013的,离现在9个月,算比较新的哈。用新的稳定版可以避免一些无解的错误哈,尽量减少我们以后开发的麻烦。下面说说怎么升级。
升级库的时候还是需要注意点的。
(1):首先是单片机的定义
涉及到的文件是:stm32f4xx.h,1.0.0里面对407采用的是 STM32F40XX 的宏定义,如果没有在keil里面的预处理添加宏定义的地方添加 STM32F40XX 编译肯定通不过,如果定义了那就没问题了,因为在.h文件里面有
1 #ifdef STM32F40XX 2 #define STM32F40_41xxx 3 #endif /* STM32F40XX */
一句话,就是为了和之前定义兼容的。1.3.0的正确定义407的方法是定义宏 STM32F40_41xxx,可以在keil预处理里面添加这个宏,也可以在stm32f4xx.h添加,我们选择在stm32f4xx.h里面添加
(2):外部晶振的频率的宏定义
系统默认的定义外部晶振是25mhz,在stm32fxx.h里面有
1 #if !defined (HSE_VALUE) 2 #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ 3 #endif /* HSE_VALUE */
我们的板子是8mhz,我们对这个宏定义进行覆盖,在stm32fxx_conf.h里面重新定义如下:
1 //sky.zhou,定义外部晶振8mhz 2 #if defined (HSE_VALUE) 3 /* Redefine the HSE value; it‘s equal to 8 MHz on the STM32F4-DISCOVERY Kit */ 4 #undef HSE_VALUE 5 #define HSE_VALUE ((uint32_t)8000000) 6 #endif /* HSE_VALUE */
虽然这个可以不定义,只要对系统时钟的PLL_M、PLL_Q、PLL_N、PLL_P设置正确就可以的到正确的时钟了,可是但调用RCC_GetClocksFreq()函数的时候,我们是得不到正确的时钟的,因为这个函数是根据PLL_M、PLL_Q、PLL_N、PLL_P和HSE_VALUE 数值进行计算然后返回给我们,所以定义正确的HSE_VALUE数值是很有必要的。
(3):根据外部晶振大小对RCC的调整
这个涉及到system_stm32f4xx.c文件,里面根据25mhz的频率设置好了PLL,也就是PLL_M、PLL_Q、PLL_N、PLL_P,我们蒋PLL_M设置为8就可以了。为什么PLL_M要为25呢?为什么默认设置外部晶振为25mhz呢?哈,为了防止超频,如果外面默认设置8mhz,我们接个16mhz,那倍频率后不是要到168*2=336mhz了,估计会发热很严重烧掉吧,电脑超频两倍的都很少呢,出发发烧级的,用液氮冷却,否则也是瞬间烧。手册规定晶振是4~26mhz,算一下,如果按照默认配置,接最大晶振26mhz的话,频率可以PLL到174.7mhz,估计这个407应该是可以承受的花,ST肯定考虑到了这种情况,不过我没试哈,钱不能这样浪费。。哈。。
(4):中断入口文件
涉及到的文件是stm32f4xx_it.c,因为用的是RT_Thread RTOS,所以里面需要注释掉几个中断入口,分别为 HardFault_Handler(void)、PendSV_Handler(void)、void SysTick_Handler(void)和void PPP_IRQHandler(void),因为他们在RTT的 context_*.S和boarc.c里面定义过了,这里不注释会出错,然后可以把RTT其他的中断函数放进来,不过我觉得自己的终端函数还是不要放这里好,免得升级库的时候麻烦,耦合越少越好,独立性越强越好。
四轴飞行器1.2.3 STM32F407时钟配置和升级标准库文件,布布扣,bubuko.com