启动文件(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
把连接到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);
在输出模式时,对端口位设置/清除寄存器BSRR寄存器、端口位清除寄存器BRR和ODR寄存器写入参数即可控制引脚的电平状态,其中操作BSRR和BRR最终影响的都是ODR寄存器,然后通过ODR寄存器的输出来控制GPIO。也可直接操作ODR寄存器来控制GPIO的电平
//PB0输出低电平
GPIO_ODR |= (0<<0);
设置完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);
}
启动文件(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
把连接到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);
在输出模式时,对端口位设置/清除寄存器BSRR寄存器、端口位清除寄存器BRR和ODR寄存器写入参数即可控制引脚的电平状态,其中操作BSRR和BRR最终影响的都是ODR寄存器,然后通过ODR寄存器的输出来控制GPIO。也可直接操作ODR寄存器来控制GPIO的电平
//PB0输出低电平
GPIO_ODR |= (0<<0);
设置完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);
}
举报