STM32f103 定时器之编码器接口模式

发布者:AngelicWhisper最新更新时间:2017-06-04 来源: eefocus关键字:STM32f103  定时器  编码器  接口模式 手机看文章 扫描二维码
随时随地手机看文章

背景

买了个Arduino的旋转编码器模块,配合STM32定时器的编码器模式实现了旋转角度以及圈数的计数。这种旋转编码器我能想到的实际应用场景暂时只有实体音量旋钮,鼠标的滚轮等,所以只实现了计数。阅读Arduino关于该编码器的介绍,该编码器还可以实现旋转的速度、加速度的计算。应该算是算法层级的吧,还没做到实际应用,暂时不深究,本篇仅仅对旋转编码器的原理以及STM32编码器接口模式的配置使用方法做个简介。

正文

编码器分类:
按工作原理:光电式、磁电式和触点电刷式;
按码盘的刻孔方式:增量式和绝对式两类;
这是从网上看到一个简介,只接触过Arduino的编码器,其他暂未使用过。

Arduino的编码器属于增量式。它一共有5根线。分别为“CLK”、“DT”、“SW”、“+”、“GND”。

  • “+”、“GND”:勿用多说,VCC与GND,接至板子的VCC与GND即可。

  • “SW”:Arduino介绍说,当旋钮旋转完一圈时,该脚会放出一个电平跳变信号,相当于旋转编码器常说的“Z”信号,实际上我买的这个只是一个开关,即旋钮部分可以按下去(类似于汽车上的音量调节按钮),该接口会产生一个下降沿。然后由MCU去做相关处理。

  • “CLK”、“DT”:在该模块上显示的丝印名称为这两个,不明白为什么是这个丝印,应该实际对应于编码器常用的“A”、“B”信号吧,这两个信号的发生方式如下:

  1. 正旋:如上图当旋钮开始正向旋转时,“A”从低电平变为高电平,“B”保持不变;当旋钮旋转到预定位置时,“A”维持为高电平,“B”然后跟着从低电平跳变到高电平。也就是说,正旋时,“A”总是先与“B”开始电平变化。

  2. 反旋:与正旋相反,“B”总是先与“A”开始电平变化。
    所以在此处,丝印将该两个接线印成“CLK”、“DT”就让我有点困惑。也未找到相关资料,先暂时放放,下次有实际应用,就知道为什么了。

根据如上正旋反旋规律,就已经可以根据编码器输出的信息判断出编码器的旋转方向以及计算出其旋转角度了,具体做法如下:
将“CLk”、“DT”分别连接至MCU的任意具有外部中断的IO口,处理方式为:

  1. 将该两个IO口配置为双边沿外部中断。

  2. 当其中某个IO口检测到上升沿或者下降沿时,在中断函数内检测另一个IO口的电平状态。以正旋为例,正旋时,“A”先上升沿引起中断,得到的“A”、“B”的电平状态为“10”,紧接着,“B”上升沿,检测到“A”、“B”电平状态为“11”。

  3. 若一直正转,则“A”、“B”的电平状态为“10 - 11 - 01 - 00 - 10 - ...”。

  4. 若一直反转,则“A”、“B”的电平状态为“01 - 11 - 10 - 00 - 01 - ...”
    以此,即可判断出该编码器的旋转方向,同时在“A”、“B”同时跳变完成后,即可根据编码器的旋转方向对编码器的旋转计数进行增减。

以上为使用外部中断方式处理旋转编码器的输出信息,当然,本篇要用到STM32定时器的接口模式,所以也就不会用以上的方法进行判断。那么定时器的接口模式是如何对旋转编码器进行计数的呢?
其实原理一样,将旋转编码器的“CLK(A)”、“DT(B)”脚接入到TIMx的通道,将对应通道引脚配置为编码器接口模式,使能计数,然后STM32的值就会在硬件上按照上述规对计数器的值进行加减。

本实验接到的是STM32F103的“PB6(TIM4_CH1)”、“PB7(TIM4_CH2)”,具体配置如下:

  1. 配置IO口:

    // GPIO// 使能对应的GPIO口时钟RCC_APB2PeriphClockCmd(Enc_GPIO_CLK, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = Enc_CLK_GPIO_PIN | Enc_DAT_GPIO_PIN | Enc_SW_GPIO_PIN;// 该编码器模块已经做了外部上拉处理,配制成浮空输入即可GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(Enc_GPIO_PORT, &GPIO_InitStructure);
  2. 配置定时器基本单元:

    // TIM4// PB6 ch1  A,PB7 ch2   // TIMxCLK = 36MHZRCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    
    TIM_DeInit(TIM4);
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Period = 0xFF;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  3. 配置对应寄存器为编码器接口模式以及配置相关的输入捕获配置:

    TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12,  TIM_ICPolarity_Falling, TIM_ICPolarity_Falling);
    
    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;TIM_ICInit(TIM2, &TIM_ICInitStructure);
  4. 清除相关中断,以及清除对应的计数器,并启动定时器:

    // Clear all pending interruptsTIM_ClearFlag(TIM4, TIM_FLAG_Update);// 其实中断可以不用开,因为硬件自行对计数器进行加减。TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//Reset counterTIM4->CNT = 0;
    
    TIM_Cmd(TIM4, ENABLE);   //启动TIM4定时器
  5. 如若开了中断,中断处理函数为:

    void TIM4_IRQHandler(void){   
    if(TIM4->SR&0x0001)//溢出中断{
        LED_Toggle(1);
    }   
    TIM4->SR&=~(1<<0);//清除中断标志位     }
  6. 主函数读取相应计数器值,并将其打印至串口:

    int main(void) {// 读取计数器信息Enc0Pos = TIM_GetCounter(TIM4);// 取模2的原因是,两个引脚接到同一个定时器,每旋转一次会计数两次Enc0Pos /= 2;if(Enc0Pos != Enc_PinDATLast
    {
        Enc_PinDATLast = Enc0Pos;    printf("Position = %d\n\r", Enc0Pos);
    }
    }

参考文献:

"Reading Rotary Encoders Contents".
"Get Native 32Bit resolution for your encoder on STM32F4".
"STM32定时器---正交编码器模式详解".

至此,记录完毕


关键字:STM32f103  定时器  编码器  接口模式 引用地址:STM32f103 定时器之编码器接口模式

上一篇:STM32f103按键检测程序实现长按短按
下一篇:STM32f10xxx 之 GPIO口配置

推荐阅读最新更新时间:2024-03-16 15:35

stm32f103c6串口发送程序
人单片机萌新一枚,最近用protues仿真stm32f103c6进行串口数据,另外protues仿真还有一个bug,必须在前面加上 RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);否则会一直发送0x00. 单片机源程序如下: #include stm32f10x.h #include stm32f10x_it.h #include led.h #include modbus.h #include delay.h void SystemTick_Configuration( void ); int main(void) { RCC_SYSCLKConfi
[单片机]
<font color='red'>stm32f103</font>c6串口发送程序
STC89C52单片机 使用定时器使LED灯闪烁
#include reg52.h #include intrins.h #define uint unsigned int #define uchar unsigned char sbit LED1 = P1^0;//LED1 //定时器1初始化 void timer1Init() { TR1 = 1; //启动定时器1 TMOD |= 0X10; //定时器1工作模式1,16位定时模式 TH1 = 0x4b; TL1 = 0xfd; //定时50ms } void main()//main函数自身会循环 { uchar mSec;//毫秒储存变量 timer1In
[单片机]
STM32CubeMX系列教程3:基本定时器
这一章我们在前一章GPIO的工程修改。复制GPIO的工程,修改文件夹名。点击 打开STM32cubeMX的工程文件重新配置。开启定时器TIM3,选择内部时钟。 定时器就相当于单片机的闹钟,下面我们以基本定时器为例简单介绍一下定时器。 从上图我们可以看到,基本定时器主要由下面三个寄存器组成。 计数器寄存器 (TIMx_CNT) 预分频器寄存器 (TIMx_PSC) 自动重载寄存器 (TIMx_ARR) 计数器寄存器 (TIMx_CNT)存储的是当前的计数值。预分频器 (TIMx_PSC)为多少个SK_PSC脉冲计数一次,如图192 预分频器的值为1(预分频寄存器默认为0,为不分频),则为两个脉冲计数一次。即为二
[单片机]
STM32CubeMX系列教程3:基本<font color='red'>定时器</font>
利用STM32高精度定时器实现PWM输出的实现原理
很多STM32系列的MCU内置高精度定时器,比方STM32F334、STM32G4、STM32H7等系列。利用高精度定时器实现PWM输出应该说是最基本的功能了。不过,在实际应用中,常有人觉得无法实现duty=0或duty=100%的PWM输出情形。这里以STM32F334的HRTIM为例,简单介绍下利用它实现PWM输出的实现原理。 STM32F334的HRTIM的功能框图如下,由一个MASTER定时器和ABCDE五个定时器单元组成。其中ABCDE五个定时器单元各可以产生2路输出信号,并支持互补输出。 先看看跟HRTIM有关的时钟。别的系列有支持向上、向下计数模式的。 在利用HRTIM中的定时器单元实现PWM输出时,基于不同
[单片机]
利用STM32高精度<font color='red'>定时器</font>实现PWM输出的实现原理
旋转编码器的零位
旋转编码器是一种光电式旋转测量装置,它将被测的角位移直接转换成数字信号(高速脉冲信号),主要应用于机床、电梯、伺服电机配套、纺织机械、包装机械、印刷机械、起重机械等行业。 旋转编码器按照工作原理编码器可分为增量式和绝对式两类。 A增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小; B绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。 二者区别: 增量型的位置从零位标记开始计算的脉冲数量确定的; 而绝对型的位置是由输出代码的读数确定的。在一圈里,每个位置的输出代码的读数是唯一的;因此,当电源断开时,绝对型编码器并不
[嵌入式]
旋转<font color='red'>编码器</font>的零位
LPC210X定时器查询方式及如何初始化
定时器查询方式定时器初始化: 1、设置定时器分频数,为(x+1)分频 2、匹配通道X中断并复位TxTC 3、比较值(1S定时值) 4、启动并复位TxTC 如: T1PR = 99; // 设置定时器0分频为100分频,得110592Hz T1MCR = 0x03; // 匹配通道0匹配中断并复位T0TC T1MR0 = 110592/2; // 比较值(1S定时值) T1TCR = 0x03; // 启动并复位T0TC T1TCR = 0x01; 研究了好长一段时间,LPC210X的定时器,查询方式定时很简单如上面,但中断方式要操作好多寄存器,太麻烦,一直是一头雾水。好不容易理出了思路,现将一段例程粘贴备忘。 #inclu
[单片机]
(C51学习四)外部中断和定时器中断
1.什么是中断 中断就是指CPU正在执行一项任务A,然后突然停止任务A去执行任务B,执行完任务B再回来继续执行任务A的过程。 例如:你正在看电视,然后电话响了,你就停止看电视,跑去接电话,接完电话后由回来继续看电视。这个过程叫中断。 中断跟硬件有关。可以说是硬件来让单片机中断。 2.中断有什么用 1.中断能让CPU同时执行多项任务,例如CPU在执行流水灯程序,就无法执行 按下按键时,蜂鸣器发声了。 2.当然上面的例子可以用软件轮询检擦案件是否按下来实现,但这样就消耗了CPU一部分资源来轮询检测 按键是否有按下了,所以中断的另一个优点就是 节省CPU资源 3.双重功能的P3引脚 由最小系统板
[单片机]
(C51学习四)外部中断和<font color='red'>定时器</font>中断
AT89S52的看门狗定时器详情分析
  AT89S52是一种低功耗、高性能CMOS 8位微控制器,具有8K 系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。   AT89S52主要性能:   1、与MCS-51单片机产品兼容;   2、8K字节在系统可编程Flash存储器;   3、1000次擦写周期;   4、全静态操作:0Hz-33MHz;   5、三级加密程序存储器;   6、32个可编程I/O口线;   7、
[单片机]
AT89S52的看门狗<font color='red'>定时器</font>详情分析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved