外设->总线 ->寄存器
APB2挂载着GPIOA~GPIOG,GPIOB挂载着类似于BSRR的寄存器。
BSRR:bit set/reset register 置位/复位寄存器,又叫端口设置/清除寄存器
如果知道了总线地址,就可以根据外设偏移地址得到外设地址,再根据寄存器偏移地址,就可以得到具体寄存器的地址(指针取址)
代码总线和外设基址宏定义
peripheral 计算机外设,外设
/*外设基地址*/
/*外设基地址*/
#define PERIPH_BASE ((unsigned int)0x40000000)
/*总线基地址*/
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE+0x00010000)
#define AHBPERIPG_BASE (PERIPH_BASE+0x00020000)
/*GPIO外设基地址*/
#define GPIOA_BASE (APB2PERIPH_BASE+0x0800)
#define GPIOB_BASE (APB2PERIPH_BASE+0x0c00)
#define GPIOC_BASE (APB2PERIPH_BASE+0x1000)
#define GPIOD_BASE (APB2PERIPH_BASE+0x1400)
#define GPIOE_BASE (APB2PERIPH_BASE+0x1800)
#define GPIOF_BASE (APB2PERIPH_BASE+0x1c00)
#define GPIOG_BASE (APB2PERIPH_BASE+0x2000)
/*寄存器基地址,以GPIOB为例*/
#define GPIOB_CRL (GPIOB_BASE+0x00)
#define GPIOB_CRH (GPIOB_BASE+0x04)
#define GPIOB_IDR (GPIOB_BASE+0x08)
#define GPIOB_ODP (GPIOB_BASE+0x0C)
#define GPIOB_BSRR (GPIOB_BASE+0x10)
#define GPIOB_BRR (GPIOB_BASE+0x14)
#define GPIOB_LCKR (GPIOB_BASE+0x18)
使用指针控制BSRR寄存器
/*控制GPIOB引脚0输出低电平(BSRR寄存器的BR0置1)*/
*(unsigned int *)GPIO_BSRR=(0x01<<(16+0));
/*控制GPIOB引脚0输出高电平(BSRR寄存器的BS0置1)*/
*(unsigned int *)GPIOB_BSRR=0x01<<0;
unsigned int tamp;
/*读取GPIOB端口所有引脚的电平(读IDR寄存器)*/
temp=*(unsigned int *)GPIOB_IDR;
使用结构体对GPIO寄存器的封装
typedef unsigned int uint32_t; /*无符号32位变量*/
typedef unaigned short int uint16_t; /*无符号16位变量*/
/*GPIO寄存器列表*/
typedef struct{
uint32_t CRL; /*GPIO端口配置低寄存器 地址偏移:0x00*/
uint32_t CRH; /*GPIO端口配置高寄存器 地址偏移:0x04*/
uint32_t IDR; /*GPIO数据输入寄存器 地址偏移:0x08*/
uint32_t ODR; /*GPIO数据输出寄存器 地址偏移:0x0C*/
uint32_t BSRR; /*GPIO位设置/清除寄存器 地址偏移:0x10*/
uint32_t BRR; /*端口位清除寄存器 地址偏移:0x14*/
uint32_t LCKR; /*端口配置锁定寄存器 地址偏移0x18*/
}GPIO_TypeDef;
还学习了如何建立一个工程模板大概的步骤如下:在桌面或者别的地方建立一个文件夹作为模板文件夹,然后打开keil5,选择建立工程,选择你所建立的文件夹,再输入名字就是文件生成的名字,比如我跟着视频起的名字叫BH-f103,它所创建的文件夹就是以BH-F103为开头的。类比于51单片机,也需要一个main文件,直接在创建的文件夹中建立就行,
这边有一个问题就是为什么在KEIL5软件中可以直接新建,为什么选择在文件夹里面新建而不是直接在软件里面新建?为什么选择这种方式呢?然后还要在文件夹里面添加一个名字是”startup_stm32f10x_hd.s“的文件,这个是一个描述文件。另外还自己新建一个名为”stm32f10x.h“的头文件,是空的。然后如果编译的话就会出现问题,大概就是没有一个描述文件里面的函数,这就需要我们在main里面写一
void SystemInit(void)
{
//函数体为空,目的是骗过编译器不报错
}
这个函数,这样就可以运行了,然后的步骤就是插上单片机,设置一些参数,印象比较深刻的就是DeBug里面的下载方式,还有就是下载方式选择DAP,然后就是时钟选择5Mhz,这两个印象比较深刻,按照视频里面的已经下载成功,但是我报错了:”Error:Flash Download Failed“这个报的错误,后来搜索了半天,只需要把DeBug里面的Connect从Nomal改成Under Reset就可以了。
实验了一下上面那个问题,发现两种方法并没有任何区别,并且尝试直接在软件里面见文件那种方法,发现并没有出现”Error:Flash Download Failed“这个报错,而是直接显示Flash load Finish,显示下载成功了,然后我又回去尝试了第一种方法,发现就算从under resert改成normal,也是可以成功的,好神奇。而且我记得我在书上看的时候,上面说如果要添加.h文件的话,要在路径里面标注.h文件的地址,但是我没有标注,也没有报错,我猜测可能是,因为我们这个头文件只是确保程序可以编译成功,只是挂了一个名字,并不是真正实现了某一些功能,所以编译器找不到也没事,就算找到了也是一个空的文件夹。
今天是学习32单片机的第一天,因为以前有一点基础,所以学的快一点,明天加油!