STM32學習筆記2--------使用寄存器點亮LED

啓動文件(startup_stm32f10x_hd.s)

當STM32芯片上電啓動的時候,首先會執行這裏的彙編程序,從而建立起C語言的運行環境。該文件使用的彙編指令是Cortex-M3內核支持的指令,可參考《Cortex-M3權威指南》中的指令集內容。

主要功能:
  • 初始化堆棧指針SP
  • 初始化程序計數器指針PC
  • 設置堆棧大小
  • 初始化中斷向量表
  • 配置外部SRAM作爲數據存儲器(這個由用戶配置,一般的開發板沒有外部SRAM)
  • 調用SystemIni()函數配置STM32的系統時鐘(需用戶定義,若不配置系統時鐘,STM32會把HSI(8M)作爲系統時鐘,由芯片內部的振盪器提供。)
  • 設置C庫的分支入口"__main"(最終用來調用main函數)

我們需要在外部定義一個SystemInit函數設置STM32的時鐘;STM32上電後,會執行SystemInit函數,最後執行C語言中的main函數。

寄存器映射(stm32f10x.h)

在編程之前我們要先實現寄存器映射,有關寄存器映射的代碼都統一寫在stm32f10x.h文件中。在此處把寄存器的地址值都直接強制轉換成了指針,方便使用。

/*  片上外設基地址  */
#define PERIPH_BASE              ((unsigned int)0x40000000)

/*  總線基地址,GPIO都掛載到APB2上 */
#define APB2PERIPH_BASE			(PERIPH_BASE + 0x10000)

/*  GPIOB外設基地址  */
#define GPIOB_BASE				(APB2PERIPH_BASE + 0x0C00)

/*  GPIOB寄存器地址,強制轉換成指針  */
#define GPIOB_CRL					*(unsigned int*) (GPIOB_BASE+0x00)
#define GPIOB_CRH					*(unsigned int*) (GPIOB_BASE+0x04)
#define GPIOB_IDR					*(unsigned int*) (GPIOB_BASE+0x08)
#define GPIOB_ODR					*(unsigned int*) (GPIOB_BASE+0x0C)
#define GPIOB_BSRR					*(unsigned int*) (GPIOB_BASE+0x10)
#define GPIOB_BRR					*(unsigned int*) (GPIOB_BASE+0x14)
#define GPIOB_LCKR					*(unsigned int*) (GPIOB_BASE+0x18)

/*  RCC外設基地址   */
#define RCC_BASE					(APB2PERIPH_BASE  +  0x1000)
/* RCC的AHB1時鐘使能寄存器地址,強制轉換成指針  */
#define RCC_APB2ENR				    *(unsigned int*)(RCC_BASE+0x18)

使用寄存器點亮LED

  • 1.GPIO模式

把連接到LED的GPIO引腳PB0配置成輸出模式,即配置GPIO的端口配置低寄存器CRL(32位寄存器,,包含0~7號引腳,其中每4位配置一個引腳),MODE位用來配置輸出的速度,CNF位用來配置各種輸入輸出模式。

把PB0配置爲通用推輓輸出,輸出速度爲10M

運算符優先級

//清空控制PB0的端口
GPIOB_CRL &= ~(0x0F << 4*0);
//配置PB0爲通用推輓輸出,速度爲10M
GPIOB_CRL |= (1<<4*0);
  • 2.控制引腳輸出電平

在輸出模式時,對端口位設置/清除寄存器BSRR寄存器、端口位清除寄存器BRR和ODR寄存器寫入參數即可控制引腳的電平狀態,其中操作BSRR和BRR最終影響的都是ODR寄存器,然後通過ODR寄存器的輸出來控制GPIO。也可直接操作ODR寄存器來控制GPIO的電平

//PB0輸出低電平
GPIO_ODR |= (0<<0);
  • 3.開啓外設時鐘

設置完GPIO的引腳,控制了電平輸出,還需要設置外設時鐘。由於STM32的外設很多,爲了降低功耗,每個外設都對應一個時鐘。在芯片剛上電的時候這些時鐘都是關閉的,如果想要外設工作,必須把相應的時鐘打開.

RCC(reset and clockcontrol)復位和時鐘管理外設,在《STM32中文參考手冊》的第六章中介紹。

所有的GPIO都掛載到APB2總線上,具體的始終由APB2外設始終使能寄存器(RCC_APB2ENR)控制。

#開啓GPIOB端口時鐘
RCC_APB2ENR |= (1<<3);
  • 完整代碼
int main(void)
{
	#開啓GPIOB端口時鐘
	RCC_APB2ENR |= (1<<3);

	//清空控制PB0的端口
	GPIOB_CRL &= ~(0x0F << 4*0);
	//配置PB0爲通用推輓輸出,速度爲10M
	GPIOB_CRL |= (1<<4*0);

	//PB0輸出低電平
	GPIO_ODR |= (0<<0);
	while(1);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章