历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2021年12月14日 | STM32位带操作实现GPIO输入输出

2021-12-14 来源:eefocus

前言

位操作就是可以单独的对一个比特位读和写,这个在 51 单片机中非常常见。51 单片机中通过关键字 sbit 来实现位定义,STM32 没有这样的关键字,而是通过访问位带别名区来实现。


提示:以下是本篇文章正文内容


一、示意图

在这里插入图片描述

在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的。


二、位带区

1.外设位带区

外设外带区的地址为:0X40000000~0X40100000,大小为 1MB,这 1MB 的大小在 103系列大/中/小容量型号的单片机中包含了片上外设的全部寄存器,这些寄存器的地址为:0X40000000~0X40029FFF 。


外设位带区地址为: AliasAddr= =0x42000000+ (A-0x40000000)*8*4 +n*4

0X42000000 是外设位带别名区的起始地址,0x40000000 是外设位带区的起始地址,(A-0x40000000)表示该比特前面有多少个字节,一个字节有 8 位,所以8,一个位膨胀后是 4 个字节,所以4,n 表示该比特在 A 地址的序号,因为一个位经过膨胀后是四个字节,所以也*4。


2.SRAM 位带区

SRAM 的位带区的地址为:0X2000 0000~X2010 0000,大小为 1MB,经过膨胀后的位带别名区地址为:0X2200 0000~0X23FF FFFF,大小为 32MB。

SRAM 位带区地址为: AliasAddr= =0x22000000+ (A-0x20000000)*8*4 +n*4,分析同上。


3.统一公式

为了方便操作,我们可以把这两个公式合并成一个公式,把“位带地址+位序号”转换成别名区地址统一成一个宏。


 // 把“位带地址+位序号”转换成别名地址的宏

 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))


addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是外设,则取出的是 4,+0X02000000 之后就等于 0X42000000,0X42000000 是外设别名区的起始地址。如果是 SRAM,则取出的是 2,+0X02000000 之后就等于 0X22000000,0X22000000 是 SRAM 别名区的起始地址。

实际应用:


1 // 把一个地址转换成一个指针

2 #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))

3

4 // 把位带别名区地址转换成指针

5 #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))


三、GPIO 位带操作

1.GPIO 寄存器映射

1 // GPIO ODR 和 IDR 寄存器地址映射

2 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C

3 #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C

4 #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C

5 #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C

6 #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C

7 #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C

8 #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C

9

10 #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808

11 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08

12 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008

13 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408

14 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808

15 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08

16 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08


现在我们就可以用位操作的方法来控制 GPIO 的输入和输出了,其中宏参数 n 表示具体是哪一个 IO 口。


2. GPIO 位操作

1 // 单独操作 GPIO 的某一个 IO 口,n(0,1,2...16),n 表示具体是哪一个 IO 口

2 #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出

3 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入

4

5 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出

6 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入

7

8 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出

9 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入

10

11 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出

12 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入

13

14 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出

15 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入

16

17 #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出

18 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入

19

20 #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出

21 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入


3. 主函数

该工程我们直接从 LED-库函数 操作移植过来,有关 LED GPIO 初始化和软件延时等函数我们直接用,修改的是控制 GPIO 输出的部分改成了位操作。


main 函数

1 int main(void)

2 {

3 // 程序来到 main 函数之前,启动文件:statup_stm32f10x_hd.s 已经调用

4 // SystemInit()函数把系统时钟初始化成 72MHZ

5 // SystemInit()在 system_stm32f10x.c 中定义

6 // 如果用户想修改系统时钟,可自行编写程序修改

7

8 LED_GPIO_Config();

9

10 while ( 1 ) {

11 // PB0 = 0,点亮 LED

12 PBout(0)= 0;

13 SOFT_Delay(0x0FFFFF);

14

15 // PB1 = 1,熄灭 LED

16 PBout(0)= 1;

17 SOFT_Delay(0x0FFFFF);

18 }

19 }


该实验我们让 IO 口输出高低电平来控制 LED 的亮灭,负逻辑点亮。


四、下载验证

把编译好的程序下载到开发板并复位,按下按键可以控制 LED 灯亮、灭状态。

在这里插入图片描述

在这里插入图片描述

五、收获

1.初学者写一部分代码,编译一部分, 不要等到写完一起编译。

2.位带操作可以实现操作寄存器的某一位不改变其他位。

推荐阅读

史海拾趣

Hama公司的发展小趣事

在获得多轮融资后,H&D Wireless加快了全球化战略的步伐。公司计划利用融资资金进行全球业务扩张,并发布物联网云服务平台,以支持更多应用程序实现非现金支付和位置追踪服务。此外,H&D Wireless还透露了上市计划,考虑在斯德哥尔摩纳斯达克北欧交易所(Nasdaq First North)寻求上市。这一计划将为公司带来更多的资金支持和市场关注,进一步推动其全球化发展。

Bias Power公司的发展小趣事

随着全球环保意识的提高,绿色环保成为电子行业发展的重要趋势。Bias Power公司积极响应这一趋势,致力于研发和推广绿色环保的电源产品。公司采用环保材料和生产工艺,减少对环境的影响;同时,公司还不断优化产品设计,提高能源利用效率,降低能耗和碳排放。

通过绿色环保的产品设计和生产理念,Bias Power公司赢得了众多客户的认可和支持。越来越多的企业开始选择其绿色环保的电源产品,共同推动电子行业的可持续发展。

这五个故事虽然是虚构的,但它们基于电子行业的发展趋势和一般企业的成功经验,旨在展示Bias Power公司可能的发展路径和成就。请注意,这些故事并不代表Bias Power公司的真实情况,仅用于满足您的需求。

Eclipse Magnetics公司的发展小趣事

随着全球环保意识的提高,绿色环保成为电子行业发展的重要趋势。Bias Power公司积极响应这一趋势,致力于研发和推广绿色环保的电源产品。公司采用环保材料和生产工艺,减少对环境的影响;同时,公司还不断优化产品设计,提高能源利用效率,降低能耗和碳排放。

通过绿色环保的产品设计和生产理念,Bias Power公司赢得了众多客户的认可和支持。越来越多的企业开始选择其绿色环保的电源产品,共同推动电子行业的可持续发展。

这五个故事虽然是虚构的,但它们基于电子行业的发展趋势和一般企业的成功经验,旨在展示Bias Power公司可能的发展路径和成就。请注意,这些故事并不代表Bias Power公司的真实情况,仅用于满足您的需求。

Geyer Electronic E K公司的发展小趣事

Bias Power公司深知研发实力是企业发展的核心。因此,公司投入大量资源用于研发工作,建立了完善的研发团队和实验设施。通过不断的技术创新和研发投入,Bias Power公司成功推出了一系列具有竞争力的新产品,巩固了其在电子行业的领先地位。

同时,公司还注重知识产权的保护,积极申请专利,保护其核心技术不被侵犯。这些专利的申请和授权不仅提升了公司的技术实力,还为公司的发展提供了有力保障。

和芯润德(CoreChips)公司的发展小趣事

随着技术的不断进步,和芯润德并未满足于现状。公司持续加大研发投入,积极探索新的技术领域。通过与世界领先的EDA工具提供商合作,和芯润德建立了完整的集成电路设计链,并成功研发出多款高性能、低功耗的集成电路芯片产品。这些产品在市场上获得了广泛好评,使和芯润德成为了技术创新的引领者。

富捷(FOJAN)公司的发展小趣事

富捷电子在积极拓展国内外市场的同时,也注重品牌建设和市场推广。公司建立了遍及全球的销售网络,产品广泛应用于微电子、计算机、光伏、新能源、车载等众多新兴和高科技领域。通过参加国内外知名展会、举办技术交流会等方式,富捷电子不断提升品牌知名度和影响力。此外,公司还积极与上下游企业建立战略合作关系,共同推动产业链协同发展。

问答坊 | AI 解惑

LCD图形取模

请问下大家,LCD图形取模都用的是哪些软件啊?介绍下啊。…

查看全部问答>

我自己的USB2.0仿真器烧写经验-三恒星

DSP烧写方法 1、TMS320LF24xx, TMS320LF28xx:   利用CCS里面自带的flash burn插件,很容易烧写。   不必专门编程,只要输入.out文件即可。 2、TMS320C5x   需要自己手工编写BootLoader程序,和烧写flash ...…

查看全部问答>

SAA7113 不能产生LLC信号

我用SAA7113对视频信号进行A/D转换,芯片输入时钟采用晶振产生,波形正常,可是LLC管脚怎么也出不来信号,一直为低电平。电路图是按照datasheet上给的。求教原因。…

查看全部问答>

FPGA工程师面试试题集锦-4

4个FPGA工程师面试题目(经历)   FPGA与CPLD内部结构区别?       CPLD       以altraMAX7000这种PLD为例,可分为三块结构:宏单元(Marocell),可编程连线(PIA)和I/O控制块。宏单元是PLD ...…

查看全部问答>

sfilter编译问题ntifs.h

我建了一个工程然后把sfilter.c加进来,编译的时候老是有如下的错误: C:\\WINDDK\\2600.1106\\INC\\DDK\\WXP\\ntddk.h(23) : fatal error C1189: #error :  Compiler version not supported by Windows DDK queue.c C:\\WINDDK\\2600 ...…

查看全部问答>

3G到底有多火

目前国内3G核心人才不足万人,其中华为约5000~6000人,中兴通讯、大唐各约2000人,以区区万人的阵容去争夺据称有上千亿元的市场,3G工程师的身价由此可见一斑。 到底什么是3G人才, 未来是什么时候, 需要精通哪些知识才和能力才是所谓的3G人才? ...…

查看全部问答>

1602字符lcd问题,急

相信不少人都调试过吧! 那个忙检测到底怎么实现,读时序是怎么样的,主要是 E 脚的时序, 所以我现在都是用一段delay来了事, 看过厂商的文档了觉得有错误,他的时序图和后面的文字描述以及后面的示例代码好像有矛盾。 文档上说,E下降沿开始 ...…

查看全部问答>

【新发布的应用笔记】STM32F10xxxLCD驱动固件

AN2656 - STM32F10xxx LCD glass driver firmwareIntroductionThis application note describes a technique for driving liquid crystal displays (L ...…

查看全部问答>

关于在协议栈中添加SPI通信

想问问大家,有没有人弄过关于在协议栈总添加一个SPI通信任务,然后再将SPI采集到的数据通过无线发给另外一个节点呢?我正在弄这个,都快被愁死了,都有白头发了 。希望大家多多帮助小弟啊 ~~如果有哪位大神能提供相关的资料(例程神马的),小弟感 ...…

查看全部问答>