类比51单片机写法在学51单片机的时候我们第一句是#includereg52.h。关于基础部分大家可以看我的51单片机部分很详细这里不具体展开。在第5小节中零零碎碎讲了一些地址这节课逻辑性的讲一下。在stm32芯片手册中可以看到P28一共4G大小地址范围0x0000 0000到0xFFFF FFFF分成8个块Block0~Block7每块大小为512M。在第4小节中我们用到了block2具体看下block2的内容参考stm32f10x系列参考手册可以看到一共有3条总线APB1、APB2、AHB。总线名称总线基地址APB10x4000 0000APB20x4001 0000AHB0x4001 8000其实APB1、APB2和AHB都是在外设地址(0x4000 0000)偏移分别偏移0x0,0x0001 0000和0x0002 0000。那么定义#define PERIPH_BASE 0x4000 0000 //总线基地址 #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE0x00010000) #define AHBPERIPH_BASE (PERIPH_BASE0x00020000)看到GPIOC在APB2上偏移0x0001 0000。定义#define GPIOC_BASE (APB2PERIPH_BASE0x00010000)再看下GPIOC相关寄存器都是在GPIOC_BASE的基础上偏移地址每次都是4个字节32位。所以定义#define GPIOC_CRL *(unsigned int *)( GPIOC_BASE0x00) #define GPIOC_CRH *(unsigned int *)( GPIOC_BASE0x04) #define GPIOC_IDR *(unsigned int *)( GPIOC_BASE0x08) #define GPIOC_ODR *(unsigned int *)( GPIOC_BASE0x0C) #define GPIOC_BSRR *(unsigned int *)( GPIOC_BASE0x10) #define GPIOC_BRR *(unsigned int *)( GPIOC_BASE0x14) #define GPIOC_LCKR *(unsigned int *)( GPIOC_BASE0x18)接下来配置时钟地址根据地址分配可得#define RCC_BASE (AHBPERIPH_BASE0x1000)根据上图可知RCC_APB2ENR是在RCC基础上偏移0x18所以#define RCC_APB2ENR *unsigned int*(RCC_BASE0x18)以上讲了那么多无非是把上节课程序中的*unsigned int*0x4002 1018 *unsigned int*0x40011004 *unsigned int*0x40011004 *unsigned int*0x4001 100C讲解更能清楚我们不希望在main函数中出现类似0x4002 1018的地址而使用可读性更好的英文单词来表述。因此仿51单片机的写法把一些地址定义放在头文件stm32f10x.h中。//头文件stm32f10x.h #define APB2PERIPH_BASE (PERIPH_BASE 0x10000) /* AHB总线基地址 */ #define AHBPERIPH_BASE (PERIPH_BASE 0x20000) /*GPIOC外设基地址*/ #define GPIOC_BASE (APB2PERIPH_BASE 0x1000) /* GPIOC寄存器地址 */ #define GPIOC_CRL *(unsigned int*)(GPIOC_BASE0x00) #define GPIOC_CRH *(unsigned int*)(GPIOC_BASE0x04) #define GPIOC_IDR *(unsigned int*)(GPIOC_BASE0x08) #define GPIOC_ODR *(unsigned int*)(GPIOC_BASE0x0C) #define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE0x10) #define GPIOC_BRR *(unsigned int*)(GPIOC_BASE0x14) #define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE0x18) /*RCC外设基地址*/ #define RCC_BASE (AHBPERIPH_BASE 0x1000) /*RCC的AHB2时钟使能寄存器地址*/ #define RCC_APB2ENR *(unsigned int*)(RCC_BASE0x18)那么在main函数中可以写成#include “stm32f10x.h” int main(void) { RCC_APB2ENR | 14; GPIOC_CRH ~(0x0F(4*5)); GPIOC_CRH |(1(4*5)); GPIOC_ODR ~(113); while(1); } void SystemIinit() { }接下来做实验在文件夹中新建文件“stm32f10x.h”。将头文件添加到Keil工程中添加方式参考添加启动文件的过程。打开头文件输入如下程序。在main.c中输入如下程序。编程下载到开发板观察到实验现象。
6、stm32F103入门学习--点亮LED(寄存器操作)(进一步完善)
类比51单片机写法在学51单片机的时候我们第一句是#includereg52.h。关于基础部分大家可以看我的51单片机部分很详细这里不具体展开。在第5小节中零零碎碎讲了一些地址这节课逻辑性的讲一下。在stm32芯片手册中可以看到P28一共4G大小地址范围0x0000 0000到0xFFFF FFFF分成8个块Block0~Block7每块大小为512M。在第4小节中我们用到了block2具体看下block2的内容参考stm32f10x系列参考手册可以看到一共有3条总线APB1、APB2、AHB。总线名称总线基地址APB10x4000 0000APB20x4001 0000AHB0x4001 8000其实APB1、APB2和AHB都是在外设地址(0x4000 0000)偏移分别偏移0x0,0x0001 0000和0x0002 0000。那么定义#define PERIPH_BASE 0x4000 0000 //总线基地址 #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE0x00010000) #define AHBPERIPH_BASE (PERIPH_BASE0x00020000)看到GPIOC在APB2上偏移0x0001 0000。定义#define GPIOC_BASE (APB2PERIPH_BASE0x00010000)再看下GPIOC相关寄存器都是在GPIOC_BASE的基础上偏移地址每次都是4个字节32位。所以定义#define GPIOC_CRL *(unsigned int *)( GPIOC_BASE0x00) #define GPIOC_CRH *(unsigned int *)( GPIOC_BASE0x04) #define GPIOC_IDR *(unsigned int *)( GPIOC_BASE0x08) #define GPIOC_ODR *(unsigned int *)( GPIOC_BASE0x0C) #define GPIOC_BSRR *(unsigned int *)( GPIOC_BASE0x10) #define GPIOC_BRR *(unsigned int *)( GPIOC_BASE0x14) #define GPIOC_LCKR *(unsigned int *)( GPIOC_BASE0x18)接下来配置时钟地址根据地址分配可得#define RCC_BASE (AHBPERIPH_BASE0x1000)根据上图可知RCC_APB2ENR是在RCC基础上偏移0x18所以#define RCC_APB2ENR *unsigned int*(RCC_BASE0x18)以上讲了那么多无非是把上节课程序中的*unsigned int*0x4002 1018 *unsigned int*0x40011004 *unsigned int*0x40011004 *unsigned int*0x4001 100C讲解更能清楚我们不希望在main函数中出现类似0x4002 1018的地址而使用可读性更好的英文单词来表述。因此仿51单片机的写法把一些地址定义放在头文件stm32f10x.h中。//头文件stm32f10x.h #define APB2PERIPH_BASE (PERIPH_BASE 0x10000) /* AHB总线基地址 */ #define AHBPERIPH_BASE (PERIPH_BASE 0x20000) /*GPIOC外设基地址*/ #define GPIOC_BASE (APB2PERIPH_BASE 0x1000) /* GPIOC寄存器地址 */ #define GPIOC_CRL *(unsigned int*)(GPIOC_BASE0x00) #define GPIOC_CRH *(unsigned int*)(GPIOC_BASE0x04) #define GPIOC_IDR *(unsigned int*)(GPIOC_BASE0x08) #define GPIOC_ODR *(unsigned int*)(GPIOC_BASE0x0C) #define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE0x10) #define GPIOC_BRR *(unsigned int*)(GPIOC_BASE0x14) #define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE0x18) /*RCC外设基地址*/ #define RCC_BASE (AHBPERIPH_BASE 0x1000) /*RCC的AHB2时钟使能寄存器地址*/ #define RCC_APB2ENR *(unsigned int*)(RCC_BASE0x18)那么在main函数中可以写成#include “stm32f10x.h” int main(void) { RCC_APB2ENR | 14; GPIOC_CRH ~(0x0F(4*5)); GPIOC_CRH |(1(4*5)); GPIOC_ODR ~(113); while(1); } void SystemIinit() { }接下来做实验在文件夹中新建文件“stm32f10x.h”。将头文件添加到Keil工程中添加方式参考添加启动文件的过程。打开头文件输入如下程序。在main.c中输入如下程序。编程下载到开发板观察到实验现象。