当前位置: 首页 > news >正文

STM32使用寄存器点灯实验

寄存器点灯实验

操作过程

使能IO口时钟配置寄存器RCC_APB2ENR

初始化IO口模式,配置寄存器GPIOx_CRH/CRL

操作IO口,输出高低电平,配置寄存器GPIOx_ODR或者BSRR/BRR。

APB2 外设时钟使能寄存器(RCC_APB2ENR)

在STM32中文参考手册6.3RCC寄存器描述的6.3.7小节可以看到该寄存器的使用说明

在这里插入图片描述

因为使用的是GPIOA端口组,所以使能IOPAEN位,该位置1则IO端口A时钟开启

端口配置低寄存器(GPIOx_CRL) (x=A…E)

在中文参考手册的8.2节可以找到GPIO寄存器相关配置寄存器的描述
在这里插入图片描述

因为开发板上的PA1连接到了LED灯,所以对CNF1和MODE1进行初始化,MODE1初始化为11,设置为输出模式,速度为50MHz,CNF1初始化为00,设置为通用推挽输出模式

因为没有用到更高的引脚位,所以端口配置高寄存器(GPIOx_CRH) 并不用配置

端口输出数据寄存器(GPIOx_ODR)

在这里插入图片描述

往ODR寄存器的ODR1位写入0,则PA1引脚输出低电平,LED灯被点亮

端口位设置/清除寄存器(GPIOx_BSRR) ,端口位清除寄存器(GPIOx_BRR)

也可以使用这两个寄存器,因为是PA1输出低电平LED灯才被点亮,所以这两个寄存器都有效

如果LED灯是引脚输出高电平才能被点亮,那就只有端口位设置/清除寄存器(GPIOx_BSRR)的设置功能才能输出高电平,BRR寄存器不行

在这里插入图片描述

在这里插入图片描述

程序

参照手册搭建好寄存器的工程模板后,新建LED.h和LED.c文件,开始编写代码

LED.h

在头文件中要添加函数声明,因为写了多种初始化方法,所以这些函数都要添加声明

#ifndef __LED_H__
#define __LED_H__

//宏定义,LED_Init_3,LED_Init_4
#define IOPAEN                  0x01<<2
#define CNF1_AND_MODE1          ((u32)0x0F<<4)
#define OUT_MODE_PP			   ((u32)0x03<<4)
#define ODR1                    ((u16)0x01<<1)
#define BSRR_BR1                ((u32)0x01<<17)
#define BRR_BR1                 ((u16)0x01<<1)

void LED_Init_1(void);
void LED_Init_2(void);
void LED_Init_3(void);
void LED_Init_4(void);

#endif

LED.c

分别用三种不同的写法实现点亮LED灯,方法一是直接往寄存器写入十六进制,方法二是用移位的方法初始化寄存器,但这两种方法的数值第一眼看去不好理解,不看参考手册的话很难知道0xFFF4是初始化什么,(u16)0x01<<2也是一样

所以推荐使用第三种方法,用宏定义,先在LED.h头文件中定义好数值,然后使用时直接调用宏名即可,可以让人一眼就看出初始化的是哪个位

第四种方法是使用BSRR或BRR寄存器对PA1进行赋值,一样能使LED灯点亮

#include "LED.h"
#include "stm32f10x.h"

/**
  * @name 	LED_Init_1
  * @brief	LED初始化-寄存器(写法1)
  * @param	None
  * @retval	None
  */
void LED_Init_1()
{
	//初始化APB2上GPIOA的时钟
	RCC->APB2ENR |= 0xFFF4;

  //GPIOA端口配置低寄存器
  //4 ~ 7配置的是PA1,所以先将这4位清零
  GPIOA->CRL &= 0xFFFFFF0F;

  //然后MODE1初始化为11,CNF1初始化为00,设置为通用推挽输出模式
  GPIOA->CRL |= 0xFFFFFF3F;

  //配置端口输出数据寄存器,将ODR1置0,输出低电平,点亮LED
  GPIOA->ODR &= 0xFFFD;
}

/**
  * @name 	LED_Init_2
  * @brief	LED初始化-寄存器(写法2)
  * @param	None
  * @retval	None
  */
void LED_Init_2()
{
  //初始化APB2上GPIOA的时钟
  RCC->APB2ENR |= ((u16)0x01<<2);

  //GPIOA端口配置低寄存器
  //4 ~ 7配置的是PA1,所以先将这4位清零
  GPIOA->CRL &= ~((u32)0x0F<<4);

  //然后MODE1初始化为11,CNF1初始化为00,设置为通用推挽输出模式
  GPIOA->CRL |= ((u32)0x03<<4);

  //配置端口输出数据寄存器,将ODR1置0,输出低电平,点亮LED
  GPIOA->ODR &= ~((u16)0x01<<1);
}

/**
  * @name 	LED_Init_3
  * @brief	LED初始化-寄存器(写法3)
  * @param	None
  * @retval	None
  */
void LED_Init_3()
{
	//初始化APB2上GPIOA的时钟
	RCC->APB2ENR |= IOPAEN;

	//GPIOA端口配置低寄存器
	//4 ~ 7配置的是PA1,所以先将这4位清零
	GPIOA->CRL &= ~CNF1_AND_MODE1;

	//然后MODE1初始化为11,CNF1初始化为00,设置为通用推挽输出模式
	GPIOA->CRL |= OUT_MODE_PP;

	//配置端口输出数据寄存器,将ODR1置0,输出低电平,点亮LED
	GPIOA->ODR &= ~ODR1;
}


/**
  * @name 	LED_Init_4
  * @brief	LED初始化-寄存器(测试BSRR寄存器和BRR寄存器)
  * @param	None
  * @retval	None
  */
void LED_Init_4()
{
  //初始化APB2上GPIOA的时钟
	RCC->APB2ENR |= IOPAEN;

	//GPIOA端口配置低寄存器
	//4 ~ 7配置的是PA1,所以先将这4位清零
	GPIOA->CRL &= ~CNF1_AND_MODE1;

	//然后MODE1初始化为11,CNF1初始化为00,设置为通用推挽输出模式
	GPIOA->CRL |= OUT_MODE_PP;

	//配置端口输出数据寄存器,将ODR1置0,输出低电平,点亮LED
	//GPIOA->ODR &= ~ODR1;

  //配置端口位设置/清除寄存器(GPIOx_BSRR) 31-16位置1则对应的ODR位清0,LED点亮
  //GPIOA->BSRR |= BSRR_BR1;

  //配置端口位清除寄存器(GPIOx_BRR) 15-0位置1则对应的ODR位清0,LED点亮
  GPIOA->BRR |= BRR_BR1;
}

main.c

主函数中引入LED.h头文件后,直接调用LED初始化函数即可

#include "LED.h"

int main()
{
	//LED_Init_1();
	//LED_Init_2();
	//LED_Init_3();
	LED_Init_4();
	while(1)
	{
		
	}
}

相关文章:

  • 技术对接35
  • 金仓数据库 KingbaseES 插件参考手册 plsql_pldbgapi
  • 测试面试 | 某 BAT 大厂测试开发面试真题与重点解析
  • 2022鹏城杯
  • Kubernetes学习笔记-保障集群内节点和网络安全(3)限制pod使用安全相关的特性20220828
  • [免费专栏] Android安全之利用ADT获取内存中的敏感信息
  • 网络编程必读经典书籍
  • TDengine-解决集群搭建过程中启动失败问题
  • STM32 GPIO工作原理
  • ros入门(九)----ros navigation
  • 数学建模神经网络应用,构建神经网络模型方法
  • 小程序模板报价_小程序模板价格_小程序模板使用多少钱
  • 校园跑腿小程序市场需要和功能分析!
  • 上半年业绩韧性增强,两大核心业务成第二增长点,商汤用硬科技冲刺AI长跑
  • MySQL 数据库(DBMS)安装教程图文详解
  • Apache Pulsar 2.1 重磅发布
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • create-react-app项目添加less配置
  • CSS盒模型深入
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • Java 最常见的 200+ 面试题:面试必备
  • Laravel Telescope:优雅的应用调试工具
  • miaov-React 最佳入门
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • PhantomJS 安装
  • webpack+react项目初体验——记录我的webpack环境配置
  • windows下mongoDB的环境配置
  • 构造函数(constructor)与原型链(prototype)关系
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 深度解析利用ES6进行Promise封装总结
  • 突破自己的技术思维
  • 想写好前端,先练好内功
  • 小李飞刀:SQL题目刷起来!
  • 《天龙八部3D》Unity技术方案揭秘
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (7)STL算法之交换赋值
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (转)创业家杂志:UCWEB天使第一步
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • .NET Core 版本不支持的问题
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .net专家(张羿专栏)
  • ?.的用法
  • @NestedConfigurationProperty 注解用法
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • @我的前任是个极品 微博分析
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [AX]AX2012 SSRS报表Drill through action
  • [C#C++]类CLASS
  • [C++]类和对象【上篇】