STM32学习笔记2--------使用寄存器点亮LED

启动文件(startup_stm32f10x_hd.s)

当STM32芯片上电启动的时候,首先会执行这里的汇编程序,从而建立起C语言的运行环境。该文件使用的汇编指令是Cortex-M3内核支持的指令,可参考《Cortex-M3权威指南》中的指令集内容。

主要功能:
  • 初始化堆栈指针SP
  • 初始化程序计数器指针PC
  • 设置堆栈大小
  • 初始化中断向量表
  • 配置外部SRAM作为数据存储器(这个由用户配置,一般的开发板没有外部SRAM)
  • 调用SystemIni()函数配置STM32的系统时钟(需用户定义,若不配置系统时钟,STM32会把HSI(8M)作为系统时钟,由芯片内部的振荡器提供。)
  • 设置C库的分支入口"__main"(最终用来调用main函数)

我们需要在外部定义一个SystemInit函数设置STM32的时钟;STM32上电后,会执行SystemInit函数,最后执行C语言中的main函数。

寄存器映射(stm32f10x.h)

在编程之前我们要先实现寄存器映射,有关寄存器映射的代码都统一写在stm32f10x.h文件中。在此处把寄存器的地址值都直接强制转换成了指针,方便使用。

/*  片上外设基地址  */
#define PERIPH_BASE              ((unsigned int)0x40000000)

/*  总线基地址,GPIO都挂载到APB2上 */
#define APB2PERIPH_BASE			(PERIPH_BASE + 0x10000)

/*  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外设基地址   */
#define RCC_BASE					(APB2PERIPH_BASE  +  0x1000)
/* RCC的AHB1时钟使能寄存器地址,强制转换成指针  */
#define RCC_APB2ENR				    *(unsigned int*)(RCC_BASE+0x18)

使用寄存器点亮LED

  • 1.GPIO模式

把连接到LED的GPIO引脚PB0配置成输出模式,即配置GPIO的端口配置低寄存器CRL(32位寄存器,,包含0~7号引脚,其中每4位配置一个引脚),MODE位用来配置输出的速度,CNF位用来配置各种输入输出模式。

把PB0配置为通用推挽输出,输出速度为10M

运算符优先级

//清空控制PB0的端口
GPIOB_CRL &= ~(0x0F << 4*0);
//配置PB0为通用推挽输出,速度为10M
GPIOB_CRL |= (1<<4*0);
  • 2.控制引脚输出电平

在输出模式时,对端口位设置/清除寄存器BSRR寄存器、端口位清除寄存器BRR和ODR寄存器写入参数即可控制引脚的电平状态,其中操作BSRR和BRR最终影响的都是ODR寄存器,然后通过ODR寄存器的输出来控制GPIO。也可直接操作ODR寄存器来控制GPIO的电平

//PB0输出低电平
GPIO_ODR |= (0<<0);
  • 3.开启外设时钟

设置完GPIO的引脚,控制了电平输出,还需要设置外设时钟。由于STM32的外设很多,为了降低功耗,每个外设都对应一个时钟。在芯片刚上电的时候这些时钟都是关闭的,如果想要外设工作,必须把相应的时钟打开.

RCC(reset and clockcontrol)复位和时钟管理外设,在《STM32中文参考手册》的第六章中介绍。

所有的GPIO都挂载到APB2总线上,具体的始终由APB2外设始终使能寄存器(RCC_APB2ENR)控制。

#开启GPIOB端口时钟
RCC_APB2ENR |= (1<<3);
  • 完整代码
int main(void)
{
	#开启GPIOB端口时钟
	RCC_APB2ENR |= (1<<3);

	//清空控制PB0的端口
	GPIOB_CRL &= ~(0x0F << 4*0);
	//配置PB0为通用推挽输出,速度为10M
	GPIOB_CRL |= (1<<4*0);

	//PB0输出低电平
	GPIO_ODR |= (0<<0);
	while(1);
}

你可能感兴趣的:(STM32)