Fm+ I2C-bus advanced stepper motor controller

Dependencies:   mbed

Committer:
wataaki
Date:
Wed Feb 04 06:07:37 2015 +0000
Revision:
0:6607b5b5fd68
Initial version

Who changed what in which revision?

UserRevisionLine numberNew 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 }