STM32 一灯大师——寄存器点亮流水灯

2023-11-10

目录

1、配置端口输出数据寄存器(ODR)

2、配置低寄存器(CRL)

3、配置复位和时钟控制寄存器(RCC)

4、拓展:如何让PC2和PC3两个LED灯同时闪烁?

5、总结: GPIO功能框图和常用的寄存器

(1)CRL和CRH寄存器

(2)IDR和ODR寄存器

(3)端口位清楚寄存器(BRR)

(4)端口位设置/清除寄存器(BSRR)

6、总结:什么是推挽输出,什么是开漏输出

 (1)推挽输出:

 (2)开漏输出:

7、配置GPIO初始化结构体步骤

学习51我们从最简单的点灯开始,同样32也是,首先我们从最简单的寄存器控制点亮LED开始。

1、配置端口输出数据寄存器(ODR)

控制LED灯:给PC2/PC3输出低电平,LED灯亮;给PC2/PC3输出高电平,LED灯会灭。

那么如何控制端口:我们要选择GPIO寄存器的端口输出数据寄存器,该寄存器共有32位,高16位始终为0。因为控制端口是PC2/3,所以,外设基地址按照GPIOC的去写。

绝对地址=外设基地址+偏移地址

0X4001 1000+0C=0X4001 100C

注意:找到绝对地址之后,该绝对地址在系统看来只是一个数,所以我们要对他进行类型转换,让系统知道我们是对该地址里的内容进行操作。(unsigned int *)0x4001 100c:把后面的数转换为unsigned int指针类型,编译器就会认为这串数是个地址;*(unsigned int *)0x4001 100c表示该地址里的值。

*(unsigned int *)0X4001100C &= ~(1<<2);
*(unsigned int *)0X4001100C &= ~(1<<3);

PC2亮灭是对ODR2进行修改(左移2位),PC3亮灭是对ODR3进行修改(左移3位)。

还要注意的是,绝对地址的中间不能添加空格符!但是这样是烧写进去之后灯不会亮,是因为我们还没配置CRL寄存器。

2、配置低寄存器(CRL)

 这个寄存器来配置GPIO端口的输入输出模式。

由于是RC2/3所以是CNF2和MODE2来控制,CNF2取决于MODE的配置,MODE选择01,CNF2选择00(通用推挽输出模式)所以是0001(注意一个小方框里面就是2位)。

3、配置复位和时钟控制寄存器(RCC)

配置到这里,但是灯还是不会亮。因为stm32为了节省功耗,让每个外设都对应时钟,在上电复位之后,所有时钟都是关闭的。所以,如果你想使用GPIO这个外设,就需要把GPIO外设的时钟给打开。 由于GPIO是属于APB2的,所以用到APB2 外设时钟使能寄存器(RCC_APB2ENR);如果是属于APB1的外设,就用APB1外设时钟使能寄存器(RCC_APB1ENR)。

寻找RCC寄存器的绝对地址:偏移地址0X18,RCC属于AHB,起始地址为0X4002 1000,绝对地址为0X4002 1018

我们用到端口C,且置1是让时钟打开。让第4位置1即可。

 *(unsigned int *)0x40021018 |= (1<<4);

4、拓展:如何让PC2和PC3两个LED灯同时闪烁?

  CRL寄存器和ODR寄存器两个端口都要配置

#include "stm32f10x.h"

void soft_delay(unsigned int count);

int main(void)
{
	// &= ~用来清0(给某一位单独置0)
	// |= 用来给某一位单独置1
	
	//配置RCC寄存器,使能GPIO口的时钟
	*(unsigned int *)0x40021018 |= (1<<4); 
	
	//配置CRL寄存器,配置为推挽输出
	*(unsigned int *)0x40011000 |= (1<<(4*3)); 
	*(unsigned int *)0x40011000 |= (1<<(4*2)); 
	
	//配置ODR寄存器,决定I/O口输出低或高电平
 	//*(unsigned int *)0x4001100C &= ~(1<<2); 
	while(1)
	{
		*(unsigned int *)0x4001100C &= ~(1<<2); //亮
		*(unsigned int *)0x4001100C &= ~(1<<3); //亮
		soft_delay(0xfffff);
		*(unsigned int *)0x4001100C |= (1<<2); //灭
		*(unsigned int *)0x4001100C |= (1<<3); //灭
		soft_delay(0xfffff);
	}
}

void soft_delay(unsigned int count)//延时函数,但是不知道延时多长时间
{
	for(;count!=0;count--);
}

void SystemInit(void)
{
	
}

至此,点灯工作完毕,灯开始流水闪烁。

---------------------------------------------------------------------------------------------------------------------------------

5、总结: GPIO功能框图和常用的寄存器

GPIO是通用输入输出端口的简称,软件可控制的引脚。

(1)CRL和CRH寄存器

这两个都是32位的寄存器,因为STM32的GPIO口不像51单片机一样只有高低电平两个参数,STM32的每个GPIO口都有八种输出方式,通过寄存器配置确定是哪一种方式,除此之外,还有输出的速度,也是GPIO口的一个重要的参数。所以,要想描述STM32的一个GPIO的状态,就需要四个位(八种输出方式和三种输出速度),STM32的一个GPIO组有16个GPIO口,CRL和CRH都拥有32个位,CRL负责描述一个GPIO组的低八位GPIO(32/8 = 4,刚好够用),CRH负责描述一个GPIO组的高八位GPIO(同样,32/8 = 4,刚好够用)。

(2)IDR和ODR寄存器

1.IDR是一个端口输入数据寄存器,只使用了低16位,该寄存器为只读寄存器,并且只能以16位数据的形式读出,作用是可以通过其读出寄存器的状态是低还是高,要想知道具体是哪个寄存器的话,就需要看具体那个位的值了,在固件库中,通过

GPIO_ReadInputDataBit函数实现:

比如要读取GPIOA.5的状态,那么方法是:

返回值是 1(Bit_SET)或者 0(Bit_RESET);

2.ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。在固件库中设置 ODR 寄存器的值来控制 IO 口的输出状态是通过函数 GPIO_Write 来实现的:

该函数一般用来往一次性一个 GPIO 的多个端口设值。

(3)端口位清楚寄存器(BRR)


某一位置1:清除对应的位为0(复位)

(4)端口位设置/清除寄存器(BSRR)

高16位:清除,置1:清除对应的位为0(复位)

低16位:设置,置1:设置对应的位为1

BRR和BSRR这两个寄存器配置好之后会把数据传送给ODR这一位的数据就是0或者1.

6、总结:什么是推挽输出,什么是开漏输出

 (1)推挽输出:

     1、可以输出高低电平,用于连接数字器件,高电平由VDD决定,低电平由VSS决定。

     2、推挽结构指两个三极管受两路互补的信号控制,总是在一个导通的时候另外一个截止,优点开关效率效率高,电流大,驱动能力强。

     3、输出高电平时,电流输出到负载,叫拉电流,可以理解成推,输出低电平时,负载电流流向芯片,叫灌电流,即挽。

 (2)开漏输出:

     1、只能输出低电平,不能输出高电平。

     2、如果要输出高电平,则需要外接上拉。

     3、开漏输出具有“线与”功能,一个为低,全部为低,多用于I2C和SMBUS总线。

7、配置GPIO初始化结构体步骤

  (1)选定具体的GPIO(选择哪个I/O口)

  (2)配置GPIO工作模式(CRL和CRH寄存器)(CRL控制低8位I/O口,CRH控制高8位I/O口)

  (3)控制GPIO输出高低电平(ODR、BRR和BSRR)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 一灯大师——寄存器点亮流水灯 的相关文章

随机推荐

  • 【VS编译器】使用scanf函数的方法

    1 VS中使用scanf函数的问题 VS中运行以下代码 include
  • windows杀死nginx进程

    查看80端口号列表 tasklist findstr 80 根据端口号查看nginx tasklist findstr 28024 杀死nginx进程 taskkill f t im nginx exe
  • OC门与OD门以及线与逻辑

    OC Open Collector 门又叫集电极开路门 主要针对的是BJT电路 从上往下依次是基极 集电极 发射极 OD Open Drain 门又叫漏极开路门 主要针对的是MOS管 从上往下依次是漏极 栅极 源极 线与逻辑指的是两个输出端
  • [从零开始学习FPGA编程-22]:进阶篇 - 架构 - FPGA内部硬件电路的设计与建模

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 第1章 什么是数字硬件电路 1 1 什么是硬件电路
  • 使用docker-compose启动docker镜像报错exec ./docker-entrypoint.sh: no such file or directory

    报错原因 exec docker entrypoint sh no such file or directory 我们可以在linux下通过cat v命令查看 sh文件 例 cat v Dockerfile WORKDIR tools M
  • 二维向量叉积的几何意义

    叉乘 cross product 相对于点乘 叉乘可能更有用吧 2维空间中的叉乘是 V1 x1 y1 X V2 x2 y2 x1y2 y1x2看起来像个标量 事实上叉乘的结果是个向量 方向在z轴上 上述结果是它的模 在二维空间里 让我们暂时
  • Zotero 知网 PDF与CAJ 抓取模式切换

    Zotero可以通过安装茉莉花插件 jasminum 一键安装https github com l0o0 translators CN内的中文翻译器 从而实现对知网文献元数据以及相应PDF的抓取 但是在使用过程中我发现 由于知网对于学位论文
  • Visual Studio开始Python编程 && Windows下用PyCharm

    Windows搭建python开发环境 首先需要去python的官网下载环境 鼠标移动到Downloads的tab上 在这里可以下载 python的环境还是很人性化的 没有那么多罗里吧嗦的配置什么的 下载好以后直接无脑next就行了 直到f
  • VS中为QT项目添加多个ui

    在VS中创建QT项目 如下图所示 这里已经有一个 ui文件 现在的目标是再添加一个 ui文件并使之在项目中可用 添加新的 ui文件 右击项目 gt 添加 gt 新建项 gt Visual C gt QT 选择一个模板 如 Qt Dialog
  • 目标检测模型从训练到部署,其实如此简单

    目标检测的任务是找出图像中所有感兴趣的目标 物体 确定它们的类别和位置 是计算机视觉领域的核心问题之一 目标检测已应用到诸多领域 比如如安防 无人销售 自动驾驶和军事等 在许多情况下 运行目标检测程序的设备并不是常用的电脑 而是仅包含必要外
  • 分布式事务管理(Seata)

    文章目录 1 概述 分布式事务问题 什么是Seata Seata术语 怎么用 Windows安装 Docker安装 MySQL nacos seata 2 配置官网案例 分析业务逻辑 创建数据库 订单模块 建Module POM YML f
  • Qt 的一些心得

    一 背景刷成黑色 前景色设为白色 方法一 paltette方式 经测试 该方法不会影响到其他控件 推荐使用 QPalette bgpal palette bgpal setColor QPalette Background QColor 0
  • Vue.js基本指令

    目录 插值表达式 v html和v text指令 例1 v on指令 例1 v model指令 例1 v if指令 例1 判断二月份有几天 例2 比较两个数的大小 v show指令 v if和v show的区别 v for 指令 遍历数组
  • 【skynet】 skynet 之 snax

    local skynet require skynet local snax require snax local p calc nil 初始化函数 function init local seed math floor skynet ti
  • xss挑战之旅level 1 - level 4

    Level 1 观察url中的 name参数 向网站提交数据 然后返回到页面上 Level 2 第二关是可以在输入框中输入一个数据提交给服务器 然后提交的数据是会被显示到页面上的 此时再使用第一关的payload已经是不行了 看一下源码 在
  • GitHub建立个人网站(一)

    github可以当做自己的个人博客网站 做一个这样的网站的好处有哪些 装 X 如果网站够炫的话 ps 以后抽空闲下来了 肯定要弄个好看的页面 好好装X 很好的用来总结自己所学的知识 可能因为流量的问题 github上面确实只能当做记载的 但
  • 探索App保活黑科技

    我们来聊聊目前可用的App保活技术 这些方法在目前看来都还可以用 并且效果也很好 但无法保证长期可用 因为Android操作系统本身可能会更改其策略 而且各厂商在定制Android时也会引入自家节电策略 这些都有可能破坏我们原本可用的保活逻
  • 在C#中怎么设置一个全局变量,方便我在其他的窗口中可以调用

    大家按照下面的步骤就可以啦 1 首先我们进入program cs 2 在Program类后面添加一个类 注意要是静态类 如下 public static class user11 public static string yhm 3 进入其
  • 《人工智能(智能系统指南,第二版)》读书笔记——3、第二章

    1 introduction to knowledge based intelligent systems summary questions for review references 2 rule based expert system
  • STM32 一灯大师——寄存器点亮流水灯

    目录 1 配置端口输出数据寄存器 ODR 2 配置低寄存器 CRL 3 配置复位和时钟控制寄存器 RCC 4 拓展 如何让PC2和PC3两个LED灯同时闪烁 5 总结 GPIO功能框图和常用的寄存器 1 CRL和CRH寄存器 2 IDR和O