天天看點

寄存器初識----stm32f103rbt6

(由于第一次在自帶的浏覽器寫,結果在粘貼代碼時網頁卡死,沒有儲存。。。是以沒了。。。這是第二次寫,是以介紹簡略了許多)

目的:通過對寄存器的操作,點亮LED;

參考文檔:國信長天嵌入式競賽平台原理圖,stm32f103rbt6 ,

STM32中文參考手冊_V10,Cortex-M3權威指南(中文)

通過對文檔的翻閱,我們知道了LED1-8使用的是開發闆的PC8-15;即GPIO的C端口的第8-15位;

其中,外設基位址是0x40000000;APB2的偏移位址是0x10000,GPIO接口都挂接在APB2總線上;

GPIOC的偏移位址是0x1000,儲存着操作GPIO口的一些寄存器;

端口配置低寄存器GPIOC_CRL的偏移是0x00;端口配置高寄存器GPIOC_CRH的偏移是0x04,用來配置IO模式,倆個寄存器共64位,每4位可以配置一個IO位線的模式,可以配置0-15共16根位線;

GPIOC_ODR的偏移是0x0C;用來輸出資料,通過實驗發現,輸出0可以使LED點亮,而ODR複位設定是0x00000000;是以,如果想要使某一個LED點亮,需要先全部置1,然後使用位運算;或者直接用立即數指派。

我們發現,即使這樣,仍然不能點亮LED,這是因為,APB2挂接在AHB,AHB基位址一般認為是0x40020000,AHB上有RCC時鐘,其中APB2 外設時鐘使能寄存器(RCC_APB2ENR)的偏移是0x18;複位是0x00000000;是以需要對GPIO的C端口的時鐘打開,如圖,需要将第4位置1,

寄存器初識----stm32f103rbt6

代碼如下:

一種是直接操作寄存器位址,另一種是通過寄存器映射來實作;

void SystemInit()
{
}

#if 0
//直接操作位址
int main()
{
//打開GPIOC的時鐘
	*(unsigned int *)0x40021018 |=((1)<<4);
//配置IO口為輸出
	*(unsigned int *)0x40011004 =0x11111111;

//控制ODR寄存器					  
	*(unsigned int *)0x4001100C =0xFEFF;
}

void SystemInit()
{
}
#endif

 //使用寄存器映射

//外設
#define PERIPH_BASE        ((unsigned int)0x40000000)
//總線
#define APB1PERIPH_BASE    PERIPH_BASE 
#define APB2PERIPH_BASE    (PERIPH_BASE+0X10000)
#define AHBPERIPH_BASE     (PERIPH_BASE+0X20000)

//寄存器組
#define RCC_BASE 			 (AHBPERIPH_BASE+0X1000)
#define GPIOC_BASE 		 (APB2PERIPH_BASE+0X1000)

//寄存器
#define RCC_APB2ENR 		 *(unsigned int *)(RCC_BASE+0X18)
#define GPIOC_CRL 		 *(unsigned int *)(GPIOC_BASE+0X00)
#define GPIOC_CRH 		 *(unsigned int *)(GPIOC_BASE+0X04)
#define GPIOC_ODR 		 *(unsigned int *)(GPIOC_BASE+0X0C)
int main()
{
//打開GPIOC的時鐘
	RCC_APB2ENR |=((1)<<4);
//配置IO口為輸出
	GPIOC_CRH =0x11111111;

//控制ODR寄存器					  
	GPIOC_ODR =0xFEFF;

}