STM32手写寄存器的方式实现点亮LED灯

这次是从头开始学习STM32,看野火的视频开始学习,感觉需要记录的时候就要记录一下学习的心得。野火视频学习的老师讲的还是很到位的,能够学习到很多的细节之处,有时会感觉很啰嗦,但是不得不说确实很详细,只有这样对于真正的底层才能更清楚明白是怎么回事,原理很重要。写这篇博文的目的是记录我的练习过程中连续好几天犯得同一个错误,每次写都这样,而且找半天找不到哪里错了,必须拿着原来写的一行一行的对,才能发现问题,特此记录一下,下次再范同样的错误时就来看这篇文章吧!感觉这样就能快速的定位错误了。我犯得错误就是每次宏定义外设基地址时都定义成了无符号整型指针类型了,其实只需要定义成无符号整型类型就好了。结果每次都忘了这事,今天有一次查了半天,感觉还是要记录一下才对,太浪费时间了。

好了,多了不想说了,直接贴代码吧:

#include "stm32f10x.h"



int main(void)
{
	/*
	
	RCC_APB2ENR = 0x0008;  //APB2外设时钟使能寄存器
	
	GPIOB_CRL = 0x0003;    //GPIOB端口配置低寄存器
	
	GPIOB_ODR = 0xFFFE;    //GPIOB端口输出配置寄存器
	
	*/
	
	RCC->APB2ENR = 0x0008;  //APB2外设时钟使能寄存器
	
	GPIOB->CRL = 0x0003;    //GPIOB端口配置低寄存器
	
	GPIOB->ODR = 0xFFFE;    //GPIOB端口输出配置寄存器
		
	
}

void SystemInit(void)
{
	
}
#ifndef __STM32F10X_H    //如果没有编译__STM32F10X_H
#define __STM32F10X_H    //就编译 __STM32F10X_H

typedef unsigned int uint32_t;    //把无符号整型重新命名为  :uint32_t

#define PERIPHL_BASE               ((uint32_t )0x40000000)   // 外设基地址(**********这里主要只是强转成无符号整型(不是指针)**********)
#define APB1_PERIPHL_BASE          (PERIPHL_BASE)            // APB1基地址 = 外设基地址
#define APB2_PERIPHL_BASE          (PERIPHL_BASE + 0x10000)  // APB2基地址 = 外设基地址 + 0x10000
#define AHB_PERIPHL_BASE           (PERIPHL_BASE + 0x20000)  // AHB基地址  = 外设基地址 + 0x20000

#define RCC_BASE                    (AHB_PERIPHL_BASE + 0x1000)  //RCC基地址 = AHB基地址 + 0x1000
#define GPIOB_BASE                  (APB2_PERIPHL_BASE + 0x0C00) //GPIOB基地址 = APB2基地址 + 0x0C00

//#define RCC_APB2ENR                 *((uint32_t *)(RCC_BASE + 0x18))    //APB2外设时钟使能寄存器
//#define GPIOB_CRL                   *((uint32_t *)(GPIOB_BASE + 0x00))  //GPIOB端口配置低寄存器
//#define GPIOB_ODR                   *((uint32_t *)(GPIOB_BASE + 0x0C))  //GPIOB端口输出配置寄存器

typedef struct
{                      //创建结构体GPIO_TypeDef 里面的每个成员地址正好相差4个字节,把GPIOB的地址赋给他
	uint32_t CRL;      //结构体内部的每个成员的地址就正好是GPIOB每个寄存器的地址,免去了一个一个的#define了
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR;
	uint32_t BRR;
	uint32_t LCKR;
}GPIO_TypeDef;

typedef struct
{                      //创建结构体RCC_TypeDef 里面的每个成员地址正好相差4个字节,把RCC的基地址赋给他
	uint32_t CR;       //结构体内部的每个成员的地址就正好是RCC每个寄存器的地址,免去了一个一个的#define了
	uint32_t CFGR;
	uint32_t CIR;
	uint32_t APB2_RSTR;
	uint32_t APB1_RSTR;
	uint32_t AHBENR;
	uint32_t APB2ENR;
	uint32_t APB1ENR;
}RCC_TypeDef;

#define GPIOB                    ((GPIO_TypeDef *)GPIOB_BASE)  // GPIOB就是把GPIOB的基地址强转成GPIO结构体的指针
#define RCC                      ((RCC_TypeDef *)RCC_BASE)     // RCC就是把RCC的基地址强转成RCC结构体的指针







#endif  /*__STM32F10X_H*/  //结束编译




这个工程是很简单的,从0开始建立工程,自己手写寄存器映射,感觉对标准库的理解又前进了一大步。

整个工程只是参考了数据手册中对RCC和GPIO的寄存器描述

最后编译就能正常点亮GPIOB 0的LED灯了:

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尚久龙

你的鼓励是我最大的动力!谢谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值