Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PCA9629.cpp
00001 /** PCA9629 library 00002 * 00003 * @author Akifumi (Tedd) OKANO, NXP Semiconductors 00004 * @version 1.1 00005 * @date 23-Jul-2012 00006 * 00007 * revision history 00008 * version 1.0 (24-Apr-2011) : Initial version 00009 * version 1.1 (23-Jul-2012) : API modification 00010 * Correction for comments 00011 * 00012 * Released under the MIT License: http://mbed.org/license/mit 00013 * 00014 * An operation sample of PCU9629 stepper motor controller. 00015 * The mbed accesses the PCU9629 registers through I2C. 00016 * 00017 * About PCA9629: 00018 * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629PW.html 00019 */ 00020 00021 #include "mbed.h" 00022 #include "PCA9629.h" 00023 00024 #define STEP_RESOLUTION 333333 // 1/(3e-6) = 333333 00025 00026 char *reg_name[] = { 00027 "MODE", "SUBADR1", "SUBADR2", "SUBADR3", "ALLCALLADR", "WDTC", "WDMOD", "IP", 00028 "INTSTAT", "OP", "IOC", "MSK", "CLRINT", "INTMODE1", "INTMODE2", "INT_ACT_SETUP", 00029 "INT_MRT_SETUP", "INT_ES_SETUP", "SETMODE", "PHCNTL", "SROTNL", "SROTNH", 00030 "CWPWL", "CWPWH", "CCWPWL", "CCWPWH", 00031 "CWSCOUNTL", "CWSCOUNTH", "CCWSCOUNTL", "CCWSCOUNTH", 00032 "CWRCOUNTL", "CWRCOUNTH", "CCWRCOUNTL", "CCWRCOUNTH", 00033 "EXTRASTEPS0", "EXTRASTEPS1", "RAMPX", "LOOPDLY", "MCNTL" 00034 }; 00035 00036 PCA9629::PCA9629( 00037 PinName I2C_sda, 00038 PinName I2C_scl, 00039 short steps_per_rotation, 00040 char I2C_address 00041 ) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) { 00042 00043 i2c.frequency( 400 * 1000 ); 00044 software_reset(); 00045 init_registers(); 00046 } 00047 00048 void PCA9629::software_reset( void ) { 00049 char v = 0x06; 00050 00051 i2c.write( 0x00, &v, 1 ); 00052 wait_ms( 1 ); 00053 } 00054 00055 void PCA9629::init_registers( void ) { 00056 char init_array[] = { 0x80, // register access start address (0x00) with incremental access flag (MSB) 00057 0x30, 0xE2, 0xE4, 0xE6, 0xE0, 0x02, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06 00058 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08) 00059 0x07, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x03, 0x02, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11) 00060 0x00, 0x00, 0x30, 0x00, 0x82, 0x66, 0x82, 0x06, // for registers SETMODE - CCWPWH (0x12 - 0x19) 00061 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21) 00062 0x00, 0x00, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23) 00063 0x00, 0x00, 0x00 // for registers RMPCNTL - MCNTL (0x24 - 0x26) 00064 }; 00065 00066 set_all_registers( init_array, sizeof( init_array ) ); 00067 } 00068 00069 void PCA9629::set_all_registers( char *a, char size ) { 00070 int error_code; 00071 00072 error_code = i2c.write( i2c_addr, a, size ); 00073 00074 if ( error_code ) 00075 error( "error @ initializing PCA9629" ); 00076 } 00077 00078 void PCA9629::write( RegisterName register_name, char value ) { 00079 int error_code; 00080 char cmd[ 2 ]; 00081 00082 cmd[ 0 ] = register_name; 00083 cmd[ 1 ] = value; 00084 00085 error_code = i2c.write( i2c_addr, cmd, 2 ); 00086 00087 if ( error_code ) 00088 error( "PCA9629 writing failed\r\n" ); 00089 } 00090 00091 void PCA9629::write( RegisterNameFor16bitAccess register_name, short value ) { 00092 int error_code; 00093 char cmd[ 3 ]; 00094 00095 cmd[ 0 ] = register_name; 00096 cmd[ 1 ] = value & 0xFF; 00097 cmd[ 2 ] = value >> 8; 00098 00099 error_code = i2c.write( i2c_addr, cmd, 3 ); 00100 00101 if ( error_code ) 00102 error( "PCA9629 writing failed\r\n" ); 00103 } 00104 00105 char PCA9629::read( RegisterName register_name ) { 00106 int error_code; 00107 char cmd; 00108 char data; 00109 00110 cmd = register_name; 00111 00112 error_code = i2c.write( i2c_addr, &cmd, 1, false ); 00113 00114 if ( error_code ) 00115 error( "PCA9629 reading (command phase) failed\r\n" ); 00116 00117 error_code = i2c.read( i2c_addr, &data, 1 ); 00118 00119 if ( error_code ) 00120 error( "PCA9629 reading (data phase) failed\r\n" ); 00121 00122 return ( data ); 00123 } 00124 00125 short PCA9629::read( RegisterNameFor16bitAccess register_name ) { 00126 int error_code; 00127 char cmd; 00128 char data[ 2 ]; 00129 00130 cmd = register_name; 00131 00132 error_code = i2c.write( i2c_addr, &cmd, 1, false ); 00133 00134 if ( error_code ) 00135 error( "PCA9629 reading (command phase) failed\r\n" ); 00136 00137 error_code = i2c.read( i2c_addr, data, 2 ); 00138 00139 if ( error_code ) 00140 error( "PCA9629 reading (data phase) failed\r\n" ); 00141 00142 return ( data[ 1 ] << 8 | data[ 0 ] ); 00143 } 00144 00145 void PCA9629::start( Direction dir ) { 00146 write( MCNTL, 0xA8 | dir ); 00147 } 00148 00149 void PCA9629::stop( void ) { 00150 write( MCNTL, 0x00 ); 00151 } 00152 00153 00154 short PCA9629::pps( Direction dir, PrescalerRange prescaler, int pps ) { 00155 int step_pulse_width; 00156 00157 step_pulse_width = STEP_RESOLUTION / ((1 << prescaler) * pps); 00158 00159 if ( step_pulse_width & 0xE000 ) { //error( "pps setting: out of range" ); 00160 step_pulse_width = 0x1FFF; 00161 printf( "the pps forced in to the range that user specified.. %fpps\r\n", (float)STEP_RESOLUTION / ((float)0x1FFF * (float)(1 << prescaler)) ); 00162 } 00163 if ( !step_pulse_width ) { //error( "pps setting: out of range" ); 00164 step_pulse_width = 0x1; 00165 printf( "the pps forced in to the range that user specified.. %fpps\r\n", (float)STEP_RESOLUTION / (float)(1 << prescaler) ); 00166 } 00167 00168 step_pulse_width |= (prescaler << 13); 00169 00170 write( (dir == CW) ? CW__STEP_WIDTH : CCW_STEP_WIDTH, step_pulse_width ); 00171 00172 return ( step_pulse_width ); 00173 } 00174 00175 short PCA9629::pps( Direction dir, float pulse_per_second ) { 00176 char p = 0; 00177 char ratio; 00178 00179 ratio = (char)(40.6901 / pulse_per_second); 00180 00181 p = (ratio & 0x01) ? 1 : p; 00182 p = (ratio & 0x02) ? 2 : p; 00183 p = (ratio & 0x04) ? 3 : p; 00184 p = (ratio & 0x08) ? 4 : p; 00185 p = (ratio & 0x10) ? 5 : p; 00186 p = (ratio & 0x20) ? 6 : p; 00187 p = (ratio & 0x40) ? 7 : p; 00188 00189 return ( pps( dir, (PrescalerRange)p, (int)pulse_per_second ) ); 00190 } 00191 00192 void PCA9629::rotations( Direction dir, int rotation_count ) { 00193 write( (dir == CW) ? CW__ROTATION_COUNT : CCW_ROTATION_COUNT, rotation_count ); 00194 } 00195 00196 void PCA9629::steps( Direction dir, int step_count ) { 00197 write( (dir == CW) ? CW__STEP_COUNT : CCW_STEP_COUNT, step_count ); 00198 } 00199 00200 void PCA9629::rotations_and_steps( Direction dir, int rotation_count, int step_count ) { 00201 rotations( dir, rotation_count ); 00202 steps( dir, step_count ); 00203 } 00204 00205 void PCA9629::register_dump( void ) { 00206 char data[ 0x27 ]; 00207 char cmd = 0x80; 00208 int i; 00209 int j; 00210 00211 i2c.write( i2c_addr, &cmd, 1 ); 00212 i2c.read( i2c_addr, data, sizeof( data ) ); 00213 00214 printf( "PCA9629 register dump\r\n" ); 00215 00216 for ( i = 0, j = 0x14; i <= 0x12; i++, j++ ) 00217 printf( " %-13s (0x%02X): 0x%02X %-13s (0x%02X): 0x%02X\r\n", reg_name[ i ], i, data[ i ], reg_name[ j ], j, data[ j ] ); 00218 00219 printf( " %-13s (0x%02X): 0x%02X\r\n", reg_name[ 0x13 ], 0x13, data[ 0x13 ] ); 00220 } 00221 00222 00223 void PCA9629::speed_change( unsigned short pw ) { 00224 char cmd0[] = { PCA9629::MCNTL, 0x00}; // data for stop the motor 00225 char cmd1[] = { PCA9629::CW__STEP_WIDTH, pw & 0xFF, pw >> 8 }; // data for rewrite pulse width 00226 char cmd2[] = { PCA9629::MCNTL, 0xB4}; // start // data for start again 00227 wait_us(10); 00228 00229 i2c.write( i2c_addr, cmd0, sizeof( cmd0 ), true ); // stop the motor 00230 wait_us(50); 00231 i2c.write( i2c_addr, cmd1, sizeof( cmd1 ), true ); // rewrite pulse width 00232 i2c.write( i2c_addr, cmd2, sizeof( cmd2 ), false ); // start again 00233 } 00234 00235 00236
Generated on Wed Jul 13 2022 21:18:11 by
1.7.2
PCA9629 Stepper motor controller