NUCLEO-F446RE ENCODER TIMER3 Y TIMER 2 HAL AND PWM. PID PARA UN PENDULO INVERTIDO CON 2 ENCODER DE CUADRATURA
Revision 0:95f924550159, committed 2016-05-21
- Comitter:
- gereina
- Date:
- Sat May 21 04:17:35 2016 +0000
- Commit message:
- QEI_TIMER2_TIMER_3 OK; PWM MBED; PID
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/Encoder.h Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,6 @@ +#ifndef ENCODER_H +#define ENCODER_H + +void EncoderInit(TIM_Encoder_InitTypeDef * encoder, TIM_HandleTypeDef * timer, TIM_TypeDef * TIMx, uint32_t maxcount, uint32_t encmode); + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderInit.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,35 @@ +#include "mbed.h" + +void EncoderInit(TIM_Encoder_InitTypeDef * encoder, TIM_HandleTypeDef * timer, TIM_TypeDef * TIMx, uint32_t maxcount, uint32_t encmode) +{ + + timer->Instance = TIMx; + timer->Init.Period = maxcount; + timer->Init.CounterMode = TIM_COUNTERMODE_UP; + timer->Init.Prescaler = 0; + timer->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + + encoder->EncoderMode = encmode; + + 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; + + + if (HAL_TIM_Encoder_Init(timer, encoder) != HAL_OK) { + printf("Couldn't Init Encoder\r\n"); + while (1) {} + } + + if(HAL_TIM_Encoder_Start(timer,TIM_CHANNEL_1)!=HAL_OK) { + printf("Couldn't Start Encoder\r\n"); + while (1) {} + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitF0.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,37 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f0xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00088500.pdf + * Table 11 has GPIO alternate function pinout mappings. + * + * TIM1_CH1: AF2 @ PA_8 - TIM1 used as system ticker under mbed, so unavailable + * TIM1_CH2: AF2 @ PA_9 + * + * TIM3_CH1: AF1 @ PA_6, PB_4; AF0 @ PC_6* *only for F030xC devices + * TIM3_CH2: AF1 @ PA_7, PB_5; AF0 @ PC_7* + * + */ + +#ifdef TARGET_STM32F0 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM3) { //PB_4 PB_5 = Nucleo D5 D4 + __TIM3_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitF1.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,74 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f1xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00161566.pdf + * Table 5 has GPIO alternate function pinout mappings. + * + * TIM1_CH1: default PA_8, remap PE_9 + * TIM1_CH2: default PA_9, remap PE_11 + * + * TIM2_CH1: default PA_0 + * TIM2_CH2: default PA_1, remap PB_3 + * + * TIM3_CH1: default PA_6, remap PB_4, PC_6 + * TIM3_CH2: default PA_7, remap PB_5, PC_7 + * + * TIM4_CH1: default PB_6, remap PD_12 + * TIM4_CH2: default PB_7, remap PD_13 + * + * NB one of these timers will be the employed by mbed as systick, unavailable as encoder. + */ + +#ifdef TARGET_STM32F1 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8 + __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); + } + else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 + __TIM2_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } + else if (htim->Instance == TIM3) { //PA6 PA7 = Nucleo D12 D11 + __TIM3_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } + else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO PB7 + __TIM4_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitF3.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,82 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f3xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00093333.pdf + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00097745.pdf + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00133117.pdf + * Table 14 has GPIO alternate function pinout mappings. + * + * TIM1_CH1: AF2 @ PC_0, PE_9; AF6 @ PA_8 + * TIM1_CH2: AF2 @ PC_1, PE_11; AF6 @ PA_9 + * + * (TIM2_CH1: AF1 @ PA_0, PA_5, PA_15; AF2 @ PD_3) TIM2 is the mbed system ticker, so unavailable as encoder. + * (TIM2_CH2: AF1 @ PA_1, PB_3; AF2 @ PD_4) + * + * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6, PE_2 not for F302R8, OK @ F334R8 + * TIM3_CH2: AF2 @ PA_4, PA_7, PB_5, PC_7, PE_3 + * + * TIM4_CH1: AF2 @ PB_6, PD_12; AF10 @ PA_11 not for both F302R8 & F334R8 + * TIM4_CH2: AF2 @ PB_7, PD_13; AF10 @ PA_12 + * + */ + +#ifdef TARGET_STM32F3 + +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8 + __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_AF6_TIM1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } +#if 0 //TIM2 is the mbed system ticker + else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 + __TIM2_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } +#endif +#if defined TARGET_STM32F334R8 + else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4 + __TIM3_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +#endif +#if 0 + else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7 + __TIM4_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +#endif +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitF4.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,102 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f4xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00102166.pdf + * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00141306.pdf + * + * TIM1_CH1: AF1 @ PA_8, PE_9 + * TIM1_CH2: AF1 @ PA_9, PE_11 + * + * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PB_8* *F446 only + * TIM2_CH2: AF1 @ PA_1, PB_3, PB_9* *F446 only + * + * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6 + * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7 + * + * TIM4_CH1: AF2 @ PB_6, PD_12 + * TIM4_CH2: AF2 @ PB_7, PD_13 + * + * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable + * TIM5_CH2: AF2 @ PA_1* + * + * + * Agrego el TIMER 8 tambien funciona + * TIM8_CH1: AF3 @ PC_6 + * TIM8_CH2: AF3 @ PC_7 + * + * + * + * + */ + +#ifdef TARGET_STM32F4 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8 + __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); + } + else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 //USANDO ALTERNO PB8 Y PB 9 para el pololulu funcione + __TIM2_CLK_ENABLE(); + __GPIOB_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_TIM2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4 + __TIM3_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7 + __TIM4_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + + + else if (htim->Instance == TIM8) { // PC7 PC8 = D9 PC6 + __TIM8_CLK_ENABLE(); + __GPIOC_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + } + + + + + + +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitL0.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,28 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f4xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + */ + +#ifdef TARGET_STM32L0 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 + __TIM2_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitL1.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,63 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32l4xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00098321.pdf + * Table 9 has GPIO alternate function pinout mappings. + * + * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PE_9 + * TIM2_CH2: AF1 @ PA_1, PB_3, PE_10 + * + * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6, PE_3 + * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7, PE_4 + * + * TIM4_CH1: AF2 @ PB_6, PD_12 + * TIM4_CH2: AF2 @ PB_7, PD_13 + * + * TIM5_CH1: AF2 @ PA_0* *TIM5 used by mbed system ticker so unavailable + * TIM5_CH2: AF2 @ PA_1* + * + */ + +#ifdef TARGET_STM32L1 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 + __TIM2_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } + else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4 + __TIM3_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7 + __TIM4_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Encoder/EncoderMspInitL4.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,86 @@ +#include "mbed.h" +/* + * HAL_TIM_Encoder_MspInit() + * Overrides the __weak function stub in stm32f4xx_hal_tim.h + * + * Edit the below for your preferred pin wiring & pullup/down + * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs. + * Encoder A&B outputs connected directly to GPIOs. + * + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00108832.pdf + * Table 15 has GPIOx AFx pinouts + * + * TIM1_CH1: AF1 @ PA8, PE9 + * TIM1_CH2: AF1 @ PA9, PE11 + * + * TIM2_CH1: AF1 @ PA0, PA5, PA15 + * TIM2_CH2: AF1 @ PA1, PB3 + * + * TIM3_CH1: AF2 @ PA6, PB4, PC6, PE3 + * TIM3_CH2: AF2 @ PA7, PB5, PC7, PE4 + * + * TIM4_CH1: AF2 @ PB6, PD12 + * TIM4_CH2: AF2 @ PB7, PD13 + * + * TIM5_CH1: AF2 @ PA0, PF6 + * TIM5_CH2: AF2 @ PA1, PF7 + * + */ + +#ifdef TARGET_STM32L4 +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8 + __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); + } + else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1 + __TIM2_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } + else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4 + __TIM3_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7 + __TIM4_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } + else if (htim->Instance == TIM5) { // here for completeness, mbed sytem timer uses this + __TIM5_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM5; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + } +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,564 @@ +/*PROYECTO DEL PENDULO INVERTIDO + * TARJETA= NUCLEO STM32F446 + ENCODER EJE X PB_8 CH1 PB_9 CH2 + ENCODER PENDULO PB_4 PB_5 + + FIN DE CARRERA MOTOR IZQ = A1 + FIN DERECHA DER = A0 + + POLOLULU + + nD2 = D6 + M1DIR=D7 + M1PWM= D11 (TIMER 1) + NsF=D12 + GND=D13 + VCC=VCC + */ + + + +/*------------- THANKS DAVID LOWE FOR YOUR HELP-Your API/HAL use full --------------------------------------- + * Using STM32's counter peripherals to interface rotary encoders. + * Encoders are supported on F4xx's TIM1,2,3,4,5. TIM2 & TIM5 have 32bit count, others 16bit. + * Beware mbed uses TIM5 for system timer, SPI needs TIM1, others used for PWM. + * Check your platform's PeripheralPins.c & PeripheralNames.h if you need both PWM & encoders. + * + * Edit HAL_TIM_Encoder_MspInitFx.cpp to suit your mcu & board's available pinouts & pullups/downs. + * + * Thanks to: + * http://petoknm.wordpress.com/2015/01/05/rotary-encoder-and-stm32/ + * + * References: + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00122015.pdf + * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00096844.pdf + * http://www.st.com/web/en/resource/technical/document/application_note/DM00042534.pdf + * http://www.st.com/web/en/resource/technical/document/datasheet/DM00102166.pdf + * + * David Lowe Jan 2015 + * + + *Se complementa con el Timer 8 en la tarjeta nucleo + *Efectivamente el Timer 5 no se debe usar. + *Se Ajustaron los pines para la tarjeta para usar otros para los PWM + + */ + +#include "mbed.h" +#include "Encoder.h" + + +/****************************ENCODER INICIALIZACION *************************/ +//STM mbed bug: these macros are MISSING from stm32f3xx_hal_tim.h +#ifdef TARGET_STM32F3 +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR)) +#endif + +TIM_Encoder_InitTypeDef encoder2, encoder3, encoder4,encoder5, encoder8; +TIM_HandleTypeDef timer2, timer3; + +/*************************************************************************/ + +/*CONFIGURAMOS EL SHIELD DEL POLOLULU + Al coincidir con los pines del timer se modifica el codigo +*/ + +DigitalOut M1DIR(D7); +PwmOut M1PWM(PA_7); +//AnalogIn M1FB(A0); + +//DigitalOut M2DIR(D8); +//PwmOut M2PWM(D10); +//DigitalIn M2FB(A1); + +DigitalOut nD2(D6,1); +DigitalIn nSF(D12); + + + + +/***********PUERTO SERIAL*****************/ + +Serial pc(SERIAL_TX, SERIAL_RX); + + +/*VALORES POR DEFECTO*/ + +float VEL=0.0; + +/*VALORES DE CONFIGURACION DE LOS PINES*/ + +InterruptIn FINIZQR(A1); +InterruptIn FINDERM(A0); +//DigitalIn FINIZQR(D5); +//DigitalIn FINDERM(D6); + +int alarma=0; +DigitalOut INDICA(LED2); +DigitalIn INIT(PC_13); + + +void toggle1(void); +void toggle2(void); +void inicializa(void); +void centrar(void); + +/*-------------VARIABLES GLOBALES----------------------*/ + + float X=0; + float POS=0; + float A=0; + float ANG=0; + float LIMIN=300;//SI no inicializa toca manual 220 + float LIMAX=7000; //Si no inciializa toca + + + float XMIN=0; //en las pruebas realizadas el 0 +200 pulsos + float XMAX=7200;; //en las pruebas aprox 7949 + float MITAD=0; + int DATAPC=0; + int LEIDO=0; + + + +/*------------------VARIABLES DEL PID Discreto--------------------------*/ + + +float uc0,yn0,en0,cn0,uc1,yn1,cn1,en1,yn2,cn2,en2,yn3,cn3,en3; + + +//Constantes + +float q0,q1,q2; + +/*-----------------PID DE PENDULO COMPLETO-------------------------------*/ +float PID_CODIGO(float MEDIDA,float SETPOINT,float DT); + +float KI; +float KP; +float KD; +float ERR; +float PREVI_ERR; +float INTEGRAL; +float DERIVATIVO; + +float DESEADO=180; + +float TM=0.01; // tiempo de muestreo + + +float numero, cal_pwm; + + + +/*-------------------------------------------------PROGRAMA---------------------------------------------------------------*/ + +int main() +{ + float SALIDAPID; + + + + //inicializacion de las varibles + yn0=0; + cn0=0; + en0=0; + yn1=0; + cn1=0; + en1=0; + yn2=0; + cn2=0; + en2=0; + yn3=0; + cn3=0; + en3=0; + + q0=0.0510; + q1=-0.00102; + q2=0; + + INTEGRAL=0.0; + KI=0.5; + KP=13; + KD=0.25; + SALIDAPID=0.0; + + + + + //Configuramos el puerto de 96000 a 115200 para mayor velocidad + pc.baud(115200); + + + //counting on both A&B inputs, 4 ticks per cycle, full 32-bit count + EncoderInit(&encoder2, &timer2, TIM2, 0xffffffff, TIM_ENCODERMODE_TI12); + + //counting on both A&B inputs, 4 ticks per cycle, full 32-bit count + EncoderInit(&encoder3, &timer3, TIM3, 0xffff, TIM_ENCODERMODE_TI12); + + int16_t count3=0; + int32_t count2=0; + //int8_t dir2, dir3; + + M1PWM.period_ms(10.0); // set PWM period to 10 ms + + pc.printf("Listo iniciamos centrando el carro !\n"); + wait(0.1); + + + inicializa(); + centrar(); + alarma=1; + + + + pc.printf("Centre el pendulo y Presione reset para continuar \n\r"); + //pc.printf("Press 'a' = aumentar, 'd' = disminuir 'i'=Izquierda 'o'=derecha 'r'=reset contadores 's'=para solo el PWM \n\r"); + char c ='s'; + if (INIT==0){ + + yn0=0; + cn0=0; + en0=0; + yn1=0; + cn1=0; + en1=0; + yn2=0; + cn2=0; + en2=0; + yn3=0; + cn3=0; + en3=0; + alarma=0; + VEL=0; + numero=0; + wait(0.5); + } + + + //Ciclo principal + while(1) { + + + //----Deje habilitado la lectura del teclado para pruebas + if(pc.readable()==1) { + wait(0.1); + c = pc.getc(); + pc.putc(c); + + + if((c == 'a') && (VEL < 0.99)) { + VEL += 0.01; + M1PWM = VEL; + } + if((c == 'd') && (VEL > 0.01)) { + VEL -= 0.01; + M1PWM = VEL; + } + if (c == 'i') { + M1DIR=1; + } + if (c == 'o') { + M1DIR=0; + } + if (c == 'r') { + __HAL_TIM_SetCounter(&timer3, 0x0000); + __HAL_TIM_SetCounter(&timer2, 0x00000000); + } + if (c == 's') { + M1PWM = 0.0; + } + + c='0'; + } + //----fin rutina de teclado + + INDICA=alarma; + + FINIZQR.rise(&toggle1); + FINDERM.rise(&toggle2); + + + //Rutina de lectura de los encoder timer2=X y Timer3 = Angulo + //X es de 100 huecos por revolucion = X4 400 pulsos por revolucion + //X es de 500 huecos por revolucuon = X4 2000 pulsos por revolucion + // X aproximado de 7950 +/10% por temas mecanicos de hay que sea variable el centro + // MITAD = 3757 depende de la ubicacion de los sensores ((MAX-220)-(MIN+220))/2 + + //count2=TIM2->CNT; + //dir2=TIM2->CR1&TIM_CR1_DIR; + count2=__HAL_TIM_GET_COUNTER(&timer2); + //dir2 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer2); //no se necesita para el calculo + + //count3=TIM3->CNT; + //dir3=TIM3->CR1&TIM_CR1_DIR; + count3=__HAL_TIM_GET_COUNTER(&timer3); + //dir3 = __HAL_TIM_IS_TIM_COUNTING_DOWN(&timer3); //no se necesita para el calculo + + + + + X=count2;//sensor de posicion + A=count3;// sensor de angulo + + pc.printf("%6.0f %6.0f \t", X,A); + + if (INIT==0){ + + yn0=0; + cn0=0; + en0=0; + yn1=0; + cn1=0; + en1=0; + yn2=0; + cn2=0; + en2=0; + yn3=0; + cn3=0; + en3=0; + alarma=0; + VEL=0; + numero=0; + wait(0.5); + } + + + //factor de conversion por longitud/pulsos (720mm/7949 =0.090577 mm* pulso LTOTAL/PULSOS + POS=X*720/7949; + + + //factor de conversion grados vuelta/pulsos (360grados/2000 pulsos)=0.18 grados por pulso + ANG=A*0.18; + + pc.printf("POS: %6.3f ANGULO:%6.3f \t", POS,ANG); + + + if(alarma==0){ + + SALIDAPID=PID_CODIGO(ANG, DESEADO, TM); + + VEL=SALIDAPID; + + + //MAXIMO DE LA TARJETA + + if (VEL>100) { //Salida PID si es mayor que el MAX + VEL=99; + } + if (VEL<-100) { //Salida PID si es mayor que el MAX + VEL=-99; + } + + if((VEL<=100)&&(VEL>=0)){ + VEL=VEL*1; //Error es positivo entonces gire a la izquierda lado opuesto del motor + M1DIR=0; + } + + if((VEL<0)&&(VEL>-100)){ + VEL=VEL*-1; //Error es negativo entonces gire a la derecha lado opuesto del motor + M1DIR=1; + } + + + if (abs(VEL)<10){ //Salida PID si es menor que el MIN + VEL=1; + } + + M1PWM=(float)VEL/100;//para controlar con las teclas por silas moscas + + + } + pc.printf("PID = %f \t", SALIDAPID); + pc.printf("REF:%6.2f ANG:%6.2f ERROR: %6.2f ACC:%6.2f Itera: %.0f\t",DESEADO, ANG, ERR,VEL,numero); + + + + + //pc.printf("El PWM %1.3f \t ",VEL); + pc.printf("Alama: %i \n \r",alarma); + + + + + + /*************************************************************************************************/ + numero=numero+1; + + + /****seguridad***************/ + if ((X+300)>=LIMAX){ + VEL=0; + M1PWM=0; + alarma=1; + } + if ((X-300)<=LIMIN){ + VEL=0.0; + M1PWM=0.0; + alarma=1; + } + + + + + + } +} + +/*---------------------FUNCIONES-----------------------------------------------*/ + + /*---------------------INTERUPPCIONES------------------------------------------*/ + + void toggle1() { + wait(0.25); + VEL = 0.0; + M1PWM = 0.0; + alarma=1; + pc.printf("ALARMA FINAL IZQUIERDA\n\r"); + } + + void toggle2() { + wait(0.25); + VEL = 0.0; + alarma=1; + M1PWM = 0.0; + pc.printf("ALARMA FINAL DERECHA\n\r"); + } + +/*--------------------------------FUCIONES DE INICIALIZACION------------------------------*/ + + +void inicializa(){ + pc.printf("Funcion de Inicializacion iniciada\n\r"); + + M1PWM=0.1; + M1DIR=1; + while(FINDERM==0){ + pc.printf("BUSCANCO DERECHA DEL MOTOR\n\r"); + } + pc.printf("ENCONTRADA - REINICIANDO EL CONTADOR EN X\n\r"); + __HAL_TIM_SetCounter(&timer2, 0x00000000); + + M1PWM=0.1; + M1DIR=0; + + while(FINIZQR==0){ + pc.printf("BUSCANCO IZQUIERDA LADO OPUESTO\n\r"); + } + M1PWM=0; + XMAX=__HAL_TIM_GET_COUNTER(&timer2); + M1PWM=0; + XMIN=0; + LIMIN=220; + LIMAX=XMAX-220; + MITAD=(LIMAX-LIMIN)/2; + pc.printf("Fijando los limites XMIN+220 y XMAX-220 por seguridad, XMIN:%6.0f XMAX:%6.0f MITAD:%6.1f \n\r",XMIN, XMAX, MITAD); + + } + +void centrar(){ + float error, pos; + int parada; + float itera; + parada=1; + itera=0; + pos=0; + error=0; + + float K1, K2, K3, uk; + + /*valores por defecto*/ + //Kp=0.03; + //Ki=0; + //Kd=0; + + + /*parametros del PID discreto*/ + // K1=Kp+(Ki/2)*Ts+(Kd/Ts); + // K2=-Kp+(Ki/2)*Ts-(2*Kd/Ts); + // K3=Kd/Ts; + + K1=0.19; + K2=0; + K3=0; + + + + pos=__HAL_TIM_GET_COUNTER(&timer2); + error=MITAD-pos; + + while(parada==1){ + + if (error>0){ + //Error es positivo entonces gire a la izquierda lado opuesto del motor + M1DIR=0; + } + else if(error<=0){ + //Error es negativo entonces gire a la derecha hacia el motor + M1DIR=1; + } + + pos=__HAL_TIM_GET_COUNTER(&timer2); + error=MITAD-pos; + + uk=error*K1; + + + + pc.printf("BUSCA LA MITAD M:%6.0f P:%6.0f E:%6.1f Uk:%6.1f Itera:%6.0f\n\r",MITAD, pos, error,uk, itera); + + if (abs(uk)>100) { //Salida si es mayor que el MAX + uk=80;} + else if (abs(uk)<20){ //Salida si es menor que el MIN + uk=5; + } + + M1PWM=(float)uk/100; //Accion de control mapeada a PWM; salida de la tarjeta. + + + + if (abs(error)<5){ + parada=0; + } + if (itera>1000){ + parada=0; + } + + itera++; + + } + M1PWM=0.0; + pc.printf("ENCONTRADO MITAD:%f POS:%f Error: %f Itera: %f\n\r",MITAD, pos, error, itera); + + +} + +/******************************************PID*******************************************************/ +float PID_CODIGO(float MEDIDA,float SETPOINT,float DT){ + float OUTPID; + + ERR=SETPOINT-MEDIDA; + INTEGRAL=INTEGRAL+ERR*DT; + DERIVATIVO=(ERR-PREVI_ERR)/DT; + OUTPID=KP*ERR-KI*INTEGRAL+KD*DERIVATIVO; + PREVI_ERR=ERR; + + //wait(DT); + return(OUTPID); + + + //previous_error = 0 + //integral = 0 + //start: + //error = setpoint - measured_value + //integral = integral + error*dt + //derivative = (error - previous_error)/dt + //output = Kp*error + Ki*integral + Kd*derivative + //previous_error = error + //wait(dt) + //goto start + + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-dev.lib Sat May 21 04:17:35 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-dev/#9b334a45a8ff