day07:自己写库,用结构体指针关联GPIO的各个寄存器的内存地址

stm32f10x.h:

/* 用于存放寄存器的映射代码,相当于51单片机的reg52.h */

/* 所有的外设基地址 */
#define PERIPH_BASE 		(unsigned int)0X40000000
	
/* 三条总线基地址 */
#define APB1_PERIPH_BASE	PERIPH_BASE
#define APB2_PERIPH_BASE	PERIPH_BASE+0X00010000
#define AHB_PERIPH_BASE		PERIPH_BASE+0X00018000

/* GPIOA - GPIOG端口的地址,它们均在APB2这条总线上 */
#define GPIOA_BASE 			APB2_PERIPH_BASE+0X00000800
#define GPIOB_BASE			APB2_PERIPH_BASE+0X00000C00
#define GPIOC_BASE			APB2_PERIPH_BASE+0X00001000
#define GPIOD_BASE			APB2_PERIPH_BASE+0X00001400
#define GPIOE_BASE			APB2_PERIPH_BASE+0X00001800
#define GPIOF_BASE			APB2_PERIPH_BASE+0X00001C00
#define GPIOG_BASE			APB2_PERIPH_BASE+0X00002000

/* GPIOC端口的寄存器地址:如果每个端口都这样定义,那么七个GPIO端口就要49行代码,太麻烦。使用结构体实现 */
/*
#define GPIOC_CRL			*(unsigned int*)(GPIOC_BASE+0X00000000)
#define GPIOC_CRH			*(unsigned int*)(GPIOC_BASE+0X00000004)
#define GPIOC_IDR			*(unsigned int*)(GPIOC_BASE+0X00000008)
#define GPIOC_ODR			*(unsigned int*)(GPIOC_BASE+0X0000000C)
#define GPIOC_BSRR			*(unsigned int*)(GPIOC_BASE+0X00000010)	
#define GPIOC_BRR			*(unsigned int*)(GPIOC_BASE+0X00000014)	
#define GPIOC_LCKR			*(unsigned int*)(GPIOC_BASE+0X00000018)
*/

/* 使用结构体定义寄存器 */
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;

// 强制转换成自定义的结构体对象:GPIO_TypeDef
/* GPIOA_BASE是一块内存地址,(GPIO_TypeDef*)表示将内存地址转换成GPIO_TypeDef类型的结构体指针 */
#define GPIOA	((GPIO_TypeDef *)(GPIOA_BASE))	
#define GPIOB	((GPIO_TypeDef *)(GPIOB_BASE))
#define GPIOC	((GPIO_TypeDef *)(GPIOC_BASE))
#define GPIOD	((GPIO_TypeDef *)(GPIOD_BASE))
#define GPIOE	((GPIO_TypeDef *)(GPIOE_BASE))	
#define GPIOF	((GPIO_TypeDef *)(GPIOF_BASE))	
#define GPIOG	((GPIO_TypeDef *)(GPIOG_BASE))

/* APB2外设时钟使能寄存器 */
#define GPIO_RCC			*(unsigned int*)0X40021018

main.c:

#include "stm32f10x.h"
	
// 延迟函数
void delay(unsigned int i)
{
	for(; i!=0; i--);
}

int main(void)
{
	/* 配置RCC寄存器,使能GPIO口的时钟 */
	GPIO_RCC |= ( 1<<4 );
	
	// 闪烁灯:D4和D5两个LED灯之间不断闪烁
	while(1)
	{
		/* 配置CRL寄存器,配置为推挽输出 */
		GPIOC->CRL |= ( 1<<(4*2) );		// 指针访问成员变量的方式
		/* 配置ODR寄存器 */
		GPIOC->ODR &= ~( 1<<2 );		// 位2置0,LED亮
		delay(0X99999);	
		GPIOC->ODR |= ( 1<<2 );			// 位2置1,LED不亮	
		
		/* 配置CRL寄存器,配置为推挽输出 */
		GPIOC->CRL |= ( 1<<(4*3) );
		/* 配置ODR寄存器 */
		GPIOC->ODR &= ~( 1<<3 );		// 位3置0,LED亮
		delay(0X99999);		
		GPIOC->ODR |= ( 1<<3 );			// 位3置1,LED不亮			
	}
}

void SystemInit(void)
{
	/* 函数体为空,目的是为了骗过编译器不报错 */
}

实验现象:D4和D5两个LED灯间断闪烁!和之前的实验现象一致

 

posted @ 2018-04-18 22:29  半生戎马,共话桑麻、  阅读(648)  评论(0)    收藏  举报
levels of contents