【STM32】位带原理分析和应用
00. 目录
文章目录
- 00. 目录
- 01. 位带概述
- 02. 位带操作
- 03. 位带C语言实现
- 04. 应用示例一
- 05. 应用示例二
- 06. 附录
- 07. 声明
01. 位带概述
位带操作简单的说,就是把每个比特膨胀为一个 32 位的字,当访问这些字的时候就达到了访问比特的目的,比如说 GPIO 的 ODR 寄存器有 32 个位,那么可以映射到 32 个地址上,我们去访问这 32 个地址就达到访问 32 个比特的目的。这样我们往某个地址写 1 就达到往对应比特位写 1 的目的,同样往某个地址写 0 就达到往对应的比特位写 0 的目的。
支持了位带操作后,可以使用普通的加载、存储指令来对单一的比特进行读写。在CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自
己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。
02. 位带操作
SRAM 区中的位带地址映射
对于片上外设,映射关系如下表所示
03. 位带C语言实现
//位带操作,实现51类似的GPIO控制功能
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414
#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814
#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414
#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014 #define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010
#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410
#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810
#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410
#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10
#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010 //IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入
04. 应用示例一
LED循环亮1秒 灭1秒
led.h文件
#ifndef __LED_H__
#define __LED_H__#include "sys.h"//LED初始化
void LED_Init(void);//位带操作
#define LED1 PFout(9)
#define LED2 PFout(10)#endif /*__LED_H__*/
led.c文件
#include "led.h"//LED初始化
void LED_Init(void)
{GPIO_InitTypeDef gpio_InitTypeDef;gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_OUT;gpio_InitTypeDef.GPIO_Speed = GPIO_Speed_100MHz;gpio_InitTypeDef.GPIO_OType = GPIO_OType_PP;gpio_InitTypeDef.GPIO_PuPd = GPIO_PuPd_UP;//使能时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//GPIO初始化GPIO_Init(GPIOF, &gpio_InitTypeDef);//设置高电平 LED灭GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
}
main.c文件
#include "stm32f4xx.h"#include "delay.h"
#include "led.h"int main(void)
{ delay_init(168);LED_Init();//3. LED闪烁while(1){//灭LED1 = 1;LED2 = 1;delay_ms(1000);//亮LED1 = 0;LED2 = 0;delay_ms(1000);}
}
05. 应用示例二
流水灯
main.c文件
#include "stm32f4xx.h"#include "delay.h"
#include "led.h"int main(void)
{ delay_init(168);LED_Init();//3. LED闪烁while(1){//灭LED1 = 0;LED2 = 1;delay_ms(1000);//亮LED1 = 1;LED2 = 0;delay_ms(1000);}
}
06. 附录
6.1 【STM32】STM32系列教程汇总
网址:【STM32】STM32系列教程汇总
07. 声明
该教程参考了正点原子的《STM32 F4 开发指南》
【STM32】位带原理分析和应用相关推荐
- STM32位带区和位带别名区的浅谈
1.首先谈下为什么要使用位带? 在学习51单片机时就已经使用过位操作,比如使用sbit对单片机IO口的定义,但是STM32中并没有这类关键字,而是通过访问位带别名区来实现,即通过将每个比特位膨胀成一个 ...
- STM32:位带操作分析
STM32的位带操作分析 8051单片机可以直接对某一位IO进行读写操作,而Cortex-M3的位带操作是8051位寻址区的加强版.使用位带操作后,可以使用普通的加载/存储指令对单一的比特进行读写操作 ...
- STM32位带操作实现过程解析
编辑这篇文档时候,听说相关的解析过程在<Cortex-M3权威指南>里有详细讲解. 前几日被一个跑马灯语句勾引 LED1=!LED1; 于是深入探究一下这句话的实现过程. #include ...
- STM32 位带应用
Cortex-M3 支持了位操作后,可以使用普通的加载/存储指令来对单一的比特进行读写. 在 CM3 支持的位带中,有两个区中实现了位带. 其中一个是 SRAM区的最低 1MB 范围, 0x2000 ...
- 【STM32】标准库与HAL库对照学习教程六--位带操作
[STM32]标准库与HAL库对照学习教程六--位带操作 一.前言 二.准备工作 三.位带介绍 1.位带操作 2.STM32位带及位带别名区域 四.位带区与位带别名区地址转换 五.GPIO的位带操作 ...
- 我对STM32所用位带操作宏的超详细剖析、优势分析及应用推广探索研究(持续更新,欢迎讨论交流)
在原子例程的sys.h中,使用宏定义建立了位带操作的基础, 使得操作IO端口可以像51一样实现位操作. 其实深入了解了位带操作的原理,几乎就可以实现对STM32所有外设寄存器的访问, 极端情况下,什么 ...
- STM32(五)------GPIO位带操作
GPIO位带操作 介绍 位带简介 外设位带区 SRAM位带区 位带区和位带别名区地址转换 GPIO 位带操作 代码解析 GPIO 寄存器映射 GPIO位操作 主函数 介绍 位带简介 位操作就是可以单独 ...
- Android LayoutInflater原理分析,带你一步步深入了解View
Android视图绘制流程完全解析,带你一步步深入了解View(一) 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12921889 ...
- STM32笔记 GPIO介绍及IO口操作 STM32F0 利用C语言位域实现仿位带操作
文章目录 GPIO简介 工作方式 相关寄存器介绍 IO 操作步骤 IO口三种操作细解 附录:C语言相关 偏移地址与绝对地址 GPIO简介 GPIO:每个连接到I/O总线上的设备都有自己的I/O地址集, ...
最新文章
- 《SQL入门经典》学习笔记
- parse函数 python_python的parse_args()函数
- 离线安装Ubuntu虚拟机和GNURadio
- 一个XOR问题的实例---神经网络的权重到底是如何变化的
- IE与Mozila FireFox 中的 JS
- 揭开隐藏数据的面纱,优化应用程序性能(转)
- UITableView 自带编辑删除 自己定义button
- 计算机开机主机无法启动,手把手教你电脑无法启动怎么办
- java输入输出26:IO流(对象操作流ObjecOutputStream)
- 权变理论计算机管理理论,现代管理理论的主要学派
- 固态硬盘:NVME 2.0 新技术 ZNS 自动分区:减少延迟,提高寿命
- 学习笔记二:接口与继承(内部类)
- Dell H300/6i/6iR/H700/H800阵列卡配置(转)
- 爬虫练习(Day4)
- NFC framework introduce(二)
- 蹲175年的号子?维基解密阿桑奇动了谁的奶酪?
- Webdw1.0版本已经整合完毕发布到github上了
- 使用RPM打包QT程序
- 有孚网络吕鑫:融媒体数据管理的实践与探讨
- c++如何输入带空格的字符串
热门文章
- Robot Framework--08 List Variables-List变量及其用法
- [转]详细介绍java中的数据结构
- 【黑马程序员】————预处理指令1-宏定义
- php中empty(), is_null(), isset()函数区别
- MySQL根被拒绝_[转载]phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接。...
- C语言结构-演员请就位
- python如何离线安装第三方模块_扣丁学堂python开发之第三方模块pip离线安装
- html 编辑xml,编辑XML\HTML时取消浏览“amp”
- 【AtCoder】AGC034
- 人脸检测中,如何构建输入图像金字塔