使用寄存器点亮led

使用寄存器来操作 STM32 使 PB5 输出一个低电平。要操作 STM32 寄存器,需要使用 C 语言对其封装,这部分程序放在 stm32f10x.h 中

stm32f10x.h

#define PERIPH_BASE      ((unsigned int)0x40000000)   //  APB1总线基地址  0x4000 0000
	
#define APB2PERIPH_BASE  (PERIPH_BASE + 0x00010000)   //  APB2总线基地址  0x4001 0000

#define GPIOB_BASE       (APB2PERIPH_BASE + 0x0C00)   //  GPIOB外设基地址 0x4001 0000

#define GPIOB_CRL 	 	 *(unsigned int*)(GPIOB_BASE+0x00)  // GPIOB外设基地址 + 偏移值
#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)


#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000) // AHB总线

#define RCC_BASE 		 (AHBPERIPH_BASE + 0x1000)
#define RCC_APB2ENR 	 *(unsigned int*)(RCC_BASE+0x18)
/*GPIOB 外设内部含有很多个寄存器,比如 GPIOB_CRL、GPIOB_CRH 端 口配置寄存器、GPIOB_BSRR 置位复位寄存器等,通过他们各自的偏移地址就可 以获取对应的寄存器地址,然后要操作地址里面的内容就需要使用到指针,将其 强制转换为 unsigned int*指针类型,然后在通过一个*指针来操作该地址里面 的内容*/

使用寄存器点亮led_第1张图片

使用寄存器点亮led_第2张图片

使用寄存器点亮led_第3张图片

使用寄存器点亮led_第4张图片

0x4000 0000-0x4000 77FF: APB1 总线外设。
0x4000 7800-0x4000 FFFF: 预留。
0x4001 0000-0x4001 3FFF: APB2 总线外设。
0x4001 4000-0x4001 7FFF: 预留。
0x4001 8000-0x4002 33FF: AHB 总线外设。
0x4002 4400-0x5FFF FFFF: 预留。

 

使用寄存器点亮led_第5张图片

(1)包含 stm32f10x.h 头文件,在这个头文件中我们定义的都是寄存器,
因此如果要在其他文件中使用这些寄存器就需要把这个头文件包含进来,否则编
译就会报错。
(2)SystemInit 函数,在前面讲解启动文件时已经说明,程序运行的时候
先进入这个函数进行 STM32 的初始化,如果不写这个函数编译器就会报错。这里
我们编写这个函数,里面并不对其操作。
(3)开启 GPIOB 时钟。要使 PB5 正常工作输出一个低电平,必须要打开它
的时钟。RCC_APB2ENR 寄存器是在 stm32f10x.h 头文件中定义好的,只要查下
《STM32F1xx 中文参考手册》RCC 时钟使能寄存器内容就可以知道此寄存器的第
3 位是控制 GPIOB 外设的时钟使能位,只有该位为 1 时才使能,如果为 0 即关闭
GPIOB 时钟。所以要让 1 左移 3 位。
(4)配置 GPIOB 为通用推挽输出模式。STM32 的 GPIO 模式有很多,可根据
CRx 寄存器设置,CRL 对应 GPIO 的低 8 位,CRH 对应 GPIO 的高 8 位。如果不是
特殊需求,一般输出采用推完输出模式。我们要让 PB5 管脚输出一个低电平,故
使用推挽输出模式。只要查下《STM32F1xx 中文参考手册》GPIO 配置寄存器内容
就可以知道此寄存器内每 4 位控制一个管脚。
(5)使 PB5 输出低电平。GPIOB_BSRR 为置位复位寄存器,只要查下
《STM32F1xx 中文参考手册》GPIO 置位复位寄存器内容就可以知道,其高 16 位用于复位,如果当高 16 位某位为 1,表示那一位管脚输出低电平,为 0 不影响
其输出电平。如果当低 16 位的某位为 1,表示那一位管脚输出高电平,为 0 不
影响其输出电平。所以要让 1 左移 16+5 位。

 

/*******************************************************************************
*                 
*                 		       普中科技
--------------------------------------------------------------------------------
* 实 验 名		 : 使用寄存器点亮一个LED
* 实验说明       : 操作寄存器控制LED1指示灯闪烁
* 连接方式       : 
* 注    意		 : 	
*******************************************************************************/

#include "stm32f10x.h"

typedef unsigned int u32;   //类型重定义 unsigned int -- u32

void SystemInit()
{
	
}

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,通过while循环占用CPU,达到延时功能
* 输    入         : i
* 输    出         : 无
*******************************************************************************/
void delay(u32 i)
{
	while(i--);
}

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	RCC_APB2ENR |= 1<<3;
	GPIOB_CRL &= ~( 0x0F<< (4*5));
	GPIOB_CRL |= (3<<4*5);
	GPIOB_BSRR=(1<<(16+5));
	while(1)
	{
		GPIOB_BSRR=(1<<(16+5));
		delay(0xFFFFF);
		GPIOB_BSRR=(1<<(5));
		delay(0xFFFFF);
	}
}



 

你可能感兴趣的:(STM32F103)