STM32的复用时钟的开启和重映射功能

IO口的复用

最近在学习STM32,在BZ上一篇关于的串口通信文章里有这么一段代码:

 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO,ENABLE);

 

当初是参考开发的子写的一直对GPIOD或上“RCC_APB2Periph_AFIO”这句话的意思没搞懂,通过这几天在网上查找资料和看手册,终于高清楚了,不敢独享,希望能对跟我一样的新手有所帮助吧o(∩_∩)o...

 

一、

 

STM32上有很多I/O口,也有很多的内置外设,像I2C,ADC,ISP,USART等 ,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。但是STM32还有一特别之处就是:很多内置外设的I/O复用引脚可以通过重映射功能从不同的I/O管脚引出,即使用了复用功能的引脚是可通过程序改变的。

知道了这些我们就不难理解上面代码的意思了,程序中用到的USART2外设的TXRX分别对应PA2PA3,但是我的学习板上的PA2,PA3引脚接了其他设备,但是为了还要用USART2

“RCC_APB2Periph_GPIOD |RCC_APB2Periph_AFIO”就打开了GPIOD重映射功能USART2设备的TXRX映射到PD5,PD6上,我们在这两个引脚上接上MAX232串口芯片就可以使用USART2串口通信了。

各位看官该问:“USART2是不是可以映射到任意管脚呢?

答案是否定的,它只能映射到固定的管脚,下图是USART2重映射表

 

其他外设的重映射可以参考STM32100X手册。

二、

 

为了节省IO资源单片机会在一个IO上复用很多功能,一般来说,单片机IO用到一个功能后就能再用外的复用功能(对应的外设),这就体现出了STM32 GPIO的强大了,我们用重映射的方法把其中一个外设映射到其他IO脚上,这样就可以充分利用片内资源!

  

也许你以为IOAFIO是很简单的,事实上有几个误区可能很多人都没注意过,当你只用现成的开发板来学习的时候,别人已经帮你做好了资源分配,所有的外设功能学习都是照着别人给你的例程去做的,这才没让你觉得奇怪。

先问自己一个问题:STM32中,USART2TIM2是共用相同IO的,你如何决定这几个IO到底是做USART2还是做TIM2呢?如果你要同时使用USART2TIM2,该怎么办?

 

 

1不是说使用了IO的复用功能就一定要启动RCC_APB2Periph_AFIOClock,参考下图

 

只有使用了AFIO的事件控制寄存器AFIO_EVCRAFIO的重映射功能(AFIO_MAPR)以及外部中断(AFIO_EXTICRx)控制寄存器才需要开启AFIO的时钟STM32参考手册从来没说过使用IO的复用功能就一定要开启AFIO时钟,这是个误区。

例如下面的,最常用的USART1,如果你的板子上,默认用的就是PA9PA10这两个IO作为USART1TXRX,那么也就是没有重映射(No Remap)这种情况下根本不需要开启AFIO时钟,只要开启USART1的外设时钟就行了。这个实验很简单,自己试试就知道了。

 

2面的图你可以看到,原来USART1是可以放在PB6PB7上面的,只不过几乎所有的原理图封装中都不会在PB6PB7的复用功能上标出它可以当USART1用,毕竟这种重映射的情况太多,几乎所有外设都可以重映射,每个都标出来会非常混乱。


STM32中,USART2CTSRTSTXRXTIM2CH1~CH4都在PA0PA3上面,具体要如何选择这两个功能呢?

如果要使用USART2,就要使能USART2的外设时钟,同理,如果要使用TIM2,就开启TIM2的外设时钟,如果你同时开启,我也不知道会怎么样,你可以自己试试,我觉得应该是两个都不能用。如果你一定要在PA0~PA3上使用这两个功能,只能是时分复用。

正确的同时使用USART2TIM2,应该是使用上面提到的AFIO_Remap寄存器,将其中的一个重映射到其他IO上去,当然这样其他IO的本身的复用功能你就不能开启了。



回到前面的问题,如果你不做重映射(Remap),你根本不可能同时在PA0~PA3同时使用这两个外设,现在你的方案有两种:

 

一、保留USART2PA口上,将TIM2完全重映射(Full Remap)到其他IO上,或者,如果你不用RTSCTS的硬件流控制,PA0(CTS)PA1(RTS)上对应的CH1CH2是可以不用重映射的,只需要将Bit98改成10,也就是将CH3CH4部分重映射到PB10PB11上去,而CH1CH2继续保留在PA0PA1上。但这种情况下,PB10PB11上的I2C2USART3就不能用了。

二、保留TIM2PA口,将USART2重映射到PD口上,很明显,当TIM2完全不重映射时,USART2所需的信号线只有时钟信号Clock不受影响,这种情况下也没有部分映射可言了,必须将USART2完全重映射到PD3PD7上,同样的,这种情况下FSMC就不能用了(被USART2占用)

三、

   

STM32上有很多I/O口,也有很多的内置外设想I2C,ADC,ISP,USART等 ,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。但是STM32还有一特别之处就是:很多复用内置的外设的I/O引脚可以通过重映射功能,从不同的I/O管脚引出,即复用功能的引脚是可通过程序改变的.

读到这里相信大家都应该了解了端口重映射的一些概念了.原理上的东西不细说了,大家可以看手册或者网上查,这方面的资料还是很多的.下面说说我的调试经历.

        上面说过,我用的ICSTM32F103VCT6 ,说到这儿跟大家提一个小插曲.当时在老板让我换方案也就是IC,只说用VCCPU,让我把要买的CPU告诉负责买器件的人,由于我是第一次做,所以傻乎乎的写了张纸给了对方.内容是"STM32F103VC  10PCS"对方看了一眼就给我退了回来并加一句"型号不对,没写全".我没明白,便也不好继续问白痴问题,所以跑网上查,原来光这个IC就不止一种.我们选用的是T6也就是LQFP封装的 工作环境为-40C -- 80C.所以说大家以后小心点儿..

言规正传.不知道是什么原因PCB制图时把串口接到USART1上了,当时也没在意,等我把USART测试程序写好烧进去硬件仿真时,串口给的是乱码,我当时就觉得奇怪.把程序检查了好几遍就是查不出问题来,以为是硬件有问题,但突然想到了STM有复用功能,心想会不会是这里有鬼?于是找来datasheet一看 ,真相大白


三个红框交汇处.STM32F103VCT6 这个CPUUSART1接的是PB6/PB7, 但是上电初始化后默认功能并非是USART1.所以想要用串口功能.必须用端口重映射..

    大家知道,STM32的单片机每个功能模块有自己的时钟系统,所以要想要调用STM32单片机的功能模块时 必须先配置对应时钟,然后才能去操作相应的功能模块.端口重映射也一样.如图示:


重映射步骤为:

1.打开重映射时钟和USART重映射后的I/O口引脚时钟, 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);

   //使能对应IO口的时钟,因为是复用功能所以还要使能AFIO时钟

2.I/O口重映射开启.

                    GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

 

3.配制重映射后的引脚: 这里只需配置重映射后的I/OPB6,PB7,原来的不需要去配置PA9PA10.

                     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                          GPIO_Init(GPIOB, &GPIO_InitStructure);

                          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
                          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
                          GPIO_Init(GPIOB, &GPIO_InitStructure);

      只需要这三步,串口就可以正常使用了,简单吧但是我纠结了大半个小时才搞定的,好多事情都是说起来容易做起来难的,希望我以后多多进步.不要眼高手低,嗯 我正朝这个方向前进

补充:

1. AFIO的功能

    为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其他引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上。

    简言之,AFIO实现了复用功能的重新映射

2. 在什么情况下,需要开启AFIO时钟?

   下图, 参考手册中写道对寄存器AFIO_EVCR, AFIO_MAPRAFIO_EXTICRX进行读写操作前,应当首先打开AFIO的时钟


 在数据手册的引脚定义中(pin definitions),复用功能"Alternate functions"栏下分为两栏:默认"Default"和重映射"Remap"。其中,在默认栏中的功能只需要开启相应外设功能的时钟,无需开启AFIO时钟(注意:一个引脚在一个时间段内只能使用一个外设功能)。而在重映射栏中的功能,则需要开启相应外设功能的时钟,并且开启AFIO时钟

    简言之,GPIO口使用了重映射栏中的外设功能,则需要开启AFIO时钟;只使用默认复用功能时,只开启相应外设时钟无需开启AFIO时钟。


  • 28
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
STM32F103的定时器4可以通过重映射功能连接到不同的GPIO引脚,具体操作步骤如下: 1. 打开AFIO时钟,并将定时器4重映射到指定的GPIO引脚。 ``` RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //打开AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //将定时器4重映射到指定的GPIO引脚 ``` 2. 配置GPIO引脚的模式和速率。 ``` GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //指定GPIO引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置GPIO引脚为复用推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO引脚输出速率为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIO引脚 ``` 3. 配置定时器4的工作模式和时钟源。 ``` TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 1000 - 1; //设置定时器4的自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; //设置定时器4的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置定时器4的时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置定时器4为向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化定时器4 ``` 4. 开启定时器4的中断并启动定时器。 ``` TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除定时器4的中断标志位 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //开启定时器4的更新中断 TIM_Cmd(TIM4, ENABLE); //启动定时器4 ``` 需要注意的是,不同的引脚重映射方式可能不同,具体需要查看芯片手册和相关资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值