391 lines
13 KiB
C++
Executable File
391 lines
13 KiB
C++
Executable File
#include <Stm32F4_Encoder.h>
|
|
|
|
/*
|
|
Stm32F4_Encoder.cpp
|
|
Created on: Nov 20, 2020
|
|
Author: GoktugH.
|
|
*/
|
|
// TIM2, TIM3, TIM4, TIM8
|
|
Encoder::Encoder()
|
|
{
|
|
int unit;
|
|
}
|
|
|
|
// void Encoder::SetCount(enum EncTimer enc, int64_t Counter)
|
|
void Encoder::SetCount(int64_t Counter)
|
|
{
|
|
tim_base->CNT = Counter;
|
|
}
|
|
// uint16_t Encoder::GetCount(enum EncTimer enc)
|
|
uint16_t Encoder::GetCount()
|
|
{
|
|
return tim_base->CNT;
|
|
}
|
|
|
|
void GpioConfigPortA(GPIO_TypeDef *GPIOx)
|
|
{
|
|
|
|
uint32_t pinpos = 0x00, pos = 0x00, currentpin = 0x00;
|
|
|
|
/* ------------------------- Configure the port pins ---------------- */
|
|
/*-- GPIO Mode Configuration --*/
|
|
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
|
|
{
|
|
pos = ((uint32_t)0x01) << pinpos;
|
|
/* Get the port pins position */
|
|
currentpin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_6 | GPIO_Pin_7) & pos;
|
|
|
|
if (currentpin == pos)
|
|
{
|
|
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
|
|
GPIOx->MODER |= (((uint32_t)GPIO_Mode_AF) << (pinpos * 2));
|
|
|
|
if ((GPIO_Mode_AF == GPIO_Mode_OUT) || (GPIO_Mode_AF == GPIO_Mode_AF))
|
|
{
|
|
/* Check Speed mode parameters */
|
|
|
|
/* Speed mode configuration */
|
|
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
|
|
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_Speed_50MHz) << (pinpos * 2));
|
|
|
|
/* Check Output mode parameters */
|
|
|
|
/* Output mode configuration*/
|
|
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));
|
|
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_OType_PP) << ((uint16_t)pinpos));
|
|
}
|
|
|
|
/* Pull-up Pull down resistor configuration*/
|
|
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
|
|
GPIOx->PUPDR |= (((uint32_t)GPIO_PuPd_NOPULL) << (pinpos * 2));
|
|
}
|
|
}
|
|
}
|
|
|
|
void GpioConfigPortC(GPIO_TypeDef *GPIOx)
|
|
{
|
|
|
|
uint32_t pinpos = 0x00, pos = 0x00, currentpin = 0x00;
|
|
|
|
/* ------------------------- Configure the port pins ---------------- */
|
|
/*-- GPIO Mode Configuration --*/
|
|
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
|
|
{
|
|
pos = ((uint32_t)0x01) << pinpos;
|
|
/* Get the port pins position */
|
|
currentpin = (GPIO_Pin_6 | GPIO_Pin_7) & pos;
|
|
|
|
if (currentpin == pos)
|
|
{
|
|
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
|
|
GPIOx->MODER |= (((uint32_t)GPIO_Mode_AF) << (pinpos * 2));
|
|
|
|
if ((GPIO_Mode_AF == GPIO_Mode_OUT) || (GPIO_Mode_AF == GPIO_Mode_AF))
|
|
{
|
|
/* Check Speed mode parameters */
|
|
|
|
/* Speed mode configuration */
|
|
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
|
|
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_Speed_50MHz) << (pinpos * 2));
|
|
|
|
/* Check Output mode parameters */
|
|
|
|
/* Output mode configuration*/
|
|
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));
|
|
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_OType_PP) << ((uint16_t)pinpos));
|
|
}
|
|
|
|
/* Pull-up Pull down resistor configuration*/
|
|
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
|
|
GPIOx->PUPDR |= (((uint32_t)GPIO_PuPd_NOPULL) << (pinpos * 2));
|
|
}
|
|
}
|
|
}
|
|
|
|
void GpioConfigPortD(GPIO_TypeDef *GPIOx)
|
|
{
|
|
|
|
uint32_t pinpos = 0x00, pos = 0x00, currentpin = 0x00;
|
|
|
|
/* ------------------------- Configure the port pins ---------------- */
|
|
/*-- GPIO Mode Configuration --*/
|
|
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
|
|
{
|
|
pos = ((uint32_t)0x01) << pinpos;
|
|
/* Get the port pins position */
|
|
currentpin = (GPIO_Pin_12 | GPIO_Pin_13) & pos;
|
|
|
|
if (currentpin == pos)
|
|
{
|
|
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
|
|
GPIOx->MODER |= (((uint32_t)GPIO_Mode_AF) << (pinpos * 2));
|
|
|
|
if ((GPIO_Mode_AF == GPIO_Mode_OUT) || (GPIO_Mode_AF == GPIO_Mode_AF))
|
|
{
|
|
/* Check Speed mode parameters */
|
|
|
|
/* Speed mode configuration */
|
|
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
|
|
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_Speed_50MHz) << (pinpos * 2));
|
|
|
|
/* Check Output mode parameters */
|
|
|
|
/* Output mode configuration*/
|
|
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));
|
|
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_OType_PP) << ((uint16_t)pinpos));
|
|
}
|
|
|
|
/* Pull-up Pull down resistor configuration*/
|
|
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
|
|
GPIOx->PUPDR |= (((uint32_t)GPIO_PuPd_NOPULL) << (pinpos * 2));
|
|
}
|
|
}
|
|
}
|
|
|
|
void TIM_EncoderInterConfig(TIM_TypeDef *TIMx, uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
|
|
{
|
|
|
|
uint16_t tmpsmcr = 0;
|
|
uint16_t tmpccmr1 = 0;
|
|
uint16_t tmpccer = 0;
|
|
|
|
/* Get the TIMx SMCR register value */
|
|
tmpsmcr = TIMx->SMCR;
|
|
|
|
/* Get the TIMx CCMR1 register value */
|
|
tmpccmr1 = TIMx->CCMR1;
|
|
|
|
/* Get the TIMx CCER register value */
|
|
tmpccer = TIMx->CCER;
|
|
|
|
/* Set the encoder Mode */
|
|
tmpsmcr &= (uint16_t)~TIM_SMCR_SMS;
|
|
tmpsmcr |= TIM_EncoderMode;
|
|
|
|
/* Select the Capture Compare 1 and the Capture Compare 2 as input */
|
|
tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S);
|
|
tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
|
|
|
|
/* Set the TI1 and the TI2 Polarities */
|
|
tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P);
|
|
tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
|
|
|
|
/* Write to TIMx SMCR */
|
|
TIMx->SMCR = tmpsmcr;
|
|
|
|
/* Write to TIMx CCMR1 */
|
|
TIMx->CCMR1 = tmpccmr1;
|
|
|
|
/* Write to TIMx CCER */
|
|
TIMx->CCER = tmpccer;
|
|
}
|
|
|
|
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
|
|
{
|
|
/* Set the default configuration */
|
|
TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF;
|
|
TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000;
|
|
TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
|
|
TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up;
|
|
TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000;
|
|
}
|
|
|
|
void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
|
|
{
|
|
uint16_t tmpcr1 = 0;
|
|
|
|
tmpcr1 = TIMx->CR1;
|
|
|
|
if ((TIMx == TIM1) || (TIMx == TIM8) ||
|
|
(TIMx == TIM2) || (TIMx == TIM3) ||
|
|
(TIMx == TIM4) || (TIMx == TIM5))
|
|
{
|
|
/* Select the Counter Mode */
|
|
tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS));
|
|
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
|
|
}
|
|
|
|
if ((TIMx != TIM6) && (TIMx != TIM7))
|
|
{
|
|
/* Set the clock division */
|
|
tmpcr1 &= (uint16_t)(~TIM_CR1_CKD);
|
|
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
|
|
}
|
|
|
|
TIMx->CR1 = tmpcr1;
|
|
|
|
/* Set the Autoreload value */
|
|
TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period;
|
|
|
|
/* Set the Prescaler value */
|
|
TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
|
|
|
|
if ((TIMx == TIM1) || (TIMx == TIM8))
|
|
{
|
|
/* Set the Repetition Counter value */
|
|
TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
|
|
}
|
|
|
|
/* Generate an update event to reload the Prescaler
|
|
and the repetition counter(only for TIM1 and TIM8) value immediatly */
|
|
TIMx->EGR = TIM_PSCReloadMode_Immediate;
|
|
}
|
|
|
|
TIM_TimeBaseInitTypeDef TIMER_InitStructure;
|
|
TIM_TimeBaseInitTypeDef TIMER_InitStructureE;
|
|
TIM_TimeBaseInitTypeDef TIMER_InitStructureEE;
|
|
TIM_TimeBaseInitTypeDef TIMER_InitStructureEEG;
|
|
|
|
void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState)
|
|
{
|
|
|
|
if (NewState != DISABLE)
|
|
{
|
|
/* Enable the TIM Counter */
|
|
TIMx->CR1 |= TIM_CR1_CEN;
|
|
}
|
|
else
|
|
{
|
|
/* Disable the TIM Counter */
|
|
TIMx->CR1 &= (uint16_t)~TIM_CR1_CEN;
|
|
}
|
|
}
|
|
void GPIO_PinAF(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
|
|
|
|
{
|
|
|
|
uint32_t temp = 0x00;
|
|
uint32_t temp_2 = 0x00;
|
|
|
|
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
|
|
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
|
|
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
|
|
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
|
|
}
|
|
|
|
void encoder_config()
|
|
{
|
|
RCC->AHB1ENR |= 0x1; // GPIOA
|
|
RCC->AHB1ENR |= 0x4; // GPIOC
|
|
RCC->AHB1ENR |= 0x8; // GPIOD
|
|
RCC->AHB1ENR |= 0x10; // GPIOE
|
|
|
|
RCC->APB1ENR |= 0x20000000; // ENABLE DAC
|
|
// RCC->APB2ENR |= 0x00000002; // APB2 TIM8
|
|
RCC->APB1ENR |= 0x00000004; // APB1 TIM4
|
|
RCC->APB1ENR |= 0x00000001; // APB1 TIM2
|
|
// RCC->APB1ENR |= 0x00000002; // APB1 TIM3
|
|
|
|
GpioConfigPortA(GPIOA);
|
|
// GpioConfigPortC(GPIOC);
|
|
GpioConfigPortD(GPIOD);
|
|
#if 0 // Skipping since TIM8 is step generator and TIM3, chan4 is smae as TIM8, chan4
|
|
GPIO_PinAF(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);
|
|
GPIO_PinAF(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);
|
|
|
|
GPIO_PinAF(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);
|
|
GPIO_PinAF(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8);
|
|
#endif
|
|
GPIO_PinAF(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
|
|
GPIO_PinAF(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
|
|
|
|
GPIO_PinAF(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
|
|
GPIO_PinAF(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
|
|
#if 0 // Skipping since I use TIM8 as stepper generator
|
|
TIM_EncoderInterConfig(TIM8, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Falling);
|
|
TIMER_InitStructure.TIM_Period = 65535;
|
|
TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up | TIM_CounterMode_Down;
|
|
TIM_TimeBaseInit(TIM8, &TIMER_InitStructure);
|
|
TIM_TimeBaseStructInit(&TIMER_InitStructure);
|
|
TIM_Cmd(TIM8, ENABLE);
|
|
TIM8->CNT = 0;
|
|
#endif
|
|
TIM_EncoderInterConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Falling);
|
|
TIMER_InitStructureE.TIM_Period = 65535;
|
|
TIMER_InitStructureE.TIM_CounterMode = TIM_CounterMode_Up | TIM_CounterMode_Down;
|
|
TIM_TimeBaseInit(TIM4, &TIMER_InitStructureE);
|
|
TIM_TimeBaseStructInit(&TIMER_InitStructureE);
|
|
TIM_Cmd(TIM4, ENABLE);
|
|
TIM4->CNT = 0;
|
|
|
|
TIM_EncoderInterConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Falling);
|
|
TIMER_InitStructureEE.TIM_Period = 65535;
|
|
TIMER_InitStructureEE.TIM_CounterMode = TIM_CounterMode_Up | TIM_CounterMode_Down;
|
|
TIM_TimeBaseInit(TIM2, &TIMER_InitStructureEE);
|
|
TIM_TimeBaseStructInit(&TIMER_InitStructureEE);
|
|
TIM_Cmd(TIM2, ENABLE);
|
|
|
|
TIM2->CNT = 0;
|
|
#if 0
|
|
TIM_EncoderInterConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Falling);
|
|
TIMER_InitStructureEEG.TIM_Period = 65535;
|
|
TIMER_InitStructureEEG.TIM_CounterMode = TIM_CounterMode_Up | TIM_CounterMode_Down;
|
|
TIM_TimeBaseInit(TIM3, &TIMER_InitStructureEEG);
|
|
TIM_TimeBaseStructInit(&TIMER_InitStructureEEG);
|
|
TIM_Cmd(TIM3, ENABLE);
|
|
|
|
TIM3->CNT = 0;
|
|
#endif
|
|
}
|
|
|
|
void encoder2_config()
|
|
{
|
|
#if 0
|
|
#include "mbed.h"
|
|
#include "stm32f4xx.h"
|
|
#include "stm32f4xx_hal_tim_ex.h"
|
|
|
|
TIM_HandleTypeDef timer;
|
|
TIM_Encoder_InitTypeDef encoder;
|
|
|
|
// direction to PA_9 -- step pulse to PA_8
|
|
|
|
int main()
|
|
{
|
|
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
__TIM1_CLK_ENABLE();
|
|
__GPIOA_CLK_ENABLE();
|
|
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
|
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
|
|
|
timer.Instance = TIM1;
|
|
timer.Init.Period = 0xffff;
|
|
timer.Init.Prescaler = 0;
|
|
timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
|
timer.Init.CounterMode = TIM_COUNTERMODE_UP;
|
|
|
|
encoder.EncoderMode = TIM_ENCODERMODE_TI12;
|
|
encoder.IC1Filter = 0x0f;
|
|
encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
|
|
encoder.IC1Prescaler = TIM_ICPSC_DIV4;
|
|
encoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;
|
|
|
|
encoder.IC2Filter = 0x0f;
|
|
encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
|
|
encoder.IC2Prescaler = TIM_ICPSC_DIV4;
|
|
encoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;
|
|
|
|
HAL_TIM_Encoder_Init(&timer, &encoder);
|
|
HAL_TIM_Encoder_Start(&timer,TIM_CHANNEL_1);
|
|
|
|
|
|
TIM1->EGR = 1; // Generate an update event
|
|
TIM1->CR1 = 1; // Enable the counter
|
|
|
|
|
|
while (1) {
|
|
int16_t count1;
|
|
count1=TIM1->CNT;
|
|
|
|
printf("%d\r\n", count1);
|
|
wait(1.0);
|
|
|
|
};
|
|
}
|
|
#endif
|
|
} |