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灯间断闪烁!和之前的实验现象一致

浙公网安备 33010602011771号