【STM32标准库】------- 标准外设库的基本结构和寄存器封装原理

1、外设库的结构介绍
(1)标准外设库的下载和解压 en.stsw-stm32054.zip
(2)建立SourceInsight工程
(3)文件夹结构和主要文件的作用
在这里插入图片描述

2.标准库对硬件信息的封装方式
(1)寄存器地址的封装-----以TIM2为例:


  • 先定义外设TIM2的基地址
  • 再用结构体封装该外设的所有寄存器
  • 通过指向各个外设的指针访问各外设的控制寄存器。这些指针所指向的数据结构与各个外设的控
    制寄存器布局一一对应把外设的基地址转换成该结构体类型的指针
    在这里插入图片描述
    (2)寄存器位定义的封装-----以RCC模块为例:

在这里插入图片描述
(3)外设操作的封装-----以RCC模块为例:
对RCC的各种操作都被封装成若干函数
在这里插入图片描述

3.使用结构体方式访问寄存器的原理
(1)C语言访问寄存器的本质是C语言访问内存,本质思路是:定义一个指针(临时变量)指向这块内存,然后*p = xx这种方式去解引用指针从而向目标内存中写入内容
(2)缺陷:当寄存器多了之后每一个寄存器都要定义一套套路,很麻烦。
(3)解决思路:就是打包,批发式的定义,用结构体(想一下为什么不用数组?)的方式进行打包。具体做法是:把整个一个模块的所有寄存器(地址是连接的)打包在一个结构体中,每个寄存器对应结构体中的一个元素,然后结构体基地址对应寄存器组的基地址,将来就可以通过结构体的各个元素来访问各个寄存器了
(4)结构体方式来访问寄存器和指针式访问寄存器,本质上其实是一样的,区别是C语言的封装不同。

(5)实现代码-----实现LED闪烁
使用结构体方式访问寄存器---------以GPIO模块为例
gpio.h

#ifndef __GPIO_H__
#define __GPIO_H__

#define GPIOB_BASE		0x40010C00          //LED接的是GPIOB端口

#define GPIOB_CRH		(GPIOB_BASE + 0x04)
#define GPIOB_ODR		(GPIOB_BASE + 0x0C)
#define GPIOB_BSRR		(GPIOB_BASE + 0x10)
#define GPIOB_BRR		(GPIOB_BASE + 0x14)

#define RCC_APB2ENR		0x40021018

//-------------------------------------------------

#define rGPIOB_CRH 		(*((unsigned int *)GPIOB_CRH))
#define rGPIOB_ODR 		(*((unsigned int *)GPIOB_ODR))
#define rGPIOB_BSRR 	(*((unsigned int *)GPIOB_BSRR))
#define rGPIOB_BRR 		(*((unsigned int *)GPIOB_BRR))

#define rRCC_APB2ENR 	(*((unsigned int *)RCC_APB2ENR))

// 用结构体的方式对寄存器访问
typedef struct 
{
	volatile unsigned int CRL;
	volatile unsigned int CRH;
	volatile unsigned int IDR;			// 定义为32位
	volatile unsigned int ODR;
	volatile unsigned int BSRR;	 		// 10
	volatile unsigned int BRR;
	volatile unsigned int LCKR;
}GPIO_Typedef;


GPIO_Typedef *pGPIOB = (GPIO_Typedef *)GPIOB_BASE;

gpio.c

#include "gpio.h"
void main(void)
{

	led_init();
	led_flash();

 	while (1);
}


void led_init(void)
{
	// 因为RCC部分还没有定义结构体,所以还按照原来的方式去操作
	rRCC_APB2ENR = 0x00000008;             //要打开GPIOB的外设时钟才能驱动GPIO端口

	pGPIOB->CRH = 0x33333333;
	pGPIOB->ODR = 0x0000AA00;
}

void led_flash(void)                //LED闪烁3下
{
	unsigned int i = 0;
	
	for (i=0; i<3; i++)
	{
	 	pGPIOB->ODR = 0x0000ff00;		// 全亮
		delay();
		pGPIOB->ODR = 0x00000000;		// 全灭
		delay();
	}

}
void delay(void)                //延时函数
{
	unsigned int i, j;

	for (i=0; i<1000; i++)
		for (j=0; j<2000; j++);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值