/******************** (C) COPYRIGHT 2007 STMicroelectronics ******************** * File Name : stm32f10x_encoder.c * Author : IMS Systems Lab * Date First Issued : 21/11/07
* Description : This file contains the software implementation for the * encoder unit
********************************************************************************
* History:
* 21/11/07 v1.0
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/ //#include
/* Private variables ---------------------------------------------------------*/
s16 hPrevious_angle, hSpeed_Buffer[SPEED_BUFFER_SIZE], hRot_Speed; //static s16 hPrevious_angle, hSpeed_Buffer[SPEED_BUFFER_SIZE]; static u8 bSpeed_Buffer_Index = 0;
static volatile u16 hEncoder_Timer_Overflow;
#define TRUE 1 #define FALSE 0
static unsigned char bIs_First_Measurement = TRUE;
/*******************************************************************************
* Function Name : ENC_Init
* Description : General Purpose Timer x set-up for encoder speed/position * sensors * Input : None
* Output : None * Return : None
*******************************************************************************/
void ENC_Init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure;
/* Encoder unit connected to TIM3, 4X mode */ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock source enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable GPIOA, clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_StructInit(&GPIO_InitStructure); /* Configure PA.06,07 as encoder input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable the TIM3 Update Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
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 */ TIM_DeInit(ENCODER_TIMER);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling //72M捕获? TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;
TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update); TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE); //Reset counter
TIM2->CNT = COUNTER_RESET;
ENC_Clear_Speed_Buffer();
TIM_Cmd(ENCODER_TIMER, ENABLE); }
/*******************************************************************************
* Function Name : ENC_Get_Electrical_Angle
* Description : Returns the absolute electrical Rotor angle * Input : None * Output : None
* Return : Rotor electrical angle: 0 -> 0 degrees,
* S16_MAX-> 180 degrees,
* S16_MIN-> -180 degrees *******************************************************************************/
s16 ENC_Get_Electrical_Angle(void) {
s32 temp;
temp = (s32)(TIM_GetCounter(ENCODER_TIMER)) * (s32)(4294967295 / (4*ENCODER_PPR)); return((s16)(temp/65536)); // s16 result }
/*******************************************************************************
* Function Name : ENC_Clear_Speed_Buffer
* Description : Clear speed buffer used for average speed calculation * Input : None * Output : None * Return : None
*******************************************************************************/
void ENC_Clear_Speed_Buffer(void) {
u32 i;
for (i=0;i hSpeed_Buffer[i] = 0; } bIs_First_Measurement = TRUE; } /******************************************************************************* * Function Name : ENC_Calc_Rot_Speed * Description : Compute return latest speed measurement * Input : None * Output : s16 * Return : Return the speed in 0.1 Hz resolution. *******************************************************************************/ s16 ENC_Calc_Rot_Speed(void) { s32 wDelta_angle; u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two; u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two; signed long long temp; s16 haux; if (!bIs_First_Measurement) { // 1st reading of overflow counter hEnc_Timer_Overflow_sample_one = hEncoder_Timer_Overflow; // 1st reading of encoder timer counter hCurrent_angle_sample_one = ENCODER_TIMER->CNT; // 2nd reading of overflow counter hEnc_Timer_Overflow_sample_two = hEncoder_Timer_Overflow; // 2nd reading of encoder timer counter hCurrent_angle_sample_two = ENCODER_TIMER->CNT; // Reset hEncoder_Timer_Overflow and read the counter value for the next // measurement hEncoder_Timer_Overflow = 0; haux = ENCODER_TIMER->CNT; if (hEncoder_Timer_Overflow != 0) {

