Fm+ I2C-bus advanced stepper motor controller
Dependencies: mbed
PCA9629A.cpp@0:6607b5b5fd68, 2015-02-04 (annotated)
- Committer:
- wataaki
- Date:
- Wed Feb 04 06:07:37 2015 +0000
- Revision:
- 0:6607b5b5fd68
Initial version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wataaki | 0:6607b5b5fd68 | 1 | #include "mbed.h" |
wataaki | 0:6607b5b5fd68 | 2 | #include "PCA9629A.h" |
wataaki | 0:6607b5b5fd68 | 3 | |
wataaki | 0:6607b5b5fd68 | 4 | I2C i2c(p28,p27); // sda, scl |
wataaki | 0:6607b5b5fd68 | 5 | Serial pc(USBTX, USBRX); // tx, rx |
wataaki | 0:6607b5b5fd68 | 6 | char cmd[32]; |
wataaki | 0:6607b5b5fd68 | 7 | int sw, swp; |
wataaki | 0:6607b5b5fd68 | 8 | long dum; |
wataaki | 0:6607b5b5fd68 | 9 | int i, j; |
wataaki | 0:6607b5b5fd68 | 10 | |
wataaki | 0:6607b5b5fd68 | 11 | void set_ch(char sel) |
wataaki | 0:6607b5b5fd68 | 12 | { // PCA9541のサンプル |
wataaki | 0:6607b5b5fd68 | 13 | // MST_0側の自分にスレーブ側の制御権を得る場合 |
wataaki | 0:6607b5b5fd68 | 14 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:6607b5b5fd68 | 15 | i2c.write( 0xe2, cmd, 1); // Cont Regを指定 |
wataaki | 0:6607b5b5fd68 | 16 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:6607b5b5fd68 | 17 | wait(0.1); // 0.1s待つ |
wataaki | 0:6607b5b5fd68 | 18 | switch(cmd[0] & 0xf) |
wataaki | 0:6607b5b5fd68 | 19 | { |
wataaki | 0:6607b5b5fd68 | 20 | case 0: // bus off, has control |
wataaki | 0:6607b5b5fd68 | 21 | case 1: // bus off, no control |
wataaki | 0:6607b5b5fd68 | 22 | case 5: // bus on, no control |
wataaki | 0:6607b5b5fd68 | 23 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:6607b5b5fd68 | 24 | cmd[1] = 4; // bus on, has control |
wataaki | 0:6607b5b5fd68 | 25 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 26 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:6607b5b5fd68 | 27 | break; |
wataaki | 0:6607b5b5fd68 | 28 | case 2: // bus off, no control |
wataaki | 0:6607b5b5fd68 | 29 | case 3: // bus off, has control |
wataaki | 0:6607b5b5fd68 | 30 | case 6: // bus on, no control |
wataaki | 0:6607b5b5fd68 | 31 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:6607b5b5fd68 | 32 | cmd[1] = 5; // bus on, has control |
wataaki | 0:6607b5b5fd68 | 33 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 34 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:6607b5b5fd68 | 35 | break; |
wataaki | 0:6607b5b5fd68 | 36 | case 9: // bus on, no control |
wataaki | 0:6607b5b5fd68 | 37 | case 0xc: // bus on, no control |
wataaki | 0:6607b5b5fd68 | 38 | case 0xd: // bus off, no control |
wataaki | 0:6607b5b5fd68 | 39 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:6607b5b5fd68 | 40 | cmd[1] = 0; // bus on, has control |
wataaki | 0:6607b5b5fd68 | 41 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 42 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:6607b5b5fd68 | 43 | break; |
wataaki | 0:6607b5b5fd68 | 44 | case 0xa: // bus on, no control |
wataaki | 0:6607b5b5fd68 | 45 | case 0xe: // bus off, no control |
wataaki | 0:6607b5b5fd68 | 46 | case 0xf: // bus on, has control |
wataaki | 0:6607b5b5fd68 | 47 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:6607b5b5fd68 | 48 | cmd[1] = 1; // bus on, has control |
wataaki | 0:6607b5b5fd68 | 49 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 50 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:6607b5b5fd68 | 51 | break; |
wataaki | 0:6607b5b5fd68 | 52 | default: |
wataaki | 0:6607b5b5fd68 | 53 | break; |
wataaki | 0:6607b5b5fd68 | 54 | } |
wataaki | 0:6607b5b5fd68 | 55 | |
wataaki | 0:6607b5b5fd68 | 56 | cmd[0] = sel; // PCA9546 Cont Reg sel channel enabled |
wataaki | 0:6607b5b5fd68 | 57 | i2c.write( 0xe8, cmd, 1); // Send command string |
wataaki | 0:6607b5b5fd68 | 58 | } |
wataaki | 0:6607b5b5fd68 | 59 | |
wataaki | 0:6607b5b5fd68 | 60 | void wdt_rst(void) // WDT |
wataaki | 0:6607b5b5fd68 | 61 | { |
wataaki | 0:6607b5b5fd68 | 62 | cmd[0] = WDTOI; |
wataaki | 0:6607b5b5fd68 | 63 | cmd[1] = 0x1; // 1s |
wataaki | 0:6607b5b5fd68 | 64 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 65 | |
wataaki | 0:6607b5b5fd68 | 66 | cmd[0] = WDCNTL; |
wataaki | 0:6607b5b5fd68 | 67 | cmd[1] = 0x2 + 0x1; // WDMOD = Reset & int WDEN = 1 |
wataaki | 0:6607b5b5fd68 | 68 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 69 | |
wataaki | 0:6607b5b5fd68 | 70 | wait(1.1); |
wataaki | 0:6607b5b5fd68 | 71 | } |
wataaki | 0:6607b5b5fd68 | 72 | |
wataaki | 0:6607b5b5fd68 | 73 | int main () |
wataaki | 0:6607b5b5fd68 | 74 | { |
wataaki | 0:6607b5b5fd68 | 75 | i2c.frequency(100000); |
wataaki | 0:6607b5b5fd68 | 76 | pc.printf("PCA9629A Sample Program\r\n"); |
wataaki | 0:6607b5b5fd68 | 77 | |
wataaki | 0:6607b5b5fd68 | 78 | set_ch(1); // PCA9629Aはch0に接続 |
wataaki | 0:6607b5b5fd68 | 79 | // PCA9629A |
wataaki | 0:6607b5b5fd68 | 80 | |
wataaki | 0:6607b5b5fd68 | 81 | while(1) |
wataaki | 0:6607b5b5fd68 | 82 | { |
wataaki | 0:6607b5b5fd68 | 83 | wdt_rst(); // reset |
wataaki | 0:6607b5b5fd68 | 84 | pc.printf("CW->CCW .. 1, Ramp .. 2, Phase .. 3 ? \r\n"); |
wataaki | 0:6607b5b5fd68 | 85 | pc.scanf("%d", &sw); |
wataaki | 0:6607b5b5fd68 | 86 | switch (sw) |
wataaki | 0:6607b5b5fd68 | 87 | { |
wataaki | 0:6607b5b5fd68 | 88 | case 1: |
wataaki | 0:6607b5b5fd68 | 89 | pc.printf("CW->CCW Sample Start\r\n"); |
wataaki | 0:6607b5b5fd68 | 90 | |
wataaki | 0:6607b5b5fd68 | 91 | cmd[0] = MODE; |
wataaki | 0:6607b5b5fd68 | 92 | cmd[1] = 0x0; // Normal |
wataaki | 0:6607b5b5fd68 | 93 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 94 | |
wataaki | 0:6607b5b5fd68 | 95 | cmd[0] = OP_CFG_PHS; |
wataaki | 0:6607b5b5fd68 | 96 | cmd[1] = 0x10; // 1Phase, OUT[3:0] |
wataaki | 0:6607b5b5fd68 | 97 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 98 | |
wataaki | 0:6607b5b5fd68 | 99 | cmd[0] = CWPWL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 100 | cmd[1] = 0x0; // 24us * 4096 = 98.304ms |
wataaki | 0:6607b5b5fd68 | 101 | cmd[2] = (0x3 << 5) + 0x10; // Prescaler = 3 |
wataaki | 0:6607b5b5fd68 | 102 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 103 | |
wataaki | 0:6607b5b5fd68 | 104 | cmd[0] = CCWPWL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 105 | cmd[1] = 0x0; // 24us * 2048 = 49.152ms |
wataaki | 0:6607b5b5fd68 | 106 | cmd[2] = (0x3 << 5) + 0x8; // Prescaler = 3 |
wataaki | 0:6607b5b5fd68 | 107 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 108 | |
wataaki | 0:6607b5b5fd68 | 109 | cmd[0] = CWSCOUNTL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 110 | cmd[1] = 0x00; // |
wataaki | 0:6607b5b5fd68 | 111 | cmd[2] = 0x1; // 256 steps |
wataaki | 0:6607b5b5fd68 | 112 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 113 | |
wataaki | 0:6607b5b5fd68 | 114 | cmd[0] = CCWSCOUNTL + 0x80; |
wataaki | 0:6607b5b5fd68 | 115 | cmd[1] = 0x80; // 128 steps |
wataaki | 0:6607b5b5fd68 | 116 | cmd[2] = 0x0; // |
wataaki | 0:6607b5b5fd68 | 117 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 118 | |
wataaki | 0:6607b5b5fd68 | 119 | cmd[0] = PMA; |
wataaki | 0:6607b5b5fd68 | 120 | cmd[1] = 2; // One time |
wataaki | 0:6607b5b5fd68 | 121 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 122 | |
wataaki | 0:6607b5b5fd68 | 123 | cmd[0] = MCNTL; |
wataaki | 0:6607b5b5fd68 | 124 | cmd[1] = 0x80 + 0x2; // Start, CW->CCW |
wataaki | 0:6607b5b5fd68 | 125 | i2c.write(PCA9629A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 126 | |
wataaki | 0:6607b5b5fd68 | 127 | while(1) |
wataaki | 0:6607b5b5fd68 | 128 | { |
wataaki | 0:6607b5b5fd68 | 129 | wait(1); |
wataaki | 0:6607b5b5fd68 | 130 | cmd[0] = 0x80 + STEPCOUNT0; |
wataaki | 0:6607b5b5fd68 | 131 | i2c.write(PCA9629A_ADDR, cmd, 1, true); |
wataaki | 0:6607b5b5fd68 | 132 | i2c.read(PCA9629A_ADDR, cmd, 4); // STEPCOUNT 4byteを読込み |
wataaki | 0:6607b5b5fd68 | 133 | dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24); |
wataaki | 0:6607b5b5fd68 | 134 | if (dum == 0) break; |
wataaki | 0:6607b5b5fd68 | 135 | } |
wataaki | 0:6607b5b5fd68 | 136 | pc.printf("CW->CCW Sample End\r\n"); |
wataaki | 0:6607b5b5fd68 | 137 | break; |
wataaki | 0:6607b5b5fd68 | 138 | |
wataaki | 0:6607b5b5fd68 | 139 | case 2: |
wataaki | 0:6607b5b5fd68 | 140 | pc.printf("Ramp Sample Start\r\n"); |
wataaki | 0:6607b5b5fd68 | 141 | |
wataaki | 0:6607b5b5fd68 | 142 | cmd[0] = MODE; |
wataaki | 0:6607b5b5fd68 | 143 | cmd[1] = 0x0; // Normal |
wataaki | 0:6607b5b5fd68 | 144 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 145 | |
wataaki | 0:6607b5b5fd68 | 146 | cmd[0] = OP_CFG_PHS; |
wataaki | 0:6607b5b5fd68 | 147 | cmd[1] = 0x10; // 1Phase, OUT[3:0] |
wataaki | 0:6607b5b5fd68 | 148 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 149 | |
wataaki | 0:6607b5b5fd68 | 150 | cmd[0] = CWPWL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 151 | cmd[1] = 0x0; // 48us * 256 = 12.288ms |
wataaki | 0:6607b5b5fd68 | 152 | cmd[2] = (0x4 << 5) + 0x1; // Prescaler = 4 |
wataaki | 0:6607b5b5fd68 | 153 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 154 | |
wataaki | 0:6607b5b5fd68 | 155 | cmd[0] = CWSCOUNTL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 156 | cmd[1] = 0x40; // |
wataaki | 0:6607b5b5fd68 | 157 | cmd[2] = 0x1; // 320 steps |
wataaki | 0:6607b5b5fd68 | 158 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 159 | |
wataaki | 0:6607b5b5fd68 | 160 | cmd[0] = RUCNTL; |
wataaki | 0:6607b5b5fd68 | 161 | cmd[1] = 0x37; // 48us x 128 = 6.144ms |
wataaki | 0:6607b5b5fd68 | 162 | i2c.write(PCA9629A_ADDR, cmd, 2); // |
wataaki | 0:6607b5b5fd68 | 163 | |
wataaki | 0:6607b5b5fd68 | 164 | cmd[0] = RDCNTL; |
wataaki | 0:6607b5b5fd68 | 165 | cmd[1] = 0x38; // 48us x 256 = 12.288ms |
wataaki | 0:6607b5b5fd68 | 166 | i2c.write(PCA9629A_ADDR, cmd, 2); // |
wataaki | 0:6607b5b5fd68 | 167 | |
wataaki | 0:6607b5b5fd68 | 168 | cmd[0] = PMA; |
wataaki | 0:6607b5b5fd68 | 169 | cmd[1] = 2; // One time |
wataaki | 0:6607b5b5fd68 | 170 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 171 | |
wataaki | 0:6607b5b5fd68 | 172 | cmd[0] = MCNTL; |
wataaki | 0:6607b5b5fd68 | 173 | cmd[1] = 0x80 + 0x0; // Start, CW |
wataaki | 0:6607b5b5fd68 | 174 | i2c.write(PCA9629A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 175 | |
wataaki | 0:6607b5b5fd68 | 176 | while(1) |
wataaki | 0:6607b5b5fd68 | 177 | { |
wataaki | 0:6607b5b5fd68 | 178 | wait(1); |
wataaki | 0:6607b5b5fd68 | 179 | cmd[0] = 0x80 + STEPCOUNT0; |
wataaki | 0:6607b5b5fd68 | 180 | i2c.write(PCA9629A_ADDR, cmd, 1, true); |
wataaki | 0:6607b5b5fd68 | 181 | i2c.read(PCA9629A_ADDR, cmd, 4); // STEPCOUNT 4byteを読込み |
wataaki | 0:6607b5b5fd68 | 182 | dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24); |
wataaki | 0:6607b5b5fd68 | 183 | if (dum == 0) break; |
wataaki | 0:6607b5b5fd68 | 184 | } |
wataaki | 0:6607b5b5fd68 | 185 | pc.printf("Ramp Sample End\r\n"); |
wataaki | 0:6607b5b5fd68 | 186 | |
wataaki | 0:6607b5b5fd68 | 187 | break; |
wataaki | 0:6607b5b5fd68 | 188 | |
wataaki | 0:6607b5b5fd68 | 189 | case 3: |
wataaki | 0:6607b5b5fd68 | 190 | pc.printf("Phase Sample Start\r\n"); |
wataaki | 0:6607b5b5fd68 | 191 | pc.printf("1相 .. 1, 2相 .. 2, 1-2相 .. 3 ? \r\n"); |
wataaki | 0:6607b5b5fd68 | 192 | pc.scanf("%d", &swp); |
wataaki | 0:6607b5b5fd68 | 193 | |
wataaki | 0:6607b5b5fd68 | 194 | cmd[0] = MODE; |
wataaki | 0:6607b5b5fd68 | 195 | cmd[1] = 0x0; // Normal |
wataaki | 0:6607b5b5fd68 | 196 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 197 | |
wataaki | 0:6607b5b5fd68 | 198 | cmd[0] = OP_CFG_PHS; |
wataaki | 0:6607b5b5fd68 | 199 | cmd[1] = ((swp - 1) << 6) + 0x10; // ?Phase, OUT[3:0] |
wataaki | 0:6607b5b5fd68 | 200 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 201 | |
wataaki | 0:6607b5b5fd68 | 202 | cmd[0] = CWPWL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 203 | cmd[1] = 0x0; // 48us * 4096 = 196.6ms |
wataaki | 0:6607b5b5fd68 | 204 | cmd[2] = (0x4 << 5) + 0x10; // Prescaler = 4 |
wataaki | 0:6607b5b5fd68 | 205 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 206 | |
wataaki | 0:6607b5b5fd68 | 207 | cmd[0] = CWSCOUNTL + 0x80; // Auto Increment |
wataaki | 0:6607b5b5fd68 | 208 | cmd[1] = 0x40; // |
wataaki | 0:6607b5b5fd68 | 209 | cmd[2] = 0x0; // 256 steps |
wataaki | 0:6607b5b5fd68 | 210 | i2c.write(PCA9629A_ADDR, cmd, 3); |
wataaki | 0:6607b5b5fd68 | 211 | |
wataaki | 0:6607b5b5fd68 | 212 | cmd[0] = PMA; |
wataaki | 0:6607b5b5fd68 | 213 | cmd[1] = 2; // One time |
wataaki | 0:6607b5b5fd68 | 214 | i2c.write(PCA9629A_ADDR, cmd, 2); |
wataaki | 0:6607b5b5fd68 | 215 | |
wataaki | 0:6607b5b5fd68 | 216 | cmd[0] = MCNTL; |
wataaki | 0:6607b5b5fd68 | 217 | cmd[1] = 0x80 + 0x0; // Start, CW |
wataaki | 0:6607b5b5fd68 | 218 | i2c.write(PCA9629A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:6607b5b5fd68 | 219 | |
wataaki | 0:6607b5b5fd68 | 220 | while(1) |
wataaki | 0:6607b5b5fd68 | 221 | { |
wataaki | 0:6607b5b5fd68 | 222 | wait(1); |
wataaki | 0:6607b5b5fd68 | 223 | cmd[0] = 0x80 + STEPCOUNT0; |
wataaki | 0:6607b5b5fd68 | 224 | i2c.write(PCA9629A_ADDR, cmd, 1, true); |
wataaki | 0:6607b5b5fd68 | 225 | i2c.read(PCA9629A_ADDR, cmd, 4); // STEPCOUNT 4byteを読込み |
wataaki | 0:6607b5b5fd68 | 226 | dum = cmd[0] + (cmd[1] << 8) + (cmd[2] << 16) + (cmd[3] << 24); |
wataaki | 0:6607b5b5fd68 | 227 | if (dum == 0) break; |
wataaki | 0:6607b5b5fd68 | 228 | } |
wataaki | 0:6607b5b5fd68 | 229 | pc.printf("Phase Sample End\r\n"); |
wataaki | 0:6607b5b5fd68 | 230 | break; |
wataaki | 0:6607b5b5fd68 | 231 | default: |
wataaki | 0:6607b5b5fd68 | 232 | break; |
wataaki | 0:6607b5b5fd68 | 233 | } |
wataaki | 0:6607b5b5fd68 | 234 | } |
wataaki | 0:6607b5b5fd68 | 235 | } |