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 一灯大师——寄存器点亮流水灯 的相关文章

  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 当数据大小较小时,内存到内存 DMA 传输是否需要权衡?

    我正在学习 STM32 F4 微控制器 我正在尝试找出使用 DMA 的限制 根据我的理解和研究 我知道如果数据量较小 即设备使用DMA生成或消耗少量数据 则开销会增加 因为DMA传输需要DMA控制器执行操作 从而不必要地增加系统成本 我做了
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • SHT10温湿度传感器——STM32驱动

    实验效果 硬件外观 接线 3 3V供电 IIC通讯 代码获取 查看下方 END
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • Arm:objcopy 如何知道 elf 中的哪些部分要包含在二进制或 ihex 中?

    我正在开发一个项目 其中涉及解析arm elf 文件并从中提取部分 显然 elf 文件中有很多部分没有加载到闪存中 但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中 以arm elf文件的以下reade
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT

随机推荐

  • 【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