定时器笔记

TIM Timer )定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16 位计数器、预分频器、自动重装寄存器的时基单元,在 72MHz 计数时钟下可以实现最大 59.65s 的定时
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

 

 高级定时器的额外功能主要是为了三相无刷电机的驱动设计的

基本定时器只能选择内部时钟

RCC_TIMxCLK的频率值一般都是系统的主频72MHz

预分频器对计数时钟(72MHz)进行预分频,写0,不分频(1分频);写1,2分频;写2,3分频

实际分频系数 = 预分频器的值 + 1

 预分频器是16位的,最大值可以写65535,也就是65536分频

UI↑----更新中断(update interuption)

U↓---更新事件,不触发中断,但可以触发内部其他电路的工作

主从触发模式:它能让内部的硬件在不受程序的控制下实现自动运行(减轻CPU的负担)

 主模式触发DAC功能:把定时器的更新事件映射到出发输出TRGO(Trigger Out)的位置,然后TRGO直接接到DAC的触发转换引脚上,这样定时器的更新就不需要再通过中断来触发DAC转换了,仅需要把更新事件通过主模式映射到TRGO,然后TRGO就会直接触发DAC了,整个过程不需要软件的参与,实现了硬件的自动化,这就是主模式的作用

 通用和高级定时器有多种计数模式,基本定时器只有向上计数

TIMx_ETR----外部时钟引脚

输入滤波---可以对外部时钟进行一定的整形,过滤毛刺,对输入波形进行滤波

滤波后的信号兵分两路,上面一路ETRF进入触发控制器,紧跟着就可以选择作为时机单元的时钟了

TRGI(Trigger In)也可以提供时钟,主要是用作触发输入来使用的,这个触发输入可以触发定时器的从模式

当这个TRGI当作外部时钟来使用的时候,这一路叫做“外部时钟模式1”

ITR信号是来自其他定时器的,这个ITR0到ITR3分别来自其他4个定时器的TRGO输出(实现级联)

TIIF_ED连接的是输入捕获单元的CH1引脚来获得时钟,ED(Edge)是边沿的意思,上升沿和下降沿均有效

TI1FP1是CH1引脚的时钟,TI2FP2是CH2引脚的时钟

外部时钟模式1的输入可以是ETR引脚、其他定时器、CH1引脚的边沿、CH1引脚和CH2引脚

编码器接口可以读取正交编码器的输出波形

右下角四个CH可以用于输出PWM波形,驱动电机

捕获/比较寄存器,是输入捕获和输出比较电路公用的,输入捕获和输出比较不能同时使用

不同:

第一个是申请中断的地方,增加了一个重复次数计数器,这个计数器可以实现每隔几个计数周期才发生一次更新事件和更新中断

第二个是对输出比较模块的升级,DTG(Dead Time Generate) 是死区生成电路,右边的输出引脚由原来的一个变为了两个互补的输出,可以输出一对互补的PWM波,这些电路是为了驱动三相无刷电机的,为了防止互补输出的PWM驱动桥臂时在开关切断的瞬间,由于器件的不理想,造成短暂的直通现象,所以加上了死区生成电路,在开关切换的瞬间,产生一定时长的死区,让桥臂的上下管全部都关断,防止直通现象

最后一部分就是刹车输入的功能,这个是为了给电机驱动提供安全保障的,如果外部引脚BKIN(Break IN)产生了刹车信号,或者内部时钟失效,产生了故障,那么控制电路就会自动切断电机的输出,防止意外的发生

 缓冲寄存器和影子寄存器,影子寄存器是真正起作用的寄存器,防止一个计数周期内,前半部分和后半部分的频率不一样。在一次计数周期结束后,更新事件产生,预分频寄存器(缓冲寄存器)的值才会被传递到影子寄存器里面去,才会生效。

计数器计数频率: CK_CNT = CK_PSC / (PSC + 1)
计数器溢出频率: CK_CNT_OV = CK_CNT / (ARR + 1)

         = CK_PSC / (PSC + 1) / (ARR + 1)

带黑色阴影的寄存器,都有缓冲寄存器和影子寄存器,包括预分频器,自动重装寄存器和捕获比较寄存器

无预装---没有设置/启动缓冲寄存器  

 主函数之前运行的SystemInit函数就是用来配置时钟树的

内部8MHz高速RC振荡器

外部4-16MHz高速石英晶体振荡器,也就是晶振,一般都是接8MHz

外部32.768KHz低速晶振,这个一般是给RTC提供时钟的

内部40KHz低速RC振荡器,这个可以给看门狗提供时钟

上面两个高速时钟是用来提供系统时钟的(AHB,APB1,APB2)

外部的石英振荡器比内部的RC振荡器更加稳定

所以一般都用外部晶振

CSS(Clock Security System)是时钟安全系统,负责切换时钟,可以监测外部时钟的运行状态,一旦外部时钟失效,他就会自动把外部时钟切换回内部时钟,保证系统时钟的运行,防止程序卡死造成事故

所有定时器内部基准时钟都是72MHz

第一步,RCC开启时钟

第二步,选择时基单元的时钟源

第三步,配置时基单元

第四步,配置输出中断控制,允许更新中断输出到NVIC

第五步,配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级

第六步,运行控制,使能计数器

最后写中断函数

void TIM_DeInit(TIM_TypeDef* TIMx);//恢复出厂设置

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//根据结构体配置时基单元

void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//可以把结构体变量赋一个默认值

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//使能计数器(运行控制部分)

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//用来使能中断输出信号(中断输出控制)

void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//选择内部时钟

void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//选择ITRx其他定时器的时钟

void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);//选择TIx捕获通道的时钟

void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
                             uint16_t ExtTRGFilter);//选择ETR通过外部时钟模式1输入的时钟

void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//选择ETR通过外部时钟模式2输入的时钟

void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
                   uint16_t ExtTRGFilter);//单独用来配置ETR引脚的预分频器、极性、滤波器等参数


void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//用来单独修改预分频器的值

void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);//用来改变计数器的计数模式

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//配置自动重装器功能配置(有预装还是无预装)

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//给计数器写入一个值

void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);//给自动重装器写入一个值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//获取当前计数器的值

uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//获取当前的预分频器的值

//获取标志位和清除标志位
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

输入滤波器的工作模式:对输入信号在一个固定的时钟频率下进行采样,如果连续n个采样点都为相同的电平,那就代表输入信号稳定了,就把这个输入信号输出出去,如果这N个采样值都不全都相同,那就说明信号有抖动,这时就保持上一次的输出,或者直接输出低电平。

采样频率可以是由内部时钟直接而来,也可以是由内部时钟加一个时钟分频而来,分频多少就是由结构体的ClockDivision决定

TimBaseInit函数里面最后说了生成一个更新事件,来重新装载预分频器和重复计数器的值,立刻,我们写的值只有在更新事件时,才会起到作用,然后就手动生成了个更新事件,这样预分频器的值就有效了。副作用是更新事件和更新中断同时发生,更新中断会更新中断标志位,当初始化之后,更新中断就会立刻进入。所以初始化完时基单元清除一下更新中断标志位可以避免问题发生。

什么时候用浮空输入呢,如果你外部的输入信号功率很小,内部的上拉电阻可能会影响到这个输入信号,这时就可以用一下浮空输入,防止影响外部输入的电平

---------PWM输出比较--------

OC Output Compare )输出比较
输出比较可以通过比较 CNT CCR 寄存器值的关系,来对输出电平进行置 1 、置 0 或翻转的操作,用于输出一定频率和占空比的 PWM 波形
每个高级定时器和通用定时器都拥有 4 个输出比较通道
高级定时器的前 3 个通道额外拥有死区生成和互补输出的功能

IC----->Input Capture

CC ---->Capture/Compare

CNT----计数器

CCR----捕获/比较寄存器

在输出比较时,CNT到CCR会比较CNT和CCR的值,CNT计数自增,CCR是我们给定的一个值,当CNT大于CCR、小于CCR或者等于CCR时,输出就会对应地置1、置0、置1、置0,这样就可以输出一个电平不断跳变的PWM波形

oc1ref高低电平信号,reference参考信号

ETRF输入,是定时器的一个小功能,一般不用

至主模式控制器:可以把REF映射到主模式的TRGO输出上去

CC1P:写0照常,写1取反

输出使能:选择要不要输出

有效电平、无效电平一般是高级定时器里面的一个说法,是和关断、刹车这些功能配合表述的,可以理解为置有效电平就是置高电平,置无效电平就是置低电平

 分辨率:占空比变化的最小步距,占空比变化的越细腻越好

H桥:两组由两个MOS管组成的推挽电路,可以驱动电机

OC1和OC1N是两个互补的输出端口,分别控制上管和下管的导通和关闭,然后是在切换上下管导通状态时,如果在上管关断的瞬间,下管立刻就打开,那可能会因为器件的不理想,上管还没完全关断,下管就已经导通了,出现了上下管同时导通的现象,这会导致功率损耗,引起器件发热,所以在这里为了避免这个问题,就有了死区生成电路,它会在上管关闭的时候,延迟一小段时间,再导通下管,下管关闭的时候,延迟一小段时间,再导通上管,这样就可以避免上下管同时导通的现象了。

SG90舵机:棕色是电源负,红色是电源正,橙色是信号线/黑负,红正,白信号

STBY(Stand By)引脚,是待机控制脚,如果接GND,芯片就不工作,处于待机状态,如果接逻辑电源VCC,芯片就正常工作 

第一步,RCC开启时钟,把要用的TIM外设和GPIO外设的时钟打开

第二步,配置时基单元,包括这前面的时钟源选择

第三步,配置输出比较单元

第四步,配置GPIO,初始化为复用推挽输出的配置

第五步,运行控制,启动计数器

//对应四个输出比较单元
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);//给输出比较结构体赋一个默认值

//用来配置强制输出模式,如果在运行中想暂停输出波形并且强制输出高或低电平,可以用,相当于100%或者0%占空比
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);

//用来配置CCR寄存器的预装功能的,这个预装功能就是影子寄存器,就是你写入的值不会立即生效,而是在更新事件才会生效
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

//用来配置快速使能,用的不多
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);

//外部事件时清除REF信号
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);

//用来单独设置输出比较的极性,带个N就是高级定时器里互补通道的配置,OC4没有互补通道所以就没有OC4N的函数
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

//是用来单独修改输出使能参数的
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);

//选择输出比较模式,用来单独更改输出比较模式
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);

//用来单独更改CCR寄存器值的函数
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

//仅高级定时器适用,在使用高级定时器输出PWM时,需要调用这个函数,使能主输出,否则PWM将不能正常输出
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

复用功能:片上外设端口和GPIO的连接关系

使用引脚重映射,需要用到AFIO,要启动他的时钟,用GPIO_PinRemapConfig()

SWJ--->SWD和JTAG,NOJTRST就是解除JTRST引脚的复用,JTAGDisable就是接触JTAG调试端口的复用,SWJDisable就是SWD和JTAG的引脚都变为普通的GPIO

定时器输入捕获功能

IC Input Capture )输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前 CNT 的值将被锁存到 CCR 中,可用于测量 PWM 波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有 4 个输入捕获通道
可配置为 PWMI 模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量

 测频法适合测量高频信号,测周法适合测量低频信号

假如给定的信号频率非常低,在一个计数周期内只有寥寥无几的几个上升沿,甚至一个上升沿都没有,在计次N很少时,误差会非常大;低频信号,周期比较长,计次就会比较多,有助于减小误差。

测频法测量结果更新的慢一些,数值相对稳定。测周法更新的快,数据跳变也非常快。测频法要等一定时间,而且是取平均,比较平滑;测周法,只测一个周期,就能出一个结果,结果值会受噪声的影响,波动比较大。N越大,相对误差越小。正负1误差,多或者少算一个周期

 异或门的输出是为了三相无刷电机服务的,无刷电机有3个霍尔传感器检测转子的位置,可以根据转子的位置进行换相,有了这个异或门,就可以在三个通道接上无刷电机的霍尔传感器,然后定时器就作为无刷电机的接口定时器,去驱动换相电路工作

输入滤波器可以对信号进行滤波,避免一些高频的毛刺信号误触发

边沿检测器,可以选择高电平触发或者低电平触发,当出现指定的电平时,边沿检测电路就会触发后续电路执行动作,另外这里其实设计了两套滤波和边沿检测电路,第一套电路经过滤波和极性选择,得到TI1FP1(T1 Filter Polarity 1),输入给通道1的后续电路;第二套电路,经过另一个滤波和极性选择,得到TI1FP2(TI1 Filter Polarity 2),输入给下面通道2的后续电路。同理,下面TI2信号进来,也经过两套滤波和极性选择,得到TI2FP1和TI2FP2。在这里,两个信号进来,可以选择各走各的,也可以选择交叉,让CH2引脚输入给通道1,或者CH1引脚输入给通道2。交叉的目的:1:可以灵活切换后续捕获电路的输入  2:可以把一个引脚的输入,同时映射到两个捕获单元,是PWMI模式的经典结构,第一个捕获通道,使用上升沿触发,用来捕获周期,第二个通道,使用下降沿触发,用来捕获占空比,两个通道同时捕获,就可以同时测量频率和占空比

TRC信号也可以选择作为捕获部分的输入,来源于上面时钟选择那里,也是为了驱动无刷电机的驱动

每来一个触发信号,CNT的值就会向CCR转运一次,转运的同时,会发生一个捕获事件,这个事件会在状态寄存器置标志位,同时也可以产生中断,如果需要在捕获的瞬间,处理一些事情,就可以开启这个捕获中断

主从触发模式自动完成CNT清零

fDTS是滤波器的采样时钟来源,下面CCMR1寄存器里的ICF位可以控制滤波器的参数,这几位定义了TI1输入的采样频率以及数字滤波器的长度,数字滤波器由一个事件计数器组成,它记录到N个事件后会产生一个输出的跳变,简单理解就是以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,连续N个值都为低电平,输出才为低电平,如果你信号出现高频抖动,导致连续采样N个值不全都相同,那输出就不会变化,这样就可以达到滤波的效果。采样频率越低,采样个数N越大,滤波效果就越好。 

用CCER寄存器里的CC1P位就可以选择极性了

得到TI1FP1触发信号,通过数据选择器,进入通道1后续的捕获电路,实际滤波器+向下计数器到TI1F_Rising+TI1F_Failing还有一套一样的电路,得到TI1FP2触发信号,连接到通道2的后续电路

CC1S位可以对数据选择器进行选择,之后ICPS位,可以配置分频器,最后CC1E位,控制输出使能或失能,如果使能了输出,输入端产生指定边沿信号,经过层层电路,就可以让CNT的值转运到CCR里面。在这里硬件电路就可以在捕获之后自动完成CNT的清零工作。TI1FP1信号和TI1的边沿信号(TI1F_ED)都可以通向从模式控制器,比如TI1FP1信号的上升沿触发捕获,还可以同时触发从模式,这个从模式里面,就有电路,可以自动完成CNT的清零。

主从触发模式,就是主模式、从模式和触发源选择这三个功能的简称,其中主模式可以将定时器内部的信号,映射到TRGO引脚,用于触发别的外设,所以这部分叫做主模式。从模式,就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制。触发源选择,就是选择从模式的触发信号源,可以认为是从模式的一部分,触发源选择指定的一个信号,得到TRGI,TRGI去触发从模式,从模式可以在列表里选择一项操作来自动执行。

触发源选择TI1FP1,从模式执行的操作选择Reset,这样TI1FP1的信号就可以自动触发从模式,从模式自动清零CNT,实现硬件全自动测量。 

重装模式:指定定时器预分频器的重装模式,Update:预分频器在更新事件重装,Immediate:预分频器立即重装,属于影子寄存器,重装载的问题

输入捕获的初始化:

第一步,RCC开启时钟,把GPIO和TIM的时钟打开

第二步,GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式

第三步,配置时基单元,让CNT计数器在内部时钟的驱动下自增运行

第四步,配置输入捕获单元,包括滤波器、极性、直连通道还是交叉通道、分频器这些参数,用一个结构体就能统一进行配置

第五步,选择从模式的触发源,触发源选择为TI1FP1,这里调用一个库函数,给一个参数就行了

第六步,选择触发之后执行的操作,执行reset操作,这里也是调用一个库函数就行了

最后,调用TIM_Cmd函数,开启定时器计数器

//用结构体配置输入捕获单元的函数
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

//用于初始化输入捕获单元,上面那个函数只是单独地配置一个通道,而这个函数可以快速配置两个通道,把外设电路结构配置成PWMI模式(频率+占空比)
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

//可以给输入捕获结构体赋一个初始值
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);

//选择输入触发源TRGI,从模式的触发源选择
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

//选择输出触发源TRGO,选择主模式输出的触发源
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);

//选择从模式
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

//分别单独配置通道1、2、3、4的分频器
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);

//分别读取4个通道的CCR,两个不同模式下,输出比较是只写,输入捕获是只读
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);

ICFilter---滤波器参数,数越大滤波效果越好,一般滤波器的采样频率都会远高于信号频率,所以它只会滤除高频噪声

Channel就是输入通道

ICPolarity---极性选择

ICPrescaler---触发信号分频,其实就是多少次触发才算一次

ICSelection---选择触发信号从哪个引脚输入,可以选择直连通道或者是交叉通道,DirectTI就是直连通道,IndirectTI就是交叉通道

 

调用PWMIconfig函数可以在完成了通道一初始化的前提下自动把剩下的一个通道初始化成相反的配置 

Encoder Interface 编码器接口
编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制 CNT 自增或自减,从而指示编码器的位置、旋转方向和旋转速度
每个高级定时器和通用定时器都拥有 1 个编码器接口
两个输入引脚借用了输入捕获的通道 1 和通道 2

 

使用编码器接口的好处就是节约软件资,如果使用外部中断来计次,那当电机高速旋转时,编码器每秒产生成千上万个脉冲,程序就得频繁进入中断,然后进入中断之后,完成的任务又只是简单的加一减一,浪费资源

编码器接口就是自动给编码器进行计次的电路,如果我们每隔一段时间取一下计次值,就能得到编码器旋转的速度了

编码器测速一般应用在电机控制的项目上,使用PWM驱动电机,再使用编码器测量电机的速度,然后再用PID算法进行闭环控制

一般电机转速比较高,会使用无接触式的霍尔传感器或者光栅进行测速

正交编码器:输出的两个方波信号,相位相差90度,超前90度或者滞后90度,分别代表正传和反转

 正交编码器一般可以测量位置,或者带有方向的速度值

编码器接口的设计逻辑就是首先把A相和B相的所有边沿作为计数器的计数时钟,出现边沿信号时,就计数自增或者自减,计数的方向由另一相的状态来确定,当出现某个边沿时,我们判断另一相的高低电平,如果对应另一相的状态出现在上面的表,那就是正转,计数自增,反之,另一相的状态出现在下面的表,那就是反转,计数自增,这样就能实现编码器接口的功能

编码器接口的两个通道:TI1FP1和TI2FP2

编码器接口的输出部分,其实就相当于从模式控制器,去控制CNT的计数时钟和计数方向

 

编码器抗噪声的原理:如果出现了一个引脚不变,另一个引脚连续跳变多次的毛刺信号,计数器就会加、减、加、减来回摆动,最终计数值呢,还是原来那个数,并不受毛刺噪声的影响

 

 采用编码器接口后,输入通道的边沿检测极性选择就是直通和反相,上升沿代表直通,下降沿代表反相

编码器接口相当于是带有方向选择的外部时钟

第一步,RCC开启时钟,开启GPIO和定时器的时钟

第二步,配置GPIO,这里需要把PA6和PA7配置成输入模式

第三步,配置时基单元,这里预分频器我们一般选择不分频,自动重装一般给最大的65535

第四步,配置输入捕获单元,这里输入捕获单元只有滤波器和极性选择这两个参数有用

第五步,配置编码器接口模式

第六步,TIM_cmd启动定时器

//定时器编码器接口配置,EncoderMode---编码器模式  后面两个参数分别是选择通道1和通道2的电平极性
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);

上拉和下拉选择原则是防止外部输出的器件默认电平与输入的默认电平冲突

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值