X-CUBE-SPN1-20150128 example source code for one motor compiled under mbed. Tested OK on Nucleo F401. l6474.cpp is modified from original with defines in l6474_target_config.h to select the original behaviour (motor de-energised when halted), or new mode to continue powering with a (reduced) current in the coils (braking/position hold capability). On F401 avoid using mbed's InterruptIn on pins 10-15 (any port). Beware of other conflicts! L0 & F0 are included but untested.
Diff: main.cpp
- Revision:
- 0:b9444a40a999
- Child:
- 1:75a41f0c0586
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Sep 05 20:18:14 2015 +0000 @@ -0,0 +1,442 @@ +/** + ****************************************************************************** + * @file Multi/Examples/MotionControl/IHM01A1_ExampleFor1Motor/Src/main.c + * @author IPC Rennes + * @version V1.5.0 + * @date November 12, 2014 + * @brief This example shows how to use 1 IHM01A1 expansion board + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "mbed.h" +#include "main.h" + +/** @defgroup IHM01A1_Example_for_1_motor_device + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + static volatile uint16_t gLastError; + +/* Private function prototypes -----------------------------------------------*/ +static void MyFlagInterruptHandler(void); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Main program + * @param None + * @retval None + */ +int main(void) +{ + int32_t pos; + uint16_t mySpeed; + + /* STM32xx HAL library initialization */ +// HAL_Init(); + + /* Configure the system clock */ +//mbed SystemClock_Config(); + +//----- Init of the Motor control library + /* Start the L6474 library to use 1 device */ + /* The L6474 registers are set with the predefined values */ + /* from file l6474_target_config.h*/ + BSP_MotorControl_Init(BSP_MOTOR_CONTROL_BOARD_ID_L6474, 1); + + /* Attach the function MyFlagInterruptHandler (defined below) to the flag interrupt */ + BSP_MotorControl_AttachFlagInterrupt(MyFlagInterruptHandler); + + /* Attach the function Error_Handler (defined below) to the error Handler*/ + BSP_MotorControl_AttachErrorHandler(Error_Handler); + +//----- Move of 16000 steps in the FW direction + + /* Move device 0 of 16000 steps in the FORWARD direction*/ + BSP_MotorControl_Move(0, FORWARD, 16000); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Move of 16000 steps in the BW direction + + /* Move device 0 of 16000 steps in the BACKWARD direction*/ + BSP_MotorControl_Move(0, BACKWARD, 16000); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Set the current position of device 0 to be the Home position */ + BSP_MotorControl_SetHome(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Go to position -6400 + + /* Request device 0 to go to position -6400 */ + BSP_MotorControl_GoTo(0,-6400); + + /* Wait for the motor ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Get current position of device 0*/ + pos = BSP_MotorControl_GetPosition(0); + + if (pos != -6400) + { + Error_Handler(11); + } + + /* Set the current position of device 0 to be the Mark position */ + BSP_MotorControl_SetMark(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Go Home + + /* Request device 0 to go to Home */ + BSP_MotorControl_GoHome(0); + BSP_MotorControl_WaitWhileActive(0); + + /* Get current position of device 0 */ + pos = BSP_MotorControl_GetPosition(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Go to position 6400 + + /* Request device 0 to go to position 6400 */ + BSP_MotorControl_GoTo(0,6400); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Get current position of device 0*/ + pos = BSP_MotorControl_GetPosition(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Go Mark which was set previously after go to -6400 + + /* Request device 0 to go to Mark position */ + BSP_MotorControl_GoMark(0); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Get current position of device 0 */ + pos = BSP_MotorControl_GetPosition(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Run the motor BACKWARD + + /* Request device 0 to run BACKWARD */ + BSP_MotorControl_Run(0,BACKWARD); + HAL_Delay(5000); + + /* Get current speed of device 0 */ + mySpeed = BSP_MotorControl_GetCurrentSpeed(0); + +//----- Increase the speed while running + + /* Increase speed of device 0 to 2400 step/s */ + BSP_MotorControl_SetMaxSpeed(0,4800); + HAL_Delay(9000); + + /* Get current speed of device 0 */ + mySpeed = BSP_MotorControl_GetCurrentSpeed(0); + +//----- Decrease the speed while running + + /* Decrease speed of device 0 to 1200 step/s */ + BSP_MotorControl_SetMaxSpeed(0,1200); + HAL_Delay(5000); + + /* Get current speed */ + mySpeed = BSP_MotorControl_GetCurrentSpeed(0); + +//----- Increase acceleration while running + + /* Increase acceleration of device 0 to 480 step/s^2 */ + BSP_MotorControl_SetAcceleration(0,480); + HAL_Delay(5000); + + /* Increase speed of device 0 to 2400 step/s */ + BSP_MotorControl_SetMaxSpeed(0,2400); + HAL_Delay(5000); + + /* Get current speed of device 0 */ + mySpeed = BSP_MotorControl_GetCurrentSpeed(0); + + if (mySpeed != 2400) + { + Error_Handler(10); + } +//----- Increase deceleration while running + + /* Increase deceleration of device 0 to 480 step/s^2 */ + BSP_MotorControl_SetDeceleration(0,480); + HAL_Delay(5000); + + /* Decrease speed of device 0 to 1200 step/s */ + BSP_MotorControl_SetMaxSpeed(0,1200); + HAL_Delay(5000); + + /* Get current speed */ + mySpeed = BSP_MotorControl_GetCurrentSpeed(0); + +//----- Soft stopped required while running + + /* Request soft stop of device 0 */ + BSP_MotorControl_SoftStop(0); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Run stopped by hardstop + + /* Request device 0 to run in FORWARD direction */ + BSP_MotorControl_Run(0,FORWARD); + HAL_Delay(5000); + + /* Request device 0 to immediatly stop */ + BSP_MotorControl_HardStop(0); + BSP_MotorControl_WaitWhileActive(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- GOTO stopped by softstop + + /* Request device 0 to go to position 20000 */ + BSP_MotorControl_GoTo(0,20000); + HAL_Delay(5000); + + /* Request device 0 to perform a soft stop */ + BSP_MotorControl_SoftStop(0); + BSP_MotorControl_WaitWhileActive(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + + //----- Read inexistent register to test MyFlagInterruptHandler + + /* Try to read an inexistent register */ + /* the flag interrupt should be raised */ + /* and the MyFlagInterruptHandler function called */ + BSP_MotorControl_CmdGetParam(0,0x1F); + HAL_Delay(500); + +//----- Change step mode to full step mode + + /* Select full step mode for device 0 */ + BSP_MotorControl_SelectStepMode(0,STEP_MODE_FULL); + + /* Set speed and acceleration to be consistent with full step mode */ + BSP_MotorControl_SetMaxSpeed(0,100); + BSP_MotorControl_SetMinSpeed(0,50); + BSP_MotorControl_SetAcceleration(0,10); + BSP_MotorControl_SetDeceleration(0,10); + + /* Request device 0 to go position 200 */ + BSP_MotorControl_GoTo(0,200); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Get current position */ + pos = BSP_MotorControl_GetPosition(0); + + /* Wait for 2 seconds */ + HAL_Delay(2000); + +//----- Restore 1/16 microstepping mode + + /* Reset device 0 to 1/16 microstepping mode */ + BSP_MotorControl_SelectStepMode(0,STEP_MODE_1_16); //_FULL _HALF 1_16 + + /* Update speed, acceleration, deceleration for 1/16 microstepping mode*/ + BSP_MotorControl_SetMaxSpeed(0,40000); + BSP_MotorControl_SetMinSpeed(0,800); + BSP_MotorControl_SetAcceleration(0,160); + BSP_MotorControl_SetDeceleration(0,160); + + /* Infinite loop */ + while(1) + { + /* Request device 0 to go position -6400 */ + BSP_MotorControl_GoTo(0,-6400); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + + /* Request device 0 to go position 6400 */ + BSP_MotorControl_GoTo(0,6400); + + /* Wait for the motor of device 0 ends moving */ + BSP_MotorControl_WaitWhileActive(0); + } +} + +/** + * @brief This function is the User handler for the flag interrupt + * @param None + * @retval None + */ +void MyFlagInterruptHandler(void) +{ + /* Get the value of the status register via the L6474 command GET_STATUS */ + uint16_t statusRegister = BSP_MotorControl_CmdGetStatus(0); + + /* Check HIZ flag: if set, power brigdes are disabled */ + if ((statusRegister & L6474_STATUS_HIZ) == L6474_STATUS_HIZ) + { + // HIZ state + // Action to be customized + } + + /* Check direction bit */ + if ((statusRegister & L6474_STATUS_DIR) == L6474_STATUS_DIR) + { + // Forward direction is set + // Action to be customized + } + else + { + // Backward direction is set + // Action to be customized + } + + /* Check NOTPERF_CMD flag: if set, the command received by SPI can't be performed */ + /* This often occures when a command is sent to the L6474 */ + /* while it is in HIZ state */ + if ((statusRegister & L6474_STATUS_NOTPERF_CMD) == L6474_STATUS_NOTPERF_CMD) + { + // Command received by SPI can't be performed + // Action to be customized + } + + /* Check WRONG_CMD flag: if set, the command does not exist */ + if ((statusRegister & L6474_STATUS_WRONG_CMD) == L6474_STATUS_WRONG_CMD) + { + //command received by SPI does not exist + // Action to be customized + } + + /* Check UVLO flag: if not set, there is an undervoltage lock-out */ + if ((statusRegister & L6474_STATUS_UVLO) == 0) + { + //undervoltage lock-out + // Action to be customized + } + + /* Check TH_WRN flag: if not set, the thermal warning threshold is reached */ + if ((statusRegister & L6474_STATUS_TH_WRN) == 0) + { + //thermal warning threshold is reached + // Action to be customized + } + + /* Check TH_SHD flag: if not set, the thermal shut down threshold is reached */ + if ((statusRegister & L6474_STATUS_TH_SD) == 0) + { + //thermal shut down threshold is reached + // Action to be customized + } + + /* Check OCD flag: if not set, there is an overcurrent detection */ + if ((statusRegister & L6474_STATUS_OCD) == 0) + { + //overcurrent detection + // Action to be customized + } + +} + +/** + * @brief This function is executed in case of error occurrence. + * @param error number of the error + * @retval None + */ +void Error_Handler(uint16_t error) +{ + /* Backup error number */ + gLastError = error; + + /* Infinite loop */ + while(1) + { + } +} + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + + /* Infinite loop */ + while (1) + { + } +} +#endif + +/** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/