stm32f103替换_能力复用

stm32f103替换_能力复用文章来源:刚接触STM32F103,在尝试编写“按键中断”和“PWM呼吸灯”程序的时候,发现例程都用到了管脚复用AFIO://打开管脚复用AFIORCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);写到“232USART串口通信”程序时,当我非常自信的写下上面这句代码后,发现例程里面却没有这句话,很让人摸不着头脑……查了很多资料,加上

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

文章来源:

刚接触STM32F103,在尝试编写“按键中断”和“PWM呼吸灯”程序的时候,发现例程都用到了管脚复用AFIO:

//打开管脚复用AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

写到“232USART串口通信”程序时,当我非常自信的写下上面这句代码后,发现例程里面却没有这句话,很让人摸不着头脑……查了很多资料,加上自己的理解,发现AFIO的使用还是有点内容值得总结一下的。

AFIO介绍:

MCU有对外管脚,包括CPU的管脚和内置外设(PWM,TIM,ADC……)的管脚;
他们都需要对外接口IO,但是管脚总数是有限的,有的管脚既作为普通IO,也作为外设IO,有时候甚至好几个内置外设共用一个IO,这就是管脚复用现象。

比如随便一个管脚的原理图上:
PA2/USART2_TX/ADC123_IN2/TIM5_CH3/TIM2_CH3
表明这个管脚除了作为普通PA2之外,还作为复用IO,有USART2,ADC,TIM5,TIM2等……

总结:
1. 普通管脚就是GPIO,复用管脚(非普通管脚)就是AFIO;
2. 只要用到内置外设的管脚,都需要打开复用IO(AFIO),比如对外输出PWM波形,使用AD转换等。

画了个简图:
这里写图片描述

例程分析:

标题“什么时候需要AFIO”看来已经解决了,但仍让我困惑的是,同样是用到AFIO,为什么有的例程不需要(比如USART例程)打开AFIO,而有的例程(比如PWM呼吸灯和按键中断例程)却需要这句话打开AFIO:

//打开管脚复用AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

我总结的规律是:

1.假如是用到挂载在APB2下的内置外设,比如下图中的ADC1/2,TIM1,SPI1,USART1,也算是管脚复用,但不需要打开AFIO语句,而是直接打开相应内置外设就好了;

这里写图片描述

2.假如是挂载在APB1下的内置外设,比如下图中,也用到了AFIO,也不用打开AFIO语句,而是直接打开相应内置外设就行了;

这里写图片描述

说来说去,什么时候用到打开AFIO呢?

  • 首先要有管脚复用功能AFIO;
  • 其次被复用的管脚一定是挂载在APB2上的,因为AFIO就是在APB2上;
  • 最后就是内置外设一定是上述APB2表中没有的,因为APB2有的话,直接打开就好了,也用不到打开AFIO;

根据以上条件,打开AFIO的只有一种情况,那就是:

挂载在APB1下的内置外设,经过重映射功能,把管脚映射到APB2上!

其实,一旦使用重映射功能,只能映射到APB2上,因为APB2表中第二个框子里面包括了GPIOA~E,几乎所有的管脚了。

复用时,是否打开AFIO & 管脚设置?

1.TIM3输出PWM,使用了重映射,所以有打开AFIO这句话;

被映射管脚设置为复用推挽输出:

GPIOC_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出

2.USART1串口传输,由于USART1挂载在APB2下,使用了AFIO,但是没有打开AFIO这句话,而是直接打开USART1;

被打开的USART管脚设置为复用推挽输出:
(推挽输出是为了点亮LED)

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出

3.按键中断,是一种输入模式,关于IO中断,数据手册上有:

这里写图片描述

关于按键中断:

首先确认IO口接收外部中断是管脚复用;

其次输入模式没有复用输入,只有普通输入,所以要按照手册配置成浮空等;

最后,因为按键中断并不是APB2表中带有的复用,没法直接打开,所以要声明打开AFIO复用!

重映射内置外设步骤:

  1. 使能映射到的I/O端口时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
  2. 使能被新映射的外设时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  3. 使能AFIO功能的时钟(勿忘!)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  4. 打开重映射
    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

参考内容:

最初我看到这句话我是想当然的不相信的:

这里写图片描述

仔细理清AFIO和重映射的关系之后,发现确实时钟这样的,而且这里还说明了外部中断的管脚复用。

上面的重映射步骤,也是参考这个文章,感谢作者对新手的帮助!
什么时候需要用到RCC_APB2Periph_AFIO–复用IO时钟的使用—gtkknd

像这个说的也很好,新手确实很容易忘记打开AFIO以及相应的管脚,但是什么情况下打开没有说明清楚。其实就是在重映射的时候需要打开AFIO。

这里写图片描述

后来又发现了一位自称菜鸟的大神,在他的这篇文章(学习STM32(2)-IO-AFIO(复用功能IO和调试配置) )中关于这个问题讲的很清楚:

这里写图片描述

结语:

有时候发现,别人讲的有点乱自己怎么也看不明白,等自己理解透了才发现别人讲的这么有条理、这么准确!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/183595.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 无锁编程技术及实现「建议收藏」

    无锁编程技术及实现「建议收藏」1.基于锁的编程的缺点 多线程编程是多CPU系统在中应用最广泛的一种编程方式,在传统的多线程编程中,多线程之间一般用各种锁的机制来保证正确的对共享资源(share resources)进行访问和操作。在多线程编程中只要需要共享某些数据,就应当将对它的访问串行化。比如像++count(count是整型变量)这样的简单操作也得加锁,因为即便是增量操作这样的操作,,实际上也是分三步进行的:读、改、写(回…

    2022年6月10日
    41
  • 电脑显示与域服务器失去信任,此工作站和主域间的信任关系失败,退出域后也不能重新加入…

    电脑显示与域服务器失去信任,此工作站和主域间的信任关系失败,退出域后也不能重新加入…谢谢前面的回答,但觉得只是提供了分析问题的思路!我用问题的英文翻译“Thetrustrelationshipbetweenthisworkstationandtheprimarydomainfailed”进行搜索发现以下这样一篇博文,按照其方法操作已经成功解决问题。基本原理就是通过命令重建服务器与该失信客户端之间联系的密码。具体操作步骤:(前提是没有退出域,或可以系统还原为没…

    2022年10月19日
    4
  • p6操作教程_pc6视频教学

    p6操作教程_pc6视频教学在开发的过程中,我们经常会遇到由于sql语句书写错误导致的bug,那么如何来解决这种困扰呢?如果方法执行完了可以打印出完整的sql语句,就可以方便我们判断执行的是否正确,所以我们希望有一个可以打印sql语句的插件。p6spy就是一款这样的工具,下面给大家介绍一下p6spy的使用。使用p6spy需要做以下三步:1. 导入jar包:将jar包复制到项目中去,记得要buildpath一下。我用…

    2022年10月5日
    3
  • shell中 的 export命令

    shell中 的 export命令export功能说明:设置或显示环境变量。

    2022年9月6日
    3
  • 数组和集合的区别有哪些?

    数组和集合的区别有哪些?更多免费教学文章请关注这里一 数组数组是 java 语言内置的数据类型 他是一个线性的序列 所有可以快速访问其他的元素 数组和其他语言不同 当你创建了一个数组时 他的容量是不变的 而且在生命周期也是不能改变的 还有 JAVA 数组会做边界检查 如果发现有越界现象 会报 RuntimeExcep 异常错误 当然检查边界会以效率为代价 二 集合 JAVA 还提供其他集合 list map set 他们

    2025年7月8日
    2
  • uniapp父子组件传值

    uniapp父子组件传值在父组件中引入子组件父传子(props)在子类props里定义接收参数在子类标签写上引用然后在父类写上准备传递的参数此时,父组件传到子组件的值,就会覆盖默认背景色子传父($emit)需要首先在子类组件定义事件在子类写上触发事件在父类引用标签上写上在子类$emit里面定义的方法名,以及接收方法然后点击子类触发,就可以传值给父类注意:1.父传子用props;…

    2022年5月17日
    299

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号