(由于第一次在自帶的浏覽器寫,結果在粘貼代碼時網頁卡死,沒有儲存。。。是以沒了。。。這是第二次寫,是以介紹簡略了許多)
目的:通過對寄存器的操作,點亮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,
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0kkaNBTSE5UeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0QTO1MzNyAjMzIjMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
代碼如下:
一種是直接操作寄存器位址,另一種是通過寄存器映射來實作;
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;
}