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 0C00CRL的地址为0x4001 0C00CRH地址为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 | 14; GPIOC-CRH ~(0x0F(4*5)); GPIOC-CRH |(1(4*5)); GPIOC-ODR ~(113); while(1); } void SystemInit() { }经测试完全没有问题