基于STM32的正交编码器接口应用含源程序
- 格式:doc
- 大小:166.00 KB
- 文档页数:7
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位,还有一种简单的方法就是开启定时器的溢出中断,每中断一次就代表编码器运转了特定的角度。
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差分编码器编程实例
当使用 STM32 微控制器编程时,可以通过外部差分编码器来实现位置或速度的测量。
下面是一个简单的 STM32 差分编码器编程实例,以帮助您了解如何进行编程:
1. 首先,确保您已经正确连接了差分编码器到 STM32 微控制器的外部引脚。
通常,差分编码器会有两个输出信号通道(通常称为 A 和 B 通道),以及一个用于指示方向的 Z 通道。
2. 在 STM32 的开发环境中,创建一个新的工程,并选择适当的 STM32 型号。
3. 在工程中,将差分编码器的 A 和 B 通道连接到 STM32 的两个外部中断引脚(例如 EXTI0 和 EXTI1)。
4. 在工程中,将差分编码器的 Z 通道连接到 STM32 的另一个外部中断引脚(例如 EXTI2)。
5. 在代码中,启用外部中断功能,并配置外部中断触发方式为上升沿或下降沿触发。
6. 在外部中断的中断处理函数中,编写代码来处理差分编码器的输出信号变化。
根据差分编码器的工作原理,每当 A 或 B 通道的信号变化时,都会触发外部中断。
您可以在中断处理函数中根据A 和 B 通道的状态变化来判断编码器的旋转方向,并相应地更新位置或速度的计数器。
7. 如果需要使用 Z 通道来确定编码器的起始位置,您可以在Z 通道的中断处理函数中重置位置或速度的计数器。
8. 在主程序中,您可以使用位置或速度的计数器值来执行相应的操作,例如控制电机或执行其他任务。
需要注意的是,具体的差分编码器编程实例可能会根据使用的STM32 型号和开发环境有所不同。
因此,您可以参考 STM32 的官方文档和相关的编程手册来获取更详细的信息和示例代码。
Abstract --- The quadrature encoder which is very popular in the motor servo control application, known as a 2-channel incremental encoder, converts linear displacementinto a pulse signal. By monitoring the number of pulses and the relative phase of thetwo signals you can track the position, the direction of rotation and speed. In ddition,a third channel, or index signal, can be used to reset the position counter.STM3210x which is the MCU based on ARM latest core - Cortex-M3, integrates thequadrature encoder interface. Accordingly STM3210x can handles the encodersignal without any CPU overhead which it is possible for CPU to focus on the vectorcontrol.在马达控制类应用中, 正交编码器可以反馈马达的转子位置及转速信号。
TM32F10x 系列MCU集成了正交编码器接口,增量编码器可与MCU直接连接而无需外部接口电路。
该应用笔记详细介绍了STM32F10x与正交编码器的接口,并附有相应的例程,使用户可以很快地掌握其使用方法。
1正交编码器原理正交编码器实际上就是光电编码器,分为增量式和绝对式,较其它检测元件有直接输出数字量信号,惯量低,低噪声,高精度,高分辨率,制作简便,成本低等优点。
stm32串口奇校验原理及程序一、STM32串口通信基本概念STM32串口通信是指通过串行通信接口进行数据传输的一种通信方式。
在串口通信中,主要有以下几个重要参数:波特率、数据位、停止位和奇偶校验。
这些参数决定了串口通信的基本特性,适用于各种串口通信场景。
二、奇校验原理及其应用奇校验是一种通过检测数据传输过程中校验位(奇校验为1,偶校验为0)的值,以判断数据是否发生传输错误的校验方法。
在STM32串口通信中,奇校验的应用能有效提高数据传输的可靠性。
奇校验原理:在数据位中,1的个数为奇数时,奇校验值为0;1的个数为偶数时,奇校验值为1。
在接收端,根据校验位值与预期值(奇校验为0,偶校验为1)进行比较,若不一致,则说明数据传输过程中发生错误。
三、奇校验程序设置与解析1.设置奇校验的串口初始化结构体:```cUSART_ART_WordLength = USART_WordLength_8b;USART_ART_Parity = USART_Parity_Odd;```2.发送数据:```cMax3485SendBuf[index] = 0xfe;Max3485SendBuf[index] = 0xfe;// ...其他数据字节UART4SendLongData(Max3485SendBuf, index);```3.解析接收到的数据:```cif (UART4ReceiveData() != 0) {uint8_t receivedData = UART4ReceiveData();// 处理接收到的数据}```四、常见问题及解决方案1.接收数据时,发现数据丢失第一个字节。
解决方案:根据实际情况,调整发送和接收的数据位、停止位和波特率,确保双方设备一致。
2.发送数据时,校验位被覆盖。
解决方案:修改串口初始化结构体,将数据位长度设置为9位,以保证校验位的正确传输。
综上,掌握STM32串口通信的奇校验原理及程序设置,能有效提高数据传输的可靠性。
标题: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的正交编码器接口应用本设计应用了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(编码器内部带有稳压芯片)。
正交编码器接口详述的所有通用定时器及高级定时器都集成了正交编码器接口。
定时器的两个输入和直接与增量式正交编码器接口。
当定时器设为正交编码器模式时,这两个信号的边沿作为计数器的时钟。
而正交编码器的第三个输出(机械零位),可连接外部中断口来触发定时器的计数器复位。
定时器正交编码器接口框图图:定时器正交编码器接口功能描述选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIM1_SMCR寄存器中的SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则置SMS=011。
通过设置TIM1_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性;如果需要,还可以对输入滤波器编程。
两个输入TI1和TI2被用来作为增量编码器的接口。
参看表1,假定计数器已经启动(TIM1_CR1寄存器中的CEN=1),则TI1FP1或TI2FP2上的有效跳变作为计数器的时钟信号。
TI1FP1和TI2FP2是TI1和TI2在通过输入滤波器和极性控制后的信号;如果没有滤波和变相,则TI1FP1=TI1,TI2FP2=TI2。
根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。
依据两个输入信号的跳变顺序,计数器向上或向下计数,因此TIM1_CR1寄存器的DIR位由硬件进行相应的设置。
不管计数器是对TI1计数、对TI2计数或者同时对TI1和TI2计数。
在任一输入(TI1或者TI2)跳变时都会重新计算DIR位。
应用笔记正交编码器接口编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。
这意味着计数器只在0到TIM1_ARR寄存器中自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计数)。
所以在开始计数之前必须配置TIM1_ARR;同样,捕获器、比较器、预分频器、周期计数器、触发输出特性等仍工作如常。
编码模式和外部时钟模式2不兼容,因此不能同时操作。
在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此,它的内容始终指示着编码器的位置。
计数方向与相连的传感器旋转的方向对应。
表1列出了所有可能的可能的组合,假设TI1和TI2不同时变换。
表1:计数方向与编码器信号的关系一个外部的增量编码器直接和MCU连接不需要外部接口逻辑。
但是,一般使用比较器将编码器的差动输出转换到数字信号,这大大增加了抗噪声干扰能力。
编码器输出的第三个信号表示机械零点,可以连接到一个外部中断输入,触发一个计数器复位。
//***************************************************************************** ***********************//编码器库函数//操作环境:MDK//***************************************************************************** ***********************#include "enconder.h"//#include "LCD.h"//***************************************************************************** ***********************//正交编码器接口的初始化//***************************************************************************** ***********************void ENC_Init(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APBPeriph_ENCODER_TIMER, ENABLE);//TIM4 // ENCODER_TIMER时钟初始化RCC_APB2PeriphClockCmd(RCC_APBPeriph_ENCODER_GPIO, ENABLE); // ENCODER_GPIO 时钟初始化GPIO_StructInit(&GPIO_InitStructure); //TI1 TI2初始化GPIO_InitStructure.GPIO_Pin = ENCODER_TI1 | ENCODER_TI2; //PB6,PB7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输出GPIO_Init(ENCODER_GPIO, &GPIO_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = TIMER_IRQChannel;//TIM4_IRQn //设置ENCODER_TIMER的优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Timer configuration in Encoder mode */ //设置ENCODER_TIMER为编码器模式TIM_DeInit(ENCODER_TIMER); //ENCODER_TIMER复位TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 无分频TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; //计数器重载值4*200-1TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure); //TIM4//TIM4TIM_EncoderInterfaceConfig(ENCODER_TIMER,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //编码器接口初始化TIM_ICStructInit(&TIM_ICInitStructure);TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER; //6TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);// Clear all pending interruptsTIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);//Reset counterTIM2->CNT = COUNTER_RESET; //0TIM_Cmd(ENCODER_TIMER, ENABLE);}//***************************************************************************** ***********************// 计算马达转子相对于初始位置的角度-180至+180//***************************************************************************** ***********************void ENC_Get_Electrical_Angle(uint16_t *degree){int32_t temp;int16_t tim_count;tim_count=TIM_GetCounter(ENCODER_TIMER); //获取ENCODER_TIMER TIM4的值if(tim_count>=400) //如果超过180度,角度为负数{degree[0]='-';degree[1]=(800-tim_count)*180/(4*ENCODER_PPR/2); //整数部分temp = (int32_t)(800-tim_count) *(int32_t)(1000000/(4*ENCODER_PPR/2))*360-degree[1]*1000000;degree[2]=(unsigned char)temp; //小数部分}else //如果未超过180度,角度为正数{degree[0]='+';degree[1]=tim_count*180/(4*ENCODER_PPR/2);//整数部分temp = (int32_t)tim_count *(int32_t)(1000000/(4*ENCODER_PPR/2))*180-degree[1]*1000000;degree[2]=(unsigned char)temp; //小数部分}}。