零死角玩轉STM32---閱讀摘記一

一、時鐘相關

從時鐘樹的分析,看到經過一系列的倍頻、分頻後得到了幾個與我們開發密切相關的時鐘。

SYSCLK:系統時鐘,STM32大部分器件的時鐘來源。主要由AHB預分頻器分配到各個部件。

HCLK:由AHB預分頻器直接輸出得到,它是高速總線AHB的時鐘信號,提供給存儲器,DMA及cortex內核,是cortex內核運行的時鐘,cpu主頻就是這個信號,它的大小與STM32運算速度,數據存取速度密切相關。

FCLK:同樣由AHB預分頻器輸出得到,是內核的“自由運行時鐘”。“自由”表現在它不來自時鐘 HCLK,因此在HCLK時鐘停止時 FCLK 也繼續運行。它的存在,可以保證在處理器休眠時,也能夠採樣和到中斷和跟蹤休眠事件 ,它與HCLK互相同步。

PCLK1:外設時鐘,由APB1預分頻器輸出得到,最大頻率爲36MHz,提供給掛載在APB1總線上的外設。

PCLK2:外設時鐘,由APB2預分頻器輸出得到,最大頻率可爲72MHz,提供給掛載在APB2總線上的外設。

爲什麼STM32的時鐘系統如此複雜,有倍頻、分頻及一系列的外設時鐘的開關。需要倍頻是考慮到電磁兼容性,如外部直接提供一個72MHz的晶振,太高的振盪頻率可能會給製作電路板帶來一定的難度。分頻是因爲STM32既有高速外設又有低速外設,各種外設的工作頻率不盡相同,如同pc機上的南北橋,把高速的和低速的設備分開來管理。最後,每個外設都配備了外設時鐘的開關,當我們不使用某個外設時,可以把這個外設時鐘關閉,從而降低STM32的整體功耗。所以,當我們使用外設時,一定要記得開啓外設的時鐘啊,親。


注意:3.5版本的庫在啓動文件中調用了SystemInit(),所以不必在main()函數中再次調用。但如果使用的是3.0版本的庫則必須在main函數中調用SystemInit(),以設置系統時鐘,因爲在3.0版本的啓動代碼中並沒有調用SystemInit()函數。(具體可以參考啓動代碼)


如果我們用到了I/O的引腳複用功能,還要開啓其複用功能時鐘。

如GPIOC的Pin4還可以作爲ADC1的輸入引腳,現在我們把它作爲ADC1來使用,除了開啓GPIOC時鐘外,還要開啓ADC1的時鐘:

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);

RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE);

/*

LED.H

*/

#ifndef __LED_H

#define __LED_H

#include "stm32f10x.h"

/* the macro definition to trigger the led on or off

* 1 - off

- 0 - on

*/

#define ON  0

#define OFF 1

//帶參宏,可以像內聯函數一樣使用

#define LED1(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_3);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_3)

#define LED2(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_4);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_4)

#define LED3(a) if (a)  \

GPIO_SetBits(GPIOC,GPIO_Pin_5);\

else        \

GPIO_ResetBits(GPIOC,GPIO_Pin_5)

void LED_GPIO_Config(void);

#endif /* __LED_H */


這個頭文件(led.h)的內容不多,但也把它獨立成一個頭文件,方便以後擴展或移植使用。希望讀者養成良好的工程習慣,在寫頭文件的時候,加上類似以下這樣的條件編譯。

#ifndef __LED_H

#define __LED_H

……

#endif

這樣可以防止頭文件重複包含,使得工程的兼容性更好。讀者問爲什麼要加兩個下劃線”__” ?在這裏加兩個下劃線可以避免這個宏標識符與其它定義重名,因爲在其它部分代碼定義的宏或變量,一般都不會出現這樣有下劃線的名字。


規範的位操作方法

由於庫函數的實現涉及到不少位操作,首先爲讀者介紹一下幾個常用的位操作方法,排除閱讀代碼的障礙。

1、將char型變量a的第七位(bit6)清0,其它位不變。

a &= ~(1<<6);   //括號內1左移6位,得二進制數:0100 0000

//按位取反,得1011 1111 ,所得的數與a作”位與&”運算,

// a的第7位(bit6)被置零,而其它位不變。

2、同理,將變量a的第七位(bit6)置1,其它位不變的方法如下。

a |= (1<<6);        //把第七位(bit6)置1,其它爲不變

3、將變量a的第七位(bit6)取反,其它位不變。

a ^=(1<<6);   //把第七位(bit6)取反,其它位不變  (  ^ 爲抑或符號)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章