文章目录定时器选择外部时钟源配置GPIO复习AFIO 什么时候需要配置AFIOmain function和“alternate-default有什么区别full和partial remap是啥意思实验又有问题了。。。摘要本文记录 STM32 定时器使用外部时钟源红外传感器的实践过程。首先介绍如何通过TIM_ETRClockMode2Config配置外部时钟模式 2 及触发极性接着讲解 GPIO 浮空输入的配置要点并深入复习 AFIO 相关知识何时需要配置、main function 与 alternate-default 的区别、full/partial remap 的含义最后记录实验中遇到的计数抖动问题分析原因并给出通过 ETR 输入滤波解决的方案。定时器选择外部时钟源这个实验主要是实践“外部时钟模式2”。要选择外部时钟就需要用这个functionTIM_ETRClockMode2Config。这里面的一个参数就是配置极性。这个极性如何配置取决于我们的功能需求和外接“时钟”的有效电平。这里“时钟”大引号主要是因为它不一定是一个以一定时间间隔产生脉冲的部件。比如我们的实验中它是一个红外传感器。实验的需求就是记录遮挡红外光的次数。这个模块的“极性”是遮挡模块槽DO输出高电平不遮挡DO输出低电平所以如果我们要检测遮挡次数一般正常感知是“不遮挡-遮挡”算一次“遮挡”那么就是电平上升算一次触发。根据RM中包括库代码中的定义所以选择non-inverted高电平/上升沿触发比较符合我们的直觉。配置GPIORM里推荐的GPIO Mode设置是浮空输入本来我也写这个但是课程中老师觉得这个不靠谱用了IPU。他补充了一下什么时候可以用浮空输入如果外部输入信号功率很小内部上拉电阻会影响到这个输入信号可以用浮空输入防止内部电路影响外部输入的电平。那么这个PA0作为了时钟输入我需要动用AFIO给它做重映射么不需要因为TIM2的ETR功能是PA0的默认功能不需要执行重映射。上面的表格有几点可以补充一下一个pin的default有很多这些都不需要用AFIO做remap只需要使能和配置这个GPIO然后相应使能其他外设即可。但是同时这几个default不能同时使用同一时刻pin脚只能时一个角色。。。TIM2_CH1_ETR其实表示的是TIM2_CH1或者TIM2_ETR这两个不能同时使用。只有当pin脚要用作“Remap”那一栏的功能时才需要动用AFIO复习AFIO 什么时候需要配置AFIO还是要关注datasheet中的这个pin definition 表格当这个Pin脚要用alternate-remap这一栏的功能时通过GPIO_PinRemapConfig外部中断EXTI引脚选择通过GPIO_EXTILineConfigmain function和“alternate-default有什么区别这个表格里有这样两列main functionPin脚初始化之后就是这个功能alternate-default刚才也提到了这是引脚的默认AF功能只需要配置GPIO的模式和相应外设即可。那么好像就有点问题了这两栏里面列的功能看起来都是这个Pin脚“上电就有的”功能啊。为什么要分成两列呢查了一下尝试理解从电路连接的角度来说main function是这个pin脚物理直连的功能STM32内部有多路复用器MUX而alternate这里列的功能是经过多路复用器连到的模块。对于那些不需要配置“remap”的功能就列在default这一栏。从代码来看一个Pin脚用main function和用alternate-default好像很像没有什么“set_main_function()或者set_alternate_default()这样的function来进行配置。但是如果这个GPIO用作”输入功能“的Pin脚似乎它用作main 或者alternate-default配置的区别是不大。可以理解为它作为输入的时候整个板子都在监听信号对于到底这个pin是main function还是alternate-default功能没有区别。但是如果它是用于”输出“功能的pin脚那其实是有区别的区别就在于配置GPIO Mode对于GPIO的输出模式可是对AF有特殊照顾的。如果希望把这个pin脚作用作输出某个AF但是还是配置成OUT_OD或者OUT_PP那么这个pin的背后还是它的main function而不是alternate-default它是不会输出我们想要的功能的。full和partial remap是啥意思在使用GPIO_PinRemapConfig会看到库里面提供的宏定义名字里面有类似于“GPIO_PartialRemap_USART3”“GPIO_FullRemap_USART3”也有不带Full/Partial的名字“GPIO_Remap_USART2”。包括在RM中的表格里也有提到这两个词其实partial和full时相对于第一列“no remap也就是这个外设默认的引脚而言的。一个外设通常会用到多个引脚比如很多时候会有RX和TX如果只有一部分引脚用了alternate function的pin脚而剩下一部分和“no remap”的时候一样那就是“partial remap”如果这个外设所有用的引脚都不是默认使用的引脚了那就是full remap。如果这个宏定义没有“full/partial”我看了一下通常好像都是full remap的情况。其实区别可以从表格中看出来比如上面这个USART3partial remap的情况有两个cell是和“no remap共用的如绿框所示。实验又有问题了。。。问题每次挡光片遮上去数值会加2或者加3甚至加5。debug开启Keil的debug模式观察了一下TIM的CNT寄存器值发现我每次遮挡它有时候1有时候直接增加其他值有时候它进入断点我不挪开挡光片它进入一次断点之后自己又会进入第二次。也做了一些查询这个是因为遮挡的瞬间信号不是一次干净的跳变而是会有一系列抖动之前GPIO实验中按键按下去的抖动一样。而TIM的CNT记录的是脉冲每次抖动就是一个脉冲所以CNT会一下次增加很多。当然这个最好是有示波器看一下波形。。不过没有。。。解决方案增加滤波。ETR输入之后有一个滤波模块可以认为是一个低通滤波器。TIM_ETRClockMode2Config 最后一个参数就是配置这个滤波器的滤波参数的其中f C K I N T f_{CK_INT}fCKINT就是内部时钟频率72MHzf D T S f_{DTS}fDTS是另一个独立时钟基准本质是由f C K I N T f_{CK_INT}fCKINT分频得到分频系数是在TIM_TimeBaseInit的输入参数的TIM_ClockDivision 指定。这个部分在“定时器3”的文章中有详细描述。对之前文章的补充之前文章里面说到在通用定时器的主电路图中没有体现 CK_INT和各个filter之间的关系。主图中确实没有但是在解释“外部时钟输入2”的细节框图有体现如下图而这里的采样频率就是基于f D T S f_{DTS}fDTS再分频并且保证连续N个电平是高/低才认为目前处于高/低电平。TIM_ClockDivision设置为了TIM_CKD_DIV1也就是不分频f D T S f_{DTS}fDTS则72MHz。这里尝试过两种0100采样频率36MHz从采到一个新的电平开始连续6个采样点为这个新的电平滤波器才输出这个新电平。滤波窗口时6/36MHz 167ns0010: 采样频率72MHz从采到一个新的电平开始连续4个采样点为这个新的电平滤波器才输出这个新电平。滤波窗口时4/72MHz 56ns前者是后者的3倍滤波更强。注关于“滤波窗口”并不是说信号必须保持这么长时间的高/低电平才能被认为是高/低电平。应该还是从离散采样来理解如果6次采样都是高电平但实际上在167ns内信号有一次低电平但是没有被这6个采样捕捉到那么滤波器还是认为是高电平。但是至于视频中老师没有用滤波就可以达到稳定的数值加1的原因不能有肯定的结论。硬件不同也会导致结果不同。可能他的传感器质量比较好看到有的说可能是因为我的模块没有比较器但是我看了一下传感器板子上是有这个模块的但是它有没有用就不知道了啊反正看起来对于外部传感器输入永远不要假设它是干净的考虑加上滤波才是正解。