STM32中使用宏定义来控制IO口

这篇具有很好参考价值的文章主要介绍了STM32中使用宏定义来控制IO口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、前言

二、前置知识

1.带参宏定义

2.三目运算符

3.需要用到的寄存器

①BSRR寄存器

②BRR寄存器

③IDR寄存器

三、有以上基础或者想直接用的直接看这里

1.使用宏定义来控制IO口

四、代码解释

1.LED(x)

2.LED_RUN

五、结语


一、前言

突然想用宏定义来控制IO口,但是发现网上并没有比较满意的解决方案,所以自己就写了一个,现在分享出来给大家用。其中用到了带参宏定义三目运算符,还有一些寄存器的知识,有基础的可以直接从《前置知识》后面看,没基础的我会在《前置知识》简单介绍一下,具体的可以自己去搜索学习一下,想直接用不想知道那么多的同学直接跳到《有以上基础或者想直接用的直接看这里》。

二、前置知识

1.带参宏定义

带参宏定义的格式一般如下,注意:严格上说并不是真正的参数,只是替换而已。

#define 宏名(参数1,参数2,...) 字符串

示例程序,如:

#define add(a,b) a+b

void add(void)
{
    int mnb;
    mnb = add(1,2);
}

因为这个宏定义会将结果返回,所以这个时候mnb就会等于3。

2.三目运算符

三目运算符为?:

其中表达式为(真/假)?(真的话执行这段):(假的话执行这段)

我习惯在三目运算符上面加括号,这样可以避免运算优先级带来的问题。

不加括号的话就是:

真/假?真的话执行这段:假的话执行这段

示例程序,如:

int AAA(int mnb)
{
    int a = (mnb>5)?(mnb-1):(mnb+1);
    return a;
}

这段代码的意思就是说先将AAA的形参mnb用来判断是否大于5,当大于5的时候返回mnb-1赋值给a,否则返回mnb+1赋值给a,最后函数返回a的值。

3.需要用到的寄存器

①BSRR寄存器

全称为“端口位设置/清除寄存器”

有高16位和低16位,这里我只用到了低16位,所以只介绍低16位。

BSRR中的低16位中某一位或者多位置1了,就会将对应的引脚拉高,而置0就是保持当前引脚状态不变。

如:

GPIOA->BSRR = 1 << 0;        //将PA0拉高
GPIOA->BSRR = GPIO_Pin_0;    //将PA0拉高

上面两个段代码是一样的效果,就看你喜欢用哪个了。

②BRR寄存器

全称为“端口位清除寄存器”

这个只有16位,且跟BSRR是反着来的,也就是说置1会将对应引脚拉低,而置0也是保持当前引脚状态不变。

如:

GPIOA->BRR = 1 << 0;        //将PA0拉低
GPIOA->BRR = GPIO_Pin_0;    //将PA0拉低

上面两个段代码也是一样的效果。

③IDR寄存器

IDR是只读寄存器,全称为“端口输入数据寄存器”,是用来读取引脚状态的寄存器。

如:

int a = GPIOA->IDR & GPIO_Pin_0;

上面的代码就是检测PA0引脚的状态,并且将返回值赋值给a。

注意:它是按位返回,如pin0为高它返回0x01,pin3为高它返回0x08。

三、有以上基础或者想直接用的直接看这里

1.使用宏定义来控制IO口

前置知识都会的话,我们就可以进入正题了。

我这里以我们最熟悉的控制LED来举例,并且写出两种控制模式,其他的你们就可以举一反三了。

GPIO口的初始化之类的代码我这里就不给出了,有需要的可以自己搜一下。直接给出代码:

//硬件上以GPIOA中的Pin0为LED,并以高电平为亮,以低电平为灭。
//控制IO高低电平
#define LED(x) ((x==1) ? (GPIOA->BSRR=GPIO_Pin_0) : (GPIOA->BRR=GPIO_Pin_0))

//控制IO口翻转电平
#define LED_RUN ((GPIOA->IDR&GPIO_Pin_0) ? (GPIOA->BRR=GPIO_Pin_0) : (GPIOA->BSRR=GPIO_Pin_0))

int main(void)
{
    LED(1);        //拉高LED
    LED(0);        //拉低LED
    while(1)
    {
        LED_RUN;   //翻转LED的IO口,使LED闪烁
    }
}

上面代码可以直接拿去用,只需要改下IO端口、Pin脚和宏名就行了,比如我现在想用PB13口控制LED灯:

#define LED(x) ((x==1) ? (GPIOB->BSRR=GPIO_Pin_13) : (GPIOB->BRR=GPIO_Pin_13))

就可以了,控制IO口翻转也同理

#define LED_RUN ((GPIOB->IDR&GPIO_Pin_13) ? (GPIOB->BRR=GPIO_Pin_13) : (GPIOB->BSRR=GPIO_Pin_13))

四、代码解释

1.LED(x)

#define LED(x) ((x==1) ? (GPIOA->BSRR=GPIO_Pin_0) : (GPIOA->BRR=GPIO_Pin_0))

先解释LED(x)的宏定义,这个宏定义是用来直接控制IO高低电平的。

使用了带参宏定义、寄存器和三目运算符的知识。

调用这个宏定义,就会调用((x==1) ? (GPIOA->BSRR=GPIO_Pin_0) : (GPIOA->BRR=GPIO_Pin_0))这一整段代码,在这整段代码中,三目运算符会首先判断x是否等于1,等于1的话就为真,执行GPIOA->BSRR=GPIO_Pin_0这段代码,这段代码的意思就是将PA0电平拉高;否则为假,执行GPIOA->BRR=GPIO_Pin_0这段代码,这段代码的意思就是将PA0电平拉低。

以此达到了拉高拉低的解决方案。

2.LED_RUN

#define LED_RUN ((GPIOA->IDR&GPIO_Pin_0) ? (GPIOA->BRR=GPIO_Pin_0) : (GPIOA->BSRR=GPIO_Pin_0))

LED_RUN(x)的宏定义是用来翻转电平的,这里我用作LED闪烁,也可以有其他用处。

进来先判断PA0脚是高电平还是低电平,并且&对应的引脚,这样就可以在高电平的时候按位返回,低电平的时候返回0。当大于0时判断为真,执行(GPIOA->BRR=GPIO_Pin_0)来将电平拉低;当为0时判断为假,执行(GPIOA->BSRR=GPIO_Pin_0)来将电平拉高。

五、结语

个人感觉比库函数简单方便,还可以用来做一些特殊操作,就比如GPIOx不是同一端口,库函数需要不停的切换GPIOx的x字母,很不方便,特别是在写数组类或者算法类的IO口控制的时候,这样写也能简单明了的知道这个端口是干嘛的,并且比直接宏定义要简洁,直接宏定义要两个才能控制拉高拉低,而这个只需要一个宏定义。

最后写出来的代码看着很简单,但是实际上写了这么一大篇,本来两句话就可以写完的,还是太照顾了大家了,希望大家都有所收获,有帮助的话就点个赞收藏一下,最好可以关注一下,不定时更新实用的东西。文章来源地址https://www.toymoban.com/news/detail-821731.html

到了这里,关于STM32中使用宏定义来控制IO口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零开始教你使用Clion优雅开发STM32(三)Clion嵌入式开发必备插件

    (一)软件安装与环境配置 (二)移植工程文件到其他芯片 (三)Clion嵌入式开发必备插件 文章目录 前言 1)Chinese(simplified) 2)CodeGlance Pro 3)File Watchers  4)Key Promoter X 5)CodeGlance Pro 6)Monokai Pro Theme 7)Rainbow Brackets Lite 8)Serial Port  Monitor 总结 前段时间,稚晖君用 Cl

    2024年02月06日
    浏览(57)
  • 【单片机毕业设计】基于STM32单片机蓝牙app遥控语音控制老年轮椅车GSM位置定位报警系统--物联网 单片机 嵌入式

            这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉小洪学长自己做的项目系统达不到老师的要求。为了大家能够顺利以及最少的精力通过毕设,小洪学长分享优质毕业

    2024年01月22日
    浏览(100)
  • 嵌入式开发:使用STM32CubeMX 和 Keil uVision5实现两位数码管循环显示实验

    一、STM32CubeMx实现数码管 1、双击打开STM32CubeMX。 2、点击File选项,在File列表下选择New Project选项新建工程。 3、在图中所示位置的方框中输入我们使用的芯片型号来搜索芯片 4、与我们的搜索相关的芯片型号会在这里呈现,我们只需要选择我们需要的即可,这里我们双击第一个

    2024年02月08日
    浏览(49)
  • stm32嵌入式实验考核

    STM32 实验考核题目 1. 利用 STM32 小板实现:控制外接 LED 灯每隔 3 秒钟亮暗变换,同 时在 PC 机上显示 MCU 的计时时间,MCU 的初始时间由 PC 机 方设置。 2. 利用 STM32 小板实现:利用导线外接 GPIO 口模拟 2 个按键输入, 根据输入组合的四种情况,分别控制三色灯四种流水灯效果

    2024年02月03日
    浏览(48)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(81)
  • 蓝桥杯嵌入式基础模块——LCD显示器的基本使用(新板)STM32G431(HAL库开发)

            在蓝桥杯嵌入式官方给我们提供好了,LCD显示的底层源码,我们只需要,记住里面的API函数,会用这些函数就行。         在官方给的资料中找到这个文件名字DK117_G4 Data Packet-开发板驱动文件里面就是所有的底层文件有两种类型,一种是基于HAL库的一种是标准库

    2024年02月09日
    浏览(59)
  • STM32的时钟系统(嵌入式学习)

    时钟是指用于计量和同步时间的装置或系统。时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,例如:串口数据的发送、AD转换、定时器计数等。因此时钟对于计算机系统是至关重要的,通常时钟系

    2024年02月16日
    浏览(47)
  • 嵌入式 STM32 通讯协议--MODBUS

    目录 一、自定义通信协议 1、协议介绍 2、网络协议 3、自定义的通信协议  二、MODBUS通信协议 1、概述 2、MODBUS帧结构  协议描述 3、MODBUS数据模型   4、MODBUS事务处理的定义 5、MODBUS功能码  6、功能码定义   7、MODBUS数据链路层 8、MODBUS地址规则  9、MODBUS帧描述 10、MODBUS两种

    2024年02月11日
    浏览(62)
  • 嵌入式——新建STM32工程(标准库)

    目录 一、初识标准库 1.CMSIS标准及库层级关系 2.库文件介绍 (1)Libraries文件夹 ①CMSIS文件夹 ②STM32F10x_Std_Periph_Driver文件夹 ③ 在用库建立一个完整的工程时,还需要添加stm32f10x_it.c、 stm32f10x_conf.h 和 system_stm32f10x.c文件 (2)Project文件夹 (3)Utilities文件夹 3.库各文件之间的关

    2024年01月23日
    浏览(53)
  • STM32串口通信详解(嵌入式学习)

    时钟信号在电子领域中是指用于同步和定时电路操作的周期性信号。它在数字系统和通信系统中起着至关重要的作用,用于协调各个组件之间的数据传输和操作。 时钟信号有以下几个重要的方面: 频率:时钟信号的频率是指单位时间内信号周期的数量。它通常以赫兹(Hz)为

    2024年02月09日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包