PCA9629 a stepper motor controller class library
Class library for PCA9629.
A sample program available on http://mbed.org/users/nxp_ip/code/PCA9629_Hello/
Revision 7:199f109eb0c6, committed 2012-07-23
- Comitter:
- nxp_ip
- Date:
- Mon Jul 23 04:57:38 2012 +0000
- Parent:
- 6:138665018069
- Commit message:
- version 1.1
Changed in this revision
PCA9629.cpp | Show annotated file Show diff for this revision Revisions of this file |
PCA9629.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/PCA9629.cpp Wed Jul 18 07:42:48 2012 +0000 +++ b/PCA9629.cpp Mon Jul 23 04:57:38 2012 +0000 @@ -1,13 +1,21 @@ -/** A sample code for PCA9629 +/** PCA9629 library * * @author Akifumi (Tedd) OKANO, NXP Semiconductors - * @version 1.0 - * @date 24-Apr-2011 + * @version 1.1 + * @date 23-Jul-2012 + * + * revision history + * version 1.0 (24-Apr-2011) : Initial version + * version 1.1 (23-Jul-2012) : API modification + * Correction for comments * * Released under the MIT License: http://mbed.org/license/mit * * An operation sample of PCU9629 stepper motor controller. * The mbed accesses the PCU9629 registers through I2C. + * + * About PCA9629: + * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629PW.html */ #include "mbed.h" @@ -28,13 +36,22 @@ PCA9629::PCA9629( PinName I2C_sda, PinName I2C_scl, + short steps_per_rotation, char I2C_address ) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) { i2c.frequency( 400 * 1000 ); + software_reset(); init_registers(); } +void PCA9629::software_reset( void ) { + char v = 0x06; + + i2c.write( 0x00, &v, 1 ); + wait_ms( 1 ); +} + void PCA9629::init_registers( void ) { char init_array[] = { 0x80, // register access start address (0x00) with incremental access flag (MSB) 0x30, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 @@ -71,7 +88,7 @@ error( "PCA9629 writing failed\r\n" ); } -void PCA9629::write( Register16bits register_name, short value ) { +void PCA9629::write( RegisterNameFor16bitAccess register_name, short value ) { int error_code; char cmd[ 3 ]; @@ -105,7 +122,7 @@ return ( data ); } -short PCA9629::read( Register16bits register_name ) { +short PCA9629::read( RegisterNameFor16bitAccess register_name ) { int error_code; char cmd; char data[ 2 ]; @@ -150,7 +167,7 @@ step_pulse_width |= (prescaler << 13); - write( (dir == CW) ? CWPW_ : CCWPW_, step_pulse_width ); + write( (dir == CW) ? CW__STEP_WIDTH : CCW_STEP_WIDTH, step_pulse_width ); return ( step_pulse_width ); } @@ -172,14 +189,18 @@ return ( pps( dir, (PrescalerRange)p, (int)pulse_per_second ) ); } -void PCA9629::rotations( Direction dir, int rotations ) { - write( (dir == CW) ? CWRCOUNT_ : CCWRCOUNT_, rotations ); +void PCA9629::rotations( Direction dir, int rotation_count ) { + write( (dir == CW) ? CW__ROTATION_COUNT : CCW_ROTATION_COUNT, rotation_count ); } -void PCA9629::steps( Direction dir, int steps ) { - write( (dir == CW) ? CWSCOUNT_ : CCWSCOUNT_, steps ); +void PCA9629::steps( Direction dir, int step_count ) { + write( (dir == CW) ? CW__STEP_COUNT : CCW_STEP_COUNT, step_count ); } +void PCA9629::rotations_and_steps( Direction dir, int rotation_count, int step_count ) { + rotations( dir, rotation_count ); + steps( dir, step_count ); +} void PCA9629::register_dump( void ) { char data[ 0x27 ];
--- a/PCA9629.h Wed Jul 18 07:42:48 2012 +0000 +++ b/PCA9629.h Mon Jul 23 04:57:38 2012 +0000 @@ -1,13 +1,21 @@ -/** A sample code for PCA9629 +/** PCA9629 library * * @author Akifumi (Tedd) OKANO, NXP Semiconductors - * @version 1.0 - * @date 24-Apr-2011 + * @version 1.1 + * @date 23-Jul-2012 + * + * revision history + * version 1.0 (24-Apr-2011) : Initial version + * version 1.1 (23-Jul-2012) : API modification + * Correction for comments * * Released under the MIT License: http://mbed.org/license/mit * * An operation sample of PCU9629 stepper motor controller. * The mbed accesses the PCU9629 registers through I2C. + * + * About PCA9629: + * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629PW.html */ #ifndef MBED_PCA9629 @@ -15,16 +23,52 @@ #define INTELIGENT_WRITE -#define PCA9629_DEFAULT_ADDR 0x42 +#define DEFAULT_STEPS_PER_ROTATION 48 +#define DEFAULT_PCA9629_ADDR 0x42 /** PCA9629 class * + * This is a driver code for the PCA9629 stepper motor controller. + * This class provides interface for PCA9629 operation and accessing its registers. + * Detail information is available on next URL. + * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629PW.html + * + * Example: + * @code + * #include "mbed.h" + * #include "PCA9629.h" + * + * PCA9629 motor( p28, p27, 48 ); // SDA, SCL, Steps/rotation, I2C_address (option) + * + * int main() { + * + * // Speed setting 200pps for clockwise (CW) rotation + * motor.pps( PCA9629::CW, 200 ); + * + * // Set 2 rotations and 24 steps for CW + * motor.rotations_and_steps( PCA9629::CW, 2, 24 ); + * + * // Speed setting 100pps for counterclockwise (CCW) rotation + * motor.pps( PCA9629::CCW, 100 ); + * + * // Set 1 rotation and 24 steps for CCW + * motor.rotations_and_steps( PCA9629::CCW, 1, 24 ); + * + * while ( 1 ) { + * motor.start( PCA9629::CW ); // Motor start for CW + * wait( 1.0 ); + * + * motor.start( PCA9629::CCW ); // Motor start for CCW + * wait( 1.0 ); + * } + * } + * @endcode */ + class PCA9629 { public: - - /** name of registers */ + /** name of the PCA9629 registers */ typedef enum { MODE, /**< Mode rgister */ SUBADR1, /**< I2C-bus subaddress 1 */ @@ -66,8 +110,9 @@ LOOPDLY, /**< Loopdelay time register */ MCNTL, /**< Control start/stop motor */ } RegisterName; - - /** register names to make 2 bytes access */ + +private: + /* register names for 2 bytes accessing */ typedef enum { SROTN_ = SROTNL | 0x80, /**< Steps per rotation */ CWPW_ = CWPWL | 0x80, /**< Step pulse width for CW rotation */ @@ -76,6 +121,11 @@ CCWSCOUNT_ = CCWSCOUNTL | 0x80, /**< Number of steps CCW */ CWRCOUNT_ = CWRCOUNTL | 0x80, /**< Number of rotatations CW */ CCWRCOUNT_ = CCWRCOUNTL | 0x80, /**< Number of rotatations CCW */ + } _RegisterNameFor16bitAccess; + +public: + /** register names for 2 bytes accessing */ + typedef enum { STEPS_PER_ROATION = SROTN_, CW__STEP_WIDTH = CWPW_, CCW_STEP_WIDTH = CCWPW_, @@ -83,7 +133,7 @@ CCW_STEP_COUNT = CCWSCOUNT_, CW__ROTATION_COUNT = CWRCOUNT_, CCW_ROTATION_COUNT = CCWRCOUNT_ - } Register16bits; + } RegisterNameFor16bitAccess; /** keyword to select direction of rotation */ typedef enum { @@ -91,30 +141,26 @@ CCW /**< ConterClockwise direction */ } Direction; - /** plescaler range setting */ - typedef enum { - PRESCALER_FROM_40_TO_333333, /**< Prescaler range from 3us(333333pps) to 24.576ms(40 pps) */ - PRESCALER_FROM_20_TO_166667, /**< Prescaler range from 6us(166667pps) to 49.152ms(20 pps) */ - PRESCALER_FROM_10_TO_83333, /**< Prescaler range from 12us( 83333pps) to 98.304ms(10 pps) */ - PRESCALER_FROM_5_TO_41667, /**< Prescaler range from 24us( 41667pps) to 196.608ms( 5 pps) */ - PRESCALER_FROM_2_5_TO_20833, /**< Prescaler range from 48us( 20833pps) to 393.216ms( 2.5 pps) */ - PRESCALER_FROM_1_27_TO_10416, /**< Prescaler range from 96us( 10416pps) to 786.432ms( 1.27pps) */ - PRESCALER_FROM_0_64_TO_5208, /**< Prescaler range from 192us( 5208pps) to 1572.864ms( 0.64pps) */ - PRESCALER_FROM_0_32_TO_2604, /**< Prescaler range from 384us( 2604pps) to 3145.728ms( 0.32pps) */ - } PrescalerRange; - /** Create a PCA9629 instance connected to specified I2C pins with specified address * * @param I2C_sda I2C-bus SDA pin * @param I2C_scl I2C-bus SCL pin + * @param steps_per_rotation motor specific setting. This determines how many steps are needed to execute one full turn of motor shaft (360°). * @param I2C_address I2C-bus address (default: 0x42) */ PCA9629( PinName I2C_sda, PinName I2C_scl, - char I2C_address = PCA9629_DEFAULT_ADDR + short steps_per_rotation, + char I2C_address = DEFAULT_PCA9629_ADDR ); + /** Software reset + * + * Performs software reset through I2C bus + */ + void software_reset( void ); + /** Initialize all registers * * The initializing values are defined in the function @@ -143,7 +189,7 @@ * @param register_name the register name: data writing into (it can be "SROTN_", "CWPW_", "CCWPW_", "CWRCOUNT_", "CCWSCOUNT_", "CWRCOUNT_" or "CCWRCOUNT_" ) * @param value 16 bits writing data */ - void write( Register16bits register_name, short value ); + void write( RegisterNameFor16bitAccess register_name, short value ); /** Read 1 byte data from a register * @@ -161,7 +207,7 @@ * @param register_name the register name: data writing into (it can be "SROTN_", "CWPW_", "CCWPW_", "CWRCOUNT_", "CCWSCOUNT_", "CWRCOUNT_" or "CCWRCOUNT_" ) * @return read 16 bits data from the registers */ - short read( Register16bits register_name ); + short read( RegisterNameFor16bitAccess register_name ); /** Motor start * @@ -186,43 +232,41 @@ * This interface can be used to set CWPWx or CCWPWx registers * * @param dir rotate direction ("CW" or "CCW") - * @param prescaler prescaler setting (for 3 bits setting range from 0 to 0x7. See datasheet) - * @param pulse_per_second pps defineds pulse width for the motor. The pulse width will be 1/pps - * @return 16 bit data that what set to the CWPWx or CCWPWx registers - */ - short pps( Direction dir, PrescalerRange prescaler, int pulse_per_second ); - - /** Set PPS - * - * Setting PulsePerSecond - * This interface can be used to set CWPWx or CCWPWx registers - * - * @param dir rotate direction ("CW" or "CCW") * @param pulse_per_second pps defineds pulse width for the motor. The pulse width will be 1/pps * @return 16 bit data that what set to the CWPWx or CCWPWx registers */ short pps( Direction dir, float pulse_per_second ); - /** Set rotation count + /** Set rotations count * * Setting rotation count - * This interfaces CWRCOUNTx, CCWRCOUNTx registers + * This interfaces CWRCOUNTx and CCWRCOUNTx registers * * @param dir rotate direction ("CW" or "CCW") - * @param rotations sets number of rotations with 16 bit value + * @param rotation_count sets number of rotations with 16 bit value */ - void rotations( Direction dir, int rotations ); + void rotations( Direction dir, int rotation_count ); - /** Set PPS + /** Set steps count * * Setting step count - * This interfaces CWSCOUNTx, CCWSCOUNTx registers + * This interfaces CWSCOUNTx and CCWSCOUNTx registers * * @param dir rotate direction ("CW" or "CCW") - * @param steps sets number of steps with 16 bit value + * @param step_count sets number of steps with 16 bit value */ - void steps( Direction dir, int pps ); + void steps( Direction dir, int step_count ); + /** Set rotations and steps counts + * + * Setting rotation and step count + * This interfaces CWRCOUNTx, CCWRCOUNTx, CWSCOUNTx and CCWSCOUNTx registers + * + * @param dir rotate direction ("CW" or "CCW") + * @param rotation_count sets number of rotations with 16 bit value + * @param step_count sets number of steps with 16 bit value + */ + void rotations_and_steps( Direction dir, int rotation_count, int step_count ); /** Register dump * @@ -239,6 +283,29 @@ void speed_change( unsigned short pw ); private: + /* plescaler range setting */ + typedef enum { + PRESCALER_FROM_40_TO_333333, /*< Prescaler range from 3us(333333pps) to 24.576ms(40 pps) */ + PRESCALER_FROM_20_TO_166667, /*< Prescaler range from 6us(166667pps) to 49.152ms(20 pps) */ + PRESCALER_FROM_10_TO_83333, /*< Prescaler range from 12us( 83333pps) to 98.304ms(10 pps) */ + PRESCALER_FROM_5_TO_41667, /*< Prescaler range from 24us( 41667pps) to 196.608ms( 5 pps) */ + PRESCALER_FROM_2_5_TO_20833, /*< Prescaler range from 48us( 20833pps) to 393.216ms( 2.5 pps) */ + PRESCALER_FROM_1_27_TO_10416, /*< Prescaler range from 96us( 10416pps) to 786.432ms( 1.27pps) */ + PRESCALER_FROM_0_64_TO_5208, /*< Prescaler range from 192us( 5208pps) to 1572.864ms( 0.64pps) */ + PRESCALER_FROM_0_32_TO_2604, /*< Prescaler range from 384us( 2604pps) to 3145.728ms( 0.32pps) */ + } PrescalerRange; + + /* Set PPS + * + * Setting PulsePerSecond + * This interface can be used to set CWPWx or CCWPWx registers + * + * @param dir rotate direction ("CW" or "CCW") + * @param prescaler prescaler setting (for 3 bits setting range from 0 to 0x7. See datasheet) + * @param pulse_per_second pps defineds pulse width for the motor. The pulse width will be 1/pps + * @return 16 bit data that what set to the CWPWx or CCWPWx registers + */ + short pps( Direction dir, PrescalerRange prescaler, int pulse_per_second ); I2C i2c; char i2c_addr;