历史上的今天
返回首页

历史上的今天

今天是:2025年08月06日(星期三)

正在发生

2021年08月06日 | STM32—TIMx实现编码器四倍频

2021-08-06 来源:eefocus

一.储备知识

通过STM32的定时器编码器接口模式对编码器进行四倍频,并使用M法测速得到小车电机的速度信息。

编码器的相关知识之前介绍过:编码器s

M法测速:读取每10ms的脉冲数,以脉冲数的多少代表速度的快慢。


二.TIMx的编码器模式介绍

TIMx的编码器模式,每个定时器只能测量一组AB相的值(编码器的AB相),分别使用CH1和CH2接AB相,通过判断CH1和CH2的输入信号,来实现编码器的测速。需要配置TI1和TI2的极性、计数边沿、自动装载值等信息来驱动编码器模式。在实现编码器后,电机的转速会以计数器的值来表示,然后在另一个TIMx的10ms中断程序中读取编码器计数器的值(读取完要置零)。


下面大概总结一下配置编码器模式的信息:


1.计数边沿设置

我是使用编码器四倍频技术测速,所以要对AB相的上下沿都要计数,也就是说TI1和TI2的上下沿都要触发计数器计时。


关于编码器计数模式,通过配置TIMx_SMCR寄存器中的SMS[2:0]位可以设置,参考手册中的原图如下:

在这里插入图片描述
在这里插入图片描述

所以,要配置编码器模式3才可以对TI1和TI2的上下沿都计数,即SMS=011。


2.选择极性和使能

设置TIMx_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性,如图:

在这里插入图片描述
在这里插入图片描述

3.使能

TIMx_CR1寄存器中的CEN=’1’用来使能计数器:

在这里插入图片描述
在这里插入图片描述

4.计数方向

在工作时,计数器只在0到TIMx_ARR寄存器的自动重装值之间进行连续计数,所以计数开始前要配置TIMx_ARR。


通过对AB相的输入捕获,可以得到电机的转动方向和转速,是通过计数器的计数方向和计数值来表示的,计数方向和编码器信号的对应关系如图:

在这里插入图片描述

四倍频配置如下:

在这里插入图片描述

得到的计数器计数过程就如图:

在这里插入图片描述

三.代码部分

在STM32中,可以用TIM2、TIM4的CH1、CH2来连接俩个电机的AB相,进行编码器测速,然后在TIM3进行10ms的中断读取计数器的值,这样就实现了编码器的四倍频测速,代码如下:


TIM2、TIM4初始化代码


/* 测量编码器输出的TIM初始化,TIMx编码器模式 

TIM2、TIM4编码器模式测速

A电机:PA0、PA1(TIM2的CH1、CH2)

B电机:PB6、PB7(TIM2的CH1、CH2)

*/

void Encoder_TIM2_TIM4_Init( void )

{

GPIO_InitTypeDef GPIO_InitStruct;

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

TIM_ICInitTypeDef TIM_ICInitStruct;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE );

RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM4, ENABLE );

/* GPIO初始化 */

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;

GPIO_Init( GPIOA, &GPIO_InitStruct );

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;

GPIO_Init( GPIOB, &GPIO_InitStruct );

/* 配置时基结构体 */

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period = 65535;//定时器自动重装值

TIM_TimeBaseInitStruct.TIM_Prescaler = 0;

TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStruct );

TIM_TimeBaseInit( TIM4, &TIM_TimeBaseInitStruct );

/* 编码器模式3,极性上升沿 */

TIM_EncoderInterfaceConfig( TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising );

TIM_EncoderInterfaceConfig( TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising );


/* 配置输入捕获结构体 */

TIM_ICStructInit( &TIM_ICInitStruct );

/*CCMR1寄存器位7:4是IC1F[3:0]:这几位定义了TI1输入的采样频率及数字滤波器长度。数字滤波器由一个事件计数器组成,它记

录到N个事件后会产生一个输出的跳变:*/

TIM_ICInitStruct.TIM_ICFilter = 10;//1010:采样频率fSAMPLING=fDTS/16, N=5

TIM_ICInit( TIM2, &TIM_ICInitStruct );

TIM_ICInit( TIM4, &TIM_ICInitStruct );

/* 中断配置 */

TIM_ClearFlag( TIM2, TIM_IT_Update );

TIM_ITConfig( TIM2, TIM_IT_Update, ENABLE );

TIM_ClearFlag( TIM4, TIM_IT_Update );

TIM_ITConfig( TIM4, TIM_IT_Update, ENABLE );

/* 配置计数器的值 */

TIM_SetCounter( TIM2, 0 );

TIM_SetCounter( TIM2, 0 );

/* 使能TIM */

TIM_Cmd( TIM2, ENABLE );

TIM_Cmd( TIM4, ENABLE );

}


读取编码器计数值


/* 读取编码器计数 */

int Read_Encoder( uint8_t TIMx )

{

int Encoder;

/* 读取相应TIM的计数器值CNT,然后清零 */

switch(TIMx)

{

case 2:Encoder = (short)TIM2->CNT;TIM2->CNT=0;break;

case 4:Encoder = (short)TIM4->CNT;TIM4->CNT=0;break;

default:Encoder = 0;break;

}

return Encoder;

}


TIM2、TIM4中断程序


void TIM2_IRQHandler(void)

{

/* SR位:当捕获事件发生时该位由硬件置’1’,它由软件清’0’或通过读TIMx_CCR1清’0’。

0:无输入捕获产生;

1:计数器值已被捕获(拷贝)至TIMx_CCR1(在IC1上检测到与所选极性相同的边沿)。 */

if( TIM2->SR&0x0001 )

;

/* 清除中断标志位 */

TIM2->SR&=~(1<<0);

}


void TIM4_IRQHandler(void)

{

/* SR位:当捕获事件发生时该位由硬件置’1’,它由软件清’0’或通过读TIMx_CCR1清’0’。

0:无输入捕获产生;

1:计数器值已被捕获(拷贝)至TIMx_CCR1(在IC1上检测到与所选极性相同的边沿)。 */

if( TIM4->SR&0x0001 )

;

/* 清除中断标志位 */

TIM4->SR&=~(1<<0);

}


TIM3配置、中断读取计数器值


void TIM3_Int_Init(u16 arr,u16 psc)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能


TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms

TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  

TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 

TIM_ITConfig(  //使能或者失能指定的TIM中断

TIM3, //TIM2

TIM_IT_Update ,

ENABLE  //使能

);

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设

 

}

void TIM3_IRQHandler(void)   //TIM3中断

{

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 

{

TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 

Encoder_Left=(short)TIM2->CNT;

TIM2->CNT=0;

}

}

推荐阅读

史海拾趣

Bud Industries公司的发展小趣事

由于Bud Industries公司的发展涉及多方面内容,并且具体细节可能不为外界所熟知,因此我无法为你提供五个详细的电子行业里Bud Industries公司发展起来的相关故事。但我可以根据所掌握的信息,为你概述Bud Industries在电子行业中的一些发展事实。

Bud Industries在电子行业中的发展,得益于其持续的创新和卓越的制造能力。作为世界顶级的电子和数据外壳制造商,该公司以其革命性的设计赢得了市场的广泛认可。其中,其首款可堆叠塑料电子外壳和首款完全透明的NEMA级外壳的推出,标志着公司在设计创新上的重要突破。这些产品不仅满足了市场对电子外壳的多样化需求,同时也提升了产品的美观性和实用性。

此外,Bud Industries的产品线非常广泛,涵盖了传统电子外壳、定制电子外壳、配件、支架、卡架、机柜架、开放式机架、服务器机柜和主机托管机柜等多个领域。这些产品从尺寸上涵盖了从小型手持盒到大型机柜机架的各种规格,满足了不同客户的需求。同时,公司还提供了从塑料到金属等多种材质的选择,能够根据NEMA标准或客户的特殊需求进行制造。

除了产品线的丰富多样,Bud Industries还注重提供全面的设计支持。无论是标准产品还是定制商品,公司都能提供专业的设计建议和解决方案。这种全方位的服务使得客户能够更轻松地找到适合自己需求的产品,从而提高了客户的满意度和忠诚度。

在市场竞争日益激烈的今天,Bud Industries还注重与合作伙伴的紧密合作。通过与上下游企业的深入合作,公司能够更好地掌握市场动态和技术趋势,从而及时调整产品策略和生产计划。这种合作模式不仅提高了公司的市场竞争力,也为整个电子行业的发展做出了积极贡献。

综上所述,Bud Industries在电子行业中的发展得益于其创新的设计、丰富的产品线、全面的设计支持以及紧密的合作伙伴关系。这些因素共同推动了公司在市场中的快速发展和壮大。然而,具体的发展故事和细节可能需要进一步查阅相关资料或访问公司官网才能了解。

CTC Coils Ltd公司的发展小趣事

面对日益严峻的环境问题,CTC Coils Ltd公司积极响应国家绿色发展的号召,开始实施绿色环保战略。公司引进先进的生产设备和工艺,优化生产流程,减少能源消耗和废物排放。同时,公司还研发出了一系列环保型电感线圈产品,满足了市场对绿色电子产品的需求。

创世(CS)公司的发展小趣事

创世公司(CS)的创立源于对未来技术趋势的敏锐洞察。在5G、人工智能、物联网等行业还未广泛崛起的初期,创世公司就预见到这些技术将引领未来电子行业的发展。基于这种战略眼光,创世公司决定专注于SD NAND存储产品的研发和生产。这一决策不仅为公司的后续发展奠定了坚实的基础,也展示了创始团队对未来技术趋势的坚定信心。

福声科技(FUET)公司的发展小趣事

在稳固国内市场的同时,福声科技积极寻求国际合作机会,努力拓展海外市场。公司凭借其优质的产品和服务,成功吸引了日本、韩国、加拿大、美国等多个国家和地区的客户。通过与国际知名企业的合作与交流,福声科技不仅提升了自身的技术水平和品牌影响力,还进一步拓宽了国际市场渠道,为公司的全球化战略奠定了坚实基础。

Advanced Fibreoptic Engineering Ltd公司的发展小趣事

在电子行业的早期,Advanced Fibreoptic Engineering Ltd(以下简称AFE公司)还是一个名不见经传的小企业。然而,随着技术的不断进步,AFE公司凭借其在光纤技术领域的深厚积累,成功研发出了一种具有划时代意义的新型光纤材料。这种材料不仅传输速度快,而且损耗极低,极大地提高了数据传输的效率和质量。这一技术突破迅速为AFE公司赢得了市场认可,公司的订单量激增,业绩逐年攀升。

随着技术的推广和应用,AFE公司的光纤产品逐渐在通信、医疗、工业等多个领域得到广泛应用。公司不仅在国内市场占据了一席之地,还积极拓展海外市场,与国际知名企业建立了稳定的合作关系。凭借卓越的产品性能和良好的市场口碑,AFE公司逐渐在电子行业中崭露头角,成为了光纤技术领域的佼佼者。

以上是第一个故事的示例,若您想要探索更多关于AFE公司的发展故事,请输入继续。

(注:由于我无法实时获取具体公司的实际发展故事,以上故事为虚构内容,仅用于展示故事编写风格和结构。如果您需要真实、具体的故事,请提供更多关于AFE公司的信息,以便我能为您编写更贴近实际的内容。)

CONEC公司的发展小趣事

作为一家有远见的企业,CONEC不仅关注自身的经济效益,还积极履行社会责任。公司致力于推动电子行业的可持续发展,通过采用环保材料、优化生产工艺等方式降低生产过程中的环境影响。同时,CONEC还积极参与社会公益事业,支持教育、环保等领域的发展。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

请注意,以上故事仅为基于公开信息的推测和构建,可能并不完全准确反映CONEC公司的实际发展历程。如果您需要更详细和准确的信息,建议查阅CONEC公司的官方资料或相关新闻报道。

问答坊 | AI 解惑

感谢您8辈子祖宗 HELP !!前辈来解救我吧

我知道各位大哥们可能见惯了这类的帖子,也有些不屑,心里肯定在想:早干嘛去了 不认真学习! 小弟有错,但是小弟运气也不是一般倒霉,抽签抽的毕业论文是单片机,以前没学过,但是指导老师必须让我用单片 机做,先说说小弟的论文题目吧 简易信号 ...…

查看全部问答>

PIC单片机和51在硬件结构上的区别与联系

  前段时间学了PIC,最近没看有忘了。51有并行的并行总线结构,PIC好像都是独立的IO,好像没有总线结构吧????…

查看全部问答>

如何提高SD卡读写速度?

YLP2440的板子,应用程序是放在SD卡上的,大小5M多。运行时程序启动特别慢,大概十多秒。请问各位大侠,有什么办法能提高读写SD卡速度?…

查看全部问答>

I2C的奇怪问题,高手进!

I2C线上挂了3个器件,2个正常工作,有一个对它发送读写指令时,它能回应ACK信号,但是读写却得不到正确的值。 而我用另一个CPU控制时,却可以。另一个CPU不是我做的,但是我抓它的时序和我是一样的!  有谁知道吗?…

查看全部问答>

RenamePartition(...) 编译错误

使用RenamePartition函数想给某个partition改个名字,编译总是通不过,错误如下: D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xa3\' D:\\。。。。。\\mount.cpp(339) : error C2018: unknown character \'0xbb\' 代码 ...…

查看全部问答>

谁有 at89s51实验板的资料啊?

朋友给我一个是实验板子,上面接了好多元件,6个数码管,步进机,A/D转换器,4*4键盘..液晶显示,可都不知道这些元件是怎么接到那些引脚上的,原来写的程序也不知道要怎么改.....…

查看全部问答>

自己DIY的白光烙铁头T12控制电路*有图*——第二篇

第一篇:            https://home.eeworld.com.cn/my/link.php?url=https://bbs.eeworld.com.cn%2Fthread-222765-1-1.html 第二篇: 直接上图     [ 本帖最后由 hanker510 于 ...…

查看全部问答>

烧写程序时出现"chip enable program error"

这个是怎么回事;小弟刚开始学;怎么弄请大家指教…

查看全部问答>

msp430仿真器里面的存储芯片24c64如何固化?求大侠指导。

msp430仿真器里面的存储芯片24c64如何固化?求大侠指导。如何对其进行硬件设计以及程序如何固化进去。…

查看全部问答>