STM32正交编码器例程
- 格式:doc
- 大小:196.50 KB
- 文档页数:4
基于STM32的磁编码器的设计
陈文浩;朱礼尧;迟涵文;刘雯;赵志永;邓仕杰;黄彤津
【期刊名称】《电子测量技术》
【年(卷),期】2015(0)6
【摘要】选用巨磁阻传感器作为敏感元件,设计一款基于STM32微控制器的磁编码器。
由正交放置在圆柱状磁体下方的4个巨磁阻传感器输出两路正交电压信号,该电压信号经过调理电路滤波、放大,采用STM32微处理器对放大后的两路电压信号进行模数转换,然后对转换后的数字量进行校正、辩向和查表等来完成信号处理,输出准确的旋转角度值,并根据需要灵活选择合适的编码器输出方式。
试验结果表明,磁编码器具有较高的检测精度以及实时性。
【总页数】6页(P22-26)
【关键词】STM32微处理器;磁编码器;巨磁阻传感器;算法运算
【作者】陈文浩;朱礼尧;迟涵文;刘雯;赵志永;邓仕杰;黄彤津
【作者单位】杭州电子科技大学电子信息学院
【正文语种】中文
【中图分类】TP212
【相关文献】
1.基于STM32的变频器+编码器精确定位控制系统设计 [J], 吴涛;李勇波;杨靖
2.基于STM32单片机的增量式编码器模拟装置设计 [J], 徐洋;余辉;黄敬贵
3.基于STM32的绝对编码器信号转换为增量编码器信号装置设计 [J], 沈宝诚; 吴
剑飞; 朱嘉
4.基于STM32的增量式编码器测速设计及实验验证 [J], 鲁伟;刘士兴;孙操;李隆
5.基于Arduino的磁编码器轴角解算系统设计 [J], 赵磊;曹广忠;梁芳萍;孙俊缔;胡勇;王芸
因版权原因,仅展示原文概要,查看原文内容请购买。
STM32 16位定时器对正交编码器计数的方法(附检测输入脉冲的方法)发布时间:2009-10-04 14:29:11今天决定在END开博,之前没有工作记录的习惯,从今天起在这里记录下自己工作时的点滴经验,以供日后参考以及与网络朋友交流。
第一篇文章先简要描述下STM32 定时器对正交编码器进行计数控制的方法。
如图,STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。
如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。
通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。
下面是我调试OK的代码:void Encoder_Configration(void){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;//PC6 A相PC7 B相GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);/* Enable the TIM3 Update Interrupt *//*NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRI ORITY;NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);*//* Timer configuration in Encoder mode */TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescalingTIM_TimeBaseStructure.TIM_Period = 10000;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;TIM_ICInit(TIM8, &TIM_ICInitStructure);// Clear all pending interruptsTIM_ClearFlag(TIM8, TIM_FLAG_Update);TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);//Reset counterTIM2->CNT = 0;TIM_Cmd(TIM8, ENABLE);}n_Counter = TIM_GetCounter(TIM8);Diled_Disp_Num((float)n_Counter);另外一个值得注意的问题是,STM32 的定时器是16位的,意思是只能计数到65535,有两种方法,一是采用链式的方式用两个定时器将16位扩展为32位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
ec11stm32例程EC11STM32是一种旋转编码器,常用于嵌入式系统中,可以用来获取旋转方向和计算旋转角度。
在STM32开发板上使用EC11STM32,需要进行相应的配置和编程。
本文将介绍EC11STM32的原理、使用方法以及编程实例。
EC11STM32工作原理:EC11STM32包含一个旋转编码器和一个按钮开关。
旋转编码器由两个光电传感器、一个LED和一个编码盘组成。
编码盘上有很多小刻度,每当旋转编码器旋转一格,编码盘上的刻度就会遮挡或透过光电传感器,从而产生一个脉冲信号。
根据脉冲信号的变化,我们可以判断旋转的方向和计算旋转的角度。
EC11STM32的使用方法:在STM32开发板上使用EC11STM32,首先需要将EC11STM32连接到正确的GPIO引脚上。
然后,我们可以通过读取GPIO引脚的状态来获取旋转和按下按钮的信息。
对于旋转编码器,我们可以使用两个引脚来获取旋转方向和计数。
对于按钮开关,我们可以使用一个引脚来获取按下和释放的状态。
编程实例:下面是一个使用EC11STM32的简单编程实例,用于获取旋转方向和计算旋转角度:```c#include "stm32f10x.h"#define CLK_GPIO GPIOA#define DT_GPIO GPIOB#define BTN_GPIO GPIOC#define CLK_PIN GPIO_Pin_0#define DT_PIN GPIO_Pin_1#define BTN_PIN GPIO_Pin_13int main(void){GPIO_InitTypeDef GPIO_InitStructure;//初始化时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);//配置CLK引脚为输入GPIO_InitStructure.GPIO_Pin = CLK_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(CLK_GPIO, &GPIO_InitStructure);//配置DT引脚为输入GPIO_InitStructure.GPIO_Pin = DT_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DT_GPIO, &GPIO_InitStructure);//配置BTN引脚为输入GPIO_InitStructure.GPIO_Pin = BTN_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(BTN_GPIO, &GPIO_InitStructure);int count = 0;int last_state = 0;int curr_state = 0;while (1){//读取CLK和DT引脚的状态last_state = curr_state;curr_state = GPIO_ReadInputDataBit(CLK_GPIO, CLK_PIN) << 1 | GPIO_ReadInputDataBit(DT_GPIO, DT_PIN);if (last_state != curr_state){//根据旋转方向增加或减少计数if ((last_state == 0b00 && curr_state == 0b01) || (last_state == 0b11 && curr_state == 0b10))count++;else if ((last_state == 0b01 && curr_state == 0b00) || (last_state == 0b10 && curr_state == 0b11))count--;//打印计数值printf("Count: %d\n", count);}//检测按钮是否按下if (GPIO_ReadInputDataBit(BTN_GPIO, BTN_PIN) == 0){//按钮按下时执行的操作printf("Button pressed\n");}}}```通过上述代码,我们可以实现读取EC11STM32的旋转和按钮信息,并进行相应的操作。
基于STM32的正交编码器接口应用本设计应用了ST公司的最新单片机STM32完成。
STM32应用的是ARM 32位的Cortex™-M3 CPU,最高72MHz工作频率,单周期乘法和硬件除法,高速的运行速度,可以保证编码器高转速条件下的高速脉冲依旧能够被准确的计数。
多达7个定时器,3个16位定时器,每个定时器有多达4个用于输入捕获/输出比较/PWM或脉冲计数的通道和增量编码器输入。
因此只要对MCU进行配置之后,MCU只需要少量的中断程序,就可以方便的完成对编码器的方向和角速度的运算。
STM32单片机工作在3.3V下。
拥有内部8M晶振,可以通过锁相环倍频到48M(内部晶振由于稳定度不够,只能倍频到48M)。
采用标准的JATGE接口进行程序的烧录和调试。
采用一块lm1117-3.3V作为芯片的稳压电源。
LM1117为一块LDO(低压差线性稳压器),输入最低为3.3+0.7=4v用一块LCD5110手机屏作为显示设备,可以显示输出电压以及当前状态。
液晶屏参数为72*48,点阵式,使用一个驱动库作为支持,方便开发,工作在3.3V电压下,与单片机相适应。
耗电极低,小于1MA,背光耗电为20MA。
采用USB接口与编码器连接,线序定义为V+,A相,B相,GND,正好将USB的所有连线用完,可以同时完成给编码器提供电力以及返回信号的功能。
同时MINIUSB接口良好的物理连接特性也保证了应用的稳定性。
由于编码器为NPN集电极输出,所以需要在信号线上提供一定的上拉电阻。
所使用的编码器为远征牌,200线(转一圈输入200个脉冲),AB 两相,最大转速200rad/s,输入电压可以为5到18V(编码器内部带有稳压芯片)。
正交编码器接口详述的所有通用定时器及高级定时器都集成了正交编码器接口。
定时器的两个输入和直接与增量式正交编码器接口。
当定时器设为正交编码器模式时,这两个信号的边沿作为计数器的时钟。
而正交编码器的第三个输出(机械零位),可连接外部中断口来触发定时器的计数器复位。
stm32f1 标准例程一、概述STM32F1是一款广泛应用于嵌入式系统开发的32位ARMCortex-M 内核微控制器。
标准例程是用于帮助初学者快速了解和掌握STM32F1的基本操作和功能的应用程序。
本例程旨在通过一系列简单的示例程序,帮助读者熟悉STM32F1的基本开发流程和常用功能。
二、开发环境设置1.安装KeiluVision开发环境,并配置相应的编译器和调试器。
2.下载STM32F1的固件库,并将其添加到KeiluVision项目中。
三、标准例程内容以下是一个简单的STM32F1标准例程程序,包含了LED灯的控制、按键输入、串口通信等功能:```c#include"stm32f10x.h"#include"stm32f1_system.h"#include"stm32f1_gpio.h"#include"stm32f1_rcc.h"#include"stm32f1_usart.h"#include"stm32f1_dma.h"//初始化GPIO和USART外设voidinit_peripherals(){GPIO_InitTypeDefGPIO_InitStruct;USART_InitTypeDefUSART_InitStruct;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Perip h_USART2,ENABLE);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;//设置LED 灯和按键引脚为输出GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);USART_ART_BaudRate=9600;//设置串口波特率为9600USART_ART_WordLength=USART_WordLength_8b;//8位数据位USART_ART_StopBits=USART_StopBits_1;//1个停止位USART_ART_Parity=USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl=USART_Hardware FlowControl_None;//不使用硬件流控制USART_Init(USART2,&USART_InitStruct);}//按键中断处理函数voidUSART2_IRQHandler(){if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET){//接收到数据中断//处理接收到的数据,例如通过按键值来判断用户操作switch(KEYB){caseKEYB_POWER://开关机键值定义,这里仅为示例if(ONOFF==0){//机器已开机状态检查ONOFF=1;//开启电源开关,机器开机启动LED灯闪烁}else{//机器已关机状态检查,关闭电源开关并关闭LED灯ONOFF=0;}break;default:break;//其他按键暂不处理,保留为默认值不发送回设备}USART_SendData(USART2,KEYB);//将按键值发送回设备,这里仅为示例发送一个按键值给设备进行反馈操作结果KEYB=KEYB&KEYB+1;//重置按键值计数器,保留不产生误触按按键的行为需求。
标题:STM32编码器4倍频原理目录1. STM32编码器接口简介2. 编码器的工作原理和应用3. STM32编码器4倍频原理4. STM32编码器4倍频的优势5. 结论1. STM32编码器接口简介STM32系列微控制器是由意法半导体推出的一类MCU产品,具有丰富的外设和强大的性能。
其中,编码器接口是STM32微控制器常见的外设之一,主要用于连接编码器传感器,实现位置或速度的测量和控制。
STM32编码器接口通常包含两个通道(A相和B相)和一个索引信号(Z 相),用于测量编码器的旋转角度和速度。
STM32还提供了丰富的编码器接口工作模式和配置选项,以满足不同应用场景的需求。
2. 编码器的工作原理和应用编码器是一种用于测量旋转角度和速度的传感器,常见的编码器类型包括光电编码器和磁性编码器。
编码器的工作原理是利用编码盘上的光、电、磁信号来生成对应的数字脉冲输出,从而实现旋转角度和速度的测量。
在工业控制和自动化领域,编码器被广泛应用于电机位置控制、轴位移测量和运动控制等领域。
特别是在闭环控制系统中,编码器可以提供准确的位置反馈信号,从而实现精准的位置控制和运动控制。
3. STM32编码器4倍频原理在STM32微控制器中,编码器接口提供了多种工作模式和编码器计数模式。
其中,4倍频模式是一种常用的编码器计数模式,可以有效提高编码器的分辨率和测量精度。
在4倍频模式下,编码器接口可以将编码器信号的脉冲数量扩大4倍输出给微控制器的定时器,从而实现对编码器脉冲数量的有效倍增。
通过4倍频模式,可以在不改变编码器硬件结构的情况下,有效提高编码器的分辨率和灵敏度。
4. STM32编码器4倍频的优势使用STM32编码器4倍频模式具有以下优势:a. 提高分辨率:通过4倍频模式,可以将编码器信号的脉冲数量扩大4倍输出给微控制器的定时器,从而提高了编码器的分辨率和测量精度。
b. 提高灵敏度:4倍频模式可以将编码器的脉冲信号有效放大,从而提高了编码器的灵敏度和反馈精度,在闭环控制系统中具有重要作用c. 保持硬件兼容性:使用4倍频模式可以在不改变编码器硬件结构的情况下,有效提高了编码器的性能,同时保持了硬件的兼容性和稳定性。
STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。
如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。
通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。
下面是我调试OK的代码:void Encoder_Configration(void){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;//PC6 A相PC7 B相GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 |GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Prescaler =0x0; // No prescalingTIM_TimeBaseStructure.TIM_Period =10000;TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;TIM_TimeBaseInit(TIM8,&TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM8,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter =6;//ICx_FILTER;TIM_ICInit(TIM8,&TIM_ICInitStructure);// Clear all pending interruptsTIM_ClearFlag(TIM8, TIM_FLAG_Update);TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);//Reset counterTIM2->CNT = 0;TIM_Cmd(TIM8, ENABLE);}n_Counter = TIM_GetCounter(TIM8);Diled_Disp_Num((float)n_Counter);另外一个值得注意的问题是,STM32的定时器是16位的,意思是只能计数到65535,有两种方法,一是采用链式的方式用两个定时器将16位扩展为32位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
如图,STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。
如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。
通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。
下面是我调试OK的代码:void Encoder_Configration(void){GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;//PC6 A相PC7 B相GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);/* Enable the TIM3 Update Interrupt *//*NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRI ORITY;NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);*//* Timer configuration in Encoder mode */TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescalingTIM_TimeBaseStructure.TIM_Period = 10000;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;TIM_ICInit(TIM8, &TIM_ICInitStructure);// Clear all pending interruptsTIM_ClearFlag(TIM8, TIM_FLAG_Update);TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);//Reset counterTIM2->CNT = 0;TIM_Cmd(TIM8, ENABLE);}n_Counter = TIM_GetCounter(TIM8);Diled_Disp_Num((float)n_Counter);另外一个值得注意的问题是,STM32 的定时器是16位的,意思是只能计数到65535,有两种方法,一是采用链式的方式用两个定时器将16位扩展为32位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
文章标题:深入探讨STM32编码器程序中Z相的处理方法在嵌入式系统开发中,STM32系列微控制器广泛应用于各种领域,其强大的性能和丰富的外设资源使得开发人员可以更加灵活和高效地进行开发。
而编码器作为一种常见的位置传感器,被广泛应用于电机控制、机械臂、机床等领域。
在STM32编码器程序中,Z相的处理显得尤为重要,本文将针对这一主题进行深入探讨。
1. 简介从编码器的基本结构出发,我们可以看到编码器通常由A相、B相和Z相组成。
其中A相和B相用于检测转动角度和方向,而Z相则用于检测转动的零点位置。
在实际应用中,Z相的处理对于确保系统的稳定性和精准性至关重要。
2. Z相的读取在STM32编码器程序中,Z相的读取可以通过外部中断的方式来实现。
当Z相的信号发生上升沿或下降沿时,通过外部中断引脚将引发中断,从而执行相应的处理函数。
在处理函数中,可以进行位置计数的清零、角度标定等操作,以确保系统在启动时能够准确获取零点位置。
3. 程序设计针对Z相信号的处理,我们需要设计相应的程序逻辑来确保系统的稳定性和精准性。
在程序设计中,我们可以采用状态机的方式来处理Z相信号,通过状态机的切换来实现位置标定、零点校准等功能。
还应该考虑到Z相信号可能存在的抖动和干扰,采取相应的滤波和消抖措施来确保信号的稳定性和可靠性。
4. 总结STM32编码器程序中Z相的处理方法对于系统的性能和稳定性具有重要影响。
通过合理的硬件设计和程序实现,我们可以确保系统能够准确地获取零点位置,并实现精准的位置控制。
在实际开发中,开发人员需要综合考虑硬件和软件两方面的因素,以便更好地实现Z相的处理和应用。
个人观点与理解对于STM32编码器程序中Z相的处理,我认为关键在于综合考虑硬件和软件两方面的因素。
在硬件设计中,需要充分考虑Z相信号的稳定性和可靠性,选择合适的电路方案和滤波措施来确保信号质量。
而在软件实现中,需要设计合理的程序逻辑和状态机,以确保系统能够准确获取零点位置,并实现精准的控制。
STM32 16位定时器对正交编码器计数的方法(附检测输入脉冲的方法)发布时间:
2009-10-04 14:29:11
今天决定在END开博,之前没有工作记录的习惯,从今天起在这里记录下自己工作时的点滴经验,以供日后参考以及与网络朋友交流。
第一篇文章先简要描述下STM32 定时器对正交编码器进行计数控制的方法。
如图,STM32的每个TIMER都有正交编码器输入接口,TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。
如下图,编码器使用了A,B两相信号,但是我只需要对TI1信号进行计数(第一行),我也是刚发现了这个错误,原来对两个信号都计数,导致码盘转一周得到不止100个脉冲(100线的光电码盘)。
通过STM32的编码器模块比较两想的电平信号就可以很容易地计算出编码器的运行情况了。
下面是我调试OK的代码:
void Encoder_Configration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
//PC6 A相PC7 B相
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
/* Enable the TIM3 Update Interrupt */
/*NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRI ORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);*/
/* Timer configuration in Encoder mode */
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
TIM_TimeBaseStructure.TIM_Period = 10000;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;
TIM_ICInit(TIM8, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(TIM8, TIM_FLAG_Update);
TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
//Reset counter
TIM2->CNT = 0;
TIM_Cmd(TIM8, ENABLE);
}
n_Counter = TIM_GetCounter(TIM8);
Diled_Disp_Num((float)n_Counter);
另外一个值得注意的问题是,STM32 的定时器是16位的,意思是只能计数到65535,有两种方法,一是采用链式的方式用两个定时器将16位扩展为32位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
比如编码器是400线的,将ARR寄存器设置为400,每溢出中断一次就代表电机转了一圈,以此类推。
另外,关于输入脉冲的检测,其实是类似的,只不过在STM32内部是专门用了一个外部触发模块来实现的,如图一中紫色框的标注,编码器模块应该是在这个模块上的升级,下面是配置代码:
void TIM3_ETR_GetDropCounts_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//test PA0 TIM8_ETR
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x00;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Time base configuration
TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonI nverted, 0);
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE);
}。