使用STM32主要寄存器
1.<总线基地址> :使用寄存器编程前,我们需要了解到STM32外设功能
百分之80的芯片只会用到这一类。其余的用不到我们就不学。
- Block2<储存器> : Block2用于设计片内的外设,所以我们一般的外设都会挂载到Block2内。
- Block2上个有三条总线,根据外设速度的不同,APB1 是低速外设,APB2 and AHB挂载高速外设。我们根据三条线的地址来选定。
2.<外设基地址 >
-
总线上挂载这各种外设。这些外设也有自己的名称,及地址范围。
-
这里我们用GPIO 因为外设基GPIO属于高速外设。与总线基外设 APB2高速外设匹配。
2.1 <外设寄存器>
- 每一个外设基地址拥有很多寄存器。以GPIOB为例,包含下列寄存器。
- 每个寄存器为32bit,占4个字节。偏移地址,就是通过位基地址位移找到每一个寄存器的位置。
使用代码演练
#我们找到外设基地址的<基地址>
#define PERIPH_BASE ((unsigned int)0x400000000)
#因为总线基地址的范围很广,
#如APB1 的地址为0x40010000 = 就是外设基地址本身
#如APB2 的地址为0x40010000 = 外设基地址 + 0x00010000
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
#因为外设基地址要与 APB2(总线基地址挂载)
#GPIOB 外设基地址 0x40010C00
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
4.操作GPIOB寄存器点亮LED灯
4.1 开始外设时钟使能寄存器,当外设没有启用时,软件不能读写外设寄存器数值,返回值始终为0x00
4.2 配置引脚工作模式 <推免输入>
这里我们的LED灯与芯片的引脚分别是 PB5,PB0,PB1 只需配置CRL就好。
!!!因为我们CRL寄存器设置的4个bit 其中MODEy =01 最大速度10MHz ,所以我们在CNFy中设置 = 00 为通用推免模式输出。并为默认下拉模式【输出低电平】
4.3控制引脚电平输出
- 寄存器和BSRR(BRR只能清除寄存器) 都可以控制输出。控制BSRR相对较快
- 注意ODR和BSRR位置跟CLR都是相对的,例如
//配置PBO为通用推免输出,速度为10M
GPIOB->CRL |= ((1)<<0);
//PB0在DOR写入 输出低电平 ~(
GPIOB->ODR |= (1<<0);
//PB0使用BSRR设置DOR低电平
GPIOB->BSRR = (1<<0);
//PBO在使用BRR清除DOR低电平
4.4 查看存储映射图结合途中偏移地址,定义寄存器的宏
- 编写C语言头文件<stm32f10x.h>
/*片上外设基地址 */
#define PERIPH_BASE ((unsigned int)0x40000000)
/*总线基地址,GPIO 都挂载到 APB2 上 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
/*GPIOB 外设基地址*/
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
/* GPIOB 寄存器地址,强制转换成指针 */
#define GPIOB_CRL *(unsigned int*)(GPIOB_BASE+0x00)
#define GPIOB_CRH *(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_IDR *(unsigned int*)(GPIOB_BASE+0x08)
#define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C)
#define GPIOB_BSRR *(unsigned int*)(GPIOB_BASE+0x10)
#define GPIOB_BRR *(unsigned int*)(GPIOB_BASE+0x14)
#define GPIOB_LCKR *(unsigned int*)(GPIOB_BASE+0x18)
//RCC 外设基地址
//RCC 的 AHB1 时钟使能寄存器地址,强制转换成指针*/
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
typedef struct
{
uint32_t CR;
uint32_t CFRG;
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 RCC ((RCC_TypeDef*)RCC_BASE)
- 编写main.c文件
#include "stm32f10x.h"
int main(void)
{
//开启GPIO端口时钟 RRC端口3 IOPB
//RCC_APB2ENR |= ((1)<<3);
RCC->APB2ENR |= (1<<3);
//清空控制PB0的端口
GPIOB->CRL &= ~(0x0F<<(4*0));
//配置PBO为通用推免输出,速度为10M
//想要把修改为PB1 则(1<<5) PB5 (1<<20)
GPIOB->CRL |= ((1)<<0);
//PB0输出低电平(开启LED) <0, 1, 5>
GPIOB->ODR |= (0<<0);
//ODR输出高电平(关闭LED)
//GPIOB->ODR |= (1<<0);
//BSSR设置 / BRR清除
//GPIOB->BSRR = (1<<0);
//GPIOB->BRR = (1<<0);