7、stm32F103入門學習--點亮LED(寄存器操作)(採用結構體方式)

採用結構體方式

在上節課我們只採用了GPIOC,但是有的型號引腳比較多,可以分成A、B、C、D…G組。那麼根據下圖的寫法我們要重複寫好幾次。大家有發現除了A、B、C、D…G不一樣之外,別的基本一樣。也就是說GPIOA有7個寄存器控制,GPIOB也是有7個寄存器控制,由此聯想到採用結構體。舉個例子,一個小區裏有A幢樓、B幢樓、、、但是每幢樓的結構層數都一樣。
在這裏插入圖片描述
定義:

typedef unsigned int uint32_t;
typedef struct 
{
	uint32_t CRL;
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR;
	uint32_t BRR;
	uint32_t LCKR;
}GPIO_TypeDef;

也就是說把32位的寄存器CRL、CRH、、LCKR組成一個整體,名字叫做 GPIO_TypeDef,在內存中是連續排列的,假設CRL的地址爲0x00,那麼CRH的地址爲0x04,依次排列下去。
在這裏插入圖片描述
再定義:

#define  GPIOC  ((GPIO_TypeDef*)GPIOC_BASE)

看下(GPIO_TypeDef*)GPIOC_BASE 這條語句,意思是將GPIOC_BASE轉換成GPIO_TypeDef類型的地址。上節課中可知GPIOC_BASE的值爲0x4001 1000。那麼以該地址爲基礎(0x4001 0C00),CRL的地址爲0x4001 0C00,CRH地址爲0x4001 1004…依次下去。完全跟我們以前的方式符合!
下圖中的“GPIO_CRH”的地址即爲0x40011004,那麼怎麼用結構體表示呢?
在這裏插入圖片描述
再回到這條語句

#define  GPIOC  ((GPIO_TypeDef*)GPIOC_BASE)

可以用GPIOC->CRH的方式來表示GPIOC_CRH。由於程序小,看不出來優勢在哪,以後慢慢體會。那麼在main函數中都可以用這種方式來代替。時鐘也類似!
在這裏插入圖片描述
寫法跟配置GPIO一樣,可以寫相應的結構體!

typedef struct 
{
	uint32_t CR;
	uint32_t CFGR;
	uint32_t CIR;
	uint32_t APB2RSTR;
	uint32_t APB1RSTR;
	uint32_t AHBENR;
	uint32_t APB2ENR;
	uint32_t APB1ENR;
	uint32_t BDCR;
	uint32_t CSR;
}RCC_TypeDef;

綜上所述,在頭文件中進行相應的程序修改,如下:

#define PERIPH_BASE           ((unsigned int)0x40000000) 
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
/* AHB總線基地址 */
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
/*GPIOC外設基地址*/
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)	
 /*RCC外設基地址*/
#define RCC_BASE      (AHBPERIPH_BASE + 0x1000)
typedef unsigned int uint32_t;
typedef struct 
{
	uint32_t CRL;
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR;
	uint32_t BRR;
	uint32_t LCKR;
}GPIO_TypeDef;

typedef struct 
{
	uint32_t CR;
	uint32_t CFGR;
	uint32_t CIR;
	uint32_t APB2RSTR;
	uint32_t APB1RSTR;
	uint32_t AHBENR;
	uint32_t APB2ENR;
	uint32_t APB1ENR;
	uint32_t BDCR;
	uint32_t CSR;
}RCC_TypeDef;

#define  GPIOC  ((GPIO_TypeDef*)GPIOC_BASE)
#define  RCC  ((RCC_TypeDef*)RCC_BASE)

在main函數中,進行如下修改:

#include "stm32f10x.h"
int main(void)
{
	RCC->APB2ENR |= 1<<4;
	GPIOC->CRH &=~(0x0F<<(4*5));
	GPIOC->CRH |=(1<<(4*5));
	GPIOC->ODR &=~(1<<13);	
	while(1);
}
void SystemInit()
{
}

經測試完全沒有問題!

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