16-channel Fm+ I2C-bus 57 mA/20 V constant current LED driver
Dependencies: mbed
PCA9955A.cpp@0:a872e4dd8ec3, 2015-02-04 (annotated)
- Committer:
- wataaki
- Date:
- Wed Feb 04 06:09:08 2015 +0000
- Revision:
- 0:a872e4dd8ec3
Initial version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wataaki | 0:a872e4dd8ec3 | 1 | #include "mbed.h" |
wataaki | 0:a872e4dd8ec3 | 2 | #include "PCA9955A.h" |
wataaki | 0:a872e4dd8ec3 | 3 | |
wataaki | 0:a872e4dd8ec3 | 4 | I2C i2c(p28,p27); // sda, scl |
wataaki | 0:a872e4dd8ec3 | 5 | Serial pc(USBTX, USBRX); // tx, rx |
wataaki | 0:a872e4dd8ec3 | 6 | char cmd[32]; |
wataaki | 0:a872e4dd8ec3 | 7 | int i, j, k; |
wataaki | 0:a872e4dd8ec3 | 8 | int sw; |
wataaki | 0:a872e4dd8ec3 | 9 | |
wataaki | 0:a872e4dd8ec3 | 10 | void set_ch(char sel) |
wataaki | 0:a872e4dd8ec3 | 11 | { // PCA9541のサンプル |
wataaki | 0:a872e4dd8ec3 | 12 | // MST_0側の自分にスレーブ側の制御権を得る場合 |
wataaki | 0:a872e4dd8ec3 | 13 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:a872e4dd8ec3 | 14 | i2c.write( 0xe2, cmd, 1); // Cont Regを指定 |
wataaki | 0:a872e4dd8ec3 | 15 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:a872e4dd8ec3 | 16 | wait(0.1); // 0.1s待つ |
wataaki | 0:a872e4dd8ec3 | 17 | switch(cmd[0] & 0xf) |
wataaki | 0:a872e4dd8ec3 | 18 | { |
wataaki | 0:a872e4dd8ec3 | 19 | case 0: // bus off, has control |
wataaki | 0:a872e4dd8ec3 | 20 | case 1: // bus off, no control |
wataaki | 0:a872e4dd8ec3 | 21 | case 5: // bus on, no control |
wataaki | 0:a872e4dd8ec3 | 22 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:a872e4dd8ec3 | 23 | cmd[1] = 4; // bus on, has control |
wataaki | 0:a872e4dd8ec3 | 24 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 25 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:a872e4dd8ec3 | 26 | break; |
wataaki | 0:a872e4dd8ec3 | 27 | case 2: // bus off, no control |
wataaki | 0:a872e4dd8ec3 | 28 | case 3: // bus off, has control |
wataaki | 0:a872e4dd8ec3 | 29 | case 6: // bus on, no control |
wataaki | 0:a872e4dd8ec3 | 30 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:a872e4dd8ec3 | 31 | cmd[1] = 5; // bus on, has control |
wataaki | 0:a872e4dd8ec3 | 32 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 33 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:a872e4dd8ec3 | 34 | break; |
wataaki | 0:a872e4dd8ec3 | 35 | case 9: // bus on, no control |
wataaki | 0:a872e4dd8ec3 | 36 | case 0xc: // bus on, no control |
wataaki | 0:a872e4dd8ec3 | 37 | case 0xd: // bus off, no control |
wataaki | 0:a872e4dd8ec3 | 38 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:a872e4dd8ec3 | 39 | cmd[1] = 0; // bus on, has control |
wataaki | 0:a872e4dd8ec3 | 40 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 41 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:a872e4dd8ec3 | 42 | break; |
wataaki | 0:a872e4dd8ec3 | 43 | case 0xa: // bus on, no control |
wataaki | 0:a872e4dd8ec3 | 44 | case 0xe: // bus off, no control |
wataaki | 0:a872e4dd8ec3 | 45 | case 0xf: // bus on, has control |
wataaki | 0:a872e4dd8ec3 | 46 | cmd[0] = 1; // PCA9541 コマンドコード Cont Reg |
wataaki | 0:a872e4dd8ec3 | 47 | cmd[1] = 1; // bus on, has control |
wataaki | 0:a872e4dd8ec3 | 48 | i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 49 | i2c.read( 0xe2, cmd, 1); // Cont Regを読込み |
wataaki | 0:a872e4dd8ec3 | 50 | break; |
wataaki | 0:a872e4dd8ec3 | 51 | default: |
wataaki | 0:a872e4dd8ec3 | 52 | break; |
wataaki | 0:a872e4dd8ec3 | 53 | } |
wataaki | 0:a872e4dd8ec3 | 54 | |
wataaki | 0:a872e4dd8ec3 | 55 | cmd[0] = sel; // PCA9546 Cont Reg sel channel enabled |
wataaki | 0:a872e4dd8ec3 | 56 | i2c.write( 0xe8, cmd, 1); // Send command string |
wataaki | 0:a872e4dd8ec3 | 57 | } |
wataaki | 0:a872e4dd8ec3 | 58 | |
wataaki | 0:a872e4dd8ec3 | 59 | int main () |
wataaki | 0:a872e4dd8ec3 | 60 | { |
wataaki | 0:a872e4dd8ec3 | 61 | i2c.frequency(100000); |
wataaki | 0:a872e4dd8ec3 | 62 | pc.printf("PCA9955A Sample Program\r\n"); |
wataaki | 0:a872e4dd8ec3 | 63 | |
wataaki | 0:a872e4dd8ec3 | 64 | set_ch(1); // PCA9955Aはch0に接続 |
wataaki | 0:a872e4dd8ec3 | 65 | |
wataaki | 0:a872e4dd8ec3 | 66 | // PCA9955A |
wataaki | 0:a872e4dd8ec3 | 67 | while(1) |
wataaki | 0:a872e4dd8ec3 | 68 | { |
wataaki | 0:a872e4dd8ec3 | 69 | pc.printf("シーケンシャル … 1, グラデーション … 2 ? \r\n"); |
wataaki | 0:a872e4dd8ec3 | 70 | pc.scanf("%d", &sw); |
wataaki | 0:a872e4dd8ec3 | 71 | pc.printf("%d\r\n", sw); |
wataaki | 0:a872e4dd8ec3 | 72 | switch (sw) |
wataaki | 0:a872e4dd8ec3 | 73 | { |
wataaki | 0:a872e4dd8ec3 | 74 | case 1: |
wataaki | 0:a872e4dd8ec3 | 75 | pc.printf("シーケンシャル Sample Start\r\n"); |
wataaki | 0:a872e4dd8ec3 | 76 | |
wataaki | 0:a872e4dd8ec3 | 77 | cmd[0] = MODE1; |
wataaki | 0:a872e4dd8ec3 | 78 | cmd[1] = 0x0; // SLEEP = 0 |
wataaki | 0:a872e4dd8ec3 | 79 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 80 | |
wataaki | 0:a872e4dd8ec3 | 81 | cmd[0] = LEDOUT0 + 0x80; // LEDOUT0, Auto incriment |
wataaki | 0:a872e4dd8ec3 | 82 | cmd[1] = 0xaa; // LED3,2,1,0 10= PWM |
wataaki | 0:a872e4dd8ec3 | 83 | cmd[2] = 0xaa; // LED7,6,5,4 10= PWM |
wataaki | 0:a872e4dd8ec3 | 84 | cmd[3] = 0xaa; // LED11,10,9,8 10= PWM |
wataaki | 0:a872e4dd8ec3 | 85 | cmd[4] = 0xaa; // LED15,14,13,12 10= PWM |
wataaki | 0:a872e4dd8ec3 | 86 | i2c.write(PCA9955A_ADDR, cmd, 5); // cmd[0]Regにcmd[1-4]を書込み |
wataaki | 0:a872e4dd8ec3 | 87 | |
wataaki | 0:a872e4dd8ec3 | 88 | cmd[0] = IREF0 + 0x80; // IREF0, Auto incriment |
wataaki | 0:a872e4dd8ec3 | 89 | for(i=0; i<16; i++) cmd[i+1] = 0x80; // all IREF = 50% |
wataaki | 0:a872e4dd8ec3 | 90 | i2c.write(PCA9955A_ADDR, cmd, 17); // cmd[0]Regにcmd[1-16]を書込み |
wataaki | 0:a872e4dd8ec3 | 91 | |
wataaki | 0:a872e4dd8ec3 | 92 | for(k=0; k<3; k++) // 3回繰返す |
wataaki | 0:a872e4dd8ec3 | 93 | { |
wataaki | 0:a872e4dd8ec3 | 94 | for(i=0; i<16; i++) // チャネル0~15まで一つずつ点灯 |
wataaki | 0:a872e4dd8ec3 | 95 | { |
wataaki | 0:a872e4dd8ec3 | 96 | cmd[0] = PWM0 + 0x80; // PWM0, Auto incriment |
wataaki | 0:a872e4dd8ec3 | 97 | for(j=0; j<16; j++) cmd[j+1] = 0x0; // all LED PWM = 0% |
wataaki | 0:a872e4dd8ec3 | 98 | cmd[i+1] = 0xff; // iチャネルのLED PWM = 99.6% |
wataaki | 0:a872e4dd8ec3 | 99 | i2c.write(PCA9955A_ADDR, cmd, 17); // cmd[0]Regにcmd[1-16]を書込み |
wataaki | 0:a872e4dd8ec3 | 100 | wait(0.5); |
wataaki | 0:a872e4dd8ec3 | 101 | } |
wataaki | 0:a872e4dd8ec3 | 102 | } |
wataaki | 0:a872e4dd8ec3 | 103 | pc.printf("シーケンシャル Sample End\r\n"); |
wataaki | 0:a872e4dd8ec3 | 104 | break; |
wataaki | 0:a872e4dd8ec3 | 105 | case 2: |
wataaki | 0:a872e4dd8ec3 | 106 | pc.printf("グラデーション Sample Start\r\n"); |
wataaki | 0:a872e4dd8ec3 | 107 | |
wataaki | 0:a872e4dd8ec3 | 108 | cmd[0] = MODE1; |
wataaki | 0:a872e4dd8ec3 | 109 | cmd[1] = 0x0; // SLEEP = 0 |
wataaki | 0:a872e4dd8ec3 | 110 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 111 | |
wataaki | 0:a872e4dd8ec3 | 112 | cmd[0] = LEDOUT0 + 0x80; // LEDOUT0, Auto incriment |
wataaki | 0:a872e4dd8ec3 | 113 | cmd[1] = 0x55; // LED3,2,1,0 01= ON |
wataaki | 0:a872e4dd8ec3 | 114 | cmd[2] = 0x05; // LED7,6 00= OFF LED5,4 01= ON |
wataaki | 0:a872e4dd8ec3 | 115 | cmd[3] = 0x00; // LED11,10,9,8 00= OFF |
wataaki | 0:a872e4dd8ec3 | 116 | cmd[4] = 0x00; // LED15,14,13,12 00= OFF |
wataaki | 0:a872e4dd8ec3 | 117 | i2c.write(PCA9955A_ADDR, cmd, 5); // cmd[0]Regにcmd[1-4]を書込み |
wataaki | 0:a872e4dd8ec3 | 118 | |
wataaki | 0:a872e4dd8ec3 | 119 | /* cmd[0] = PWMALL; |
wataaki | 0:a872e4dd8ec3 | 120 | cmd[1] = 0xFF; // PWM = 99.6% |
wataaki | 0:a872e4dd8ec3 | 121 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 122 | */ |
wataaki | 0:a872e4dd8ec3 | 123 | cmd[0] = GRAD_GRP_SEL1; |
wataaki | 0:a872e4dd8ec3 | 124 | cmd[1] = 0x50; // LED3, 4 = GRP0 |
wataaki | 0:a872e4dd8ec3 | 125 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 126 | |
wataaki | 0:a872e4dd8ec3 | 127 | cmd[0] = IREFALL; // |
wataaki | 0:a872e4dd8ec3 | 128 | cmd[1] = 0x1; // あとでIREF_GRP0で設定するので1以上であればよい |
wataaki | 0:a872e4dd8ec3 | 129 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 130 | /* cmd[0] = IREF4; // |
wataaki | 0:a872e4dd8ec3 | 131 | cmd[1] = 0x1; // Idrv = 240 * 40uA(Rext = 5.6k)=9.6mA |
wataaki | 0:a872e4dd8ec3 | 132 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 133 | */ |
wataaki | 0:a872e4dd8ec3 | 134 | cmd[0] = GRAD_MODE_SEL0; |
wataaki | 0:a872e4dd8ec3 | 135 | cmd[1] = 0x31; // LED0, 4, 5 = Gradation |
wataaki | 0:a872e4dd8ec3 | 136 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 137 | |
wataaki | 0:a872e4dd8ec3 | 138 | cmd[0] = GRAD_GRP_SEL0; |
wataaki | 0:a872e4dd8ec3 | 139 | cmd[1] = 0x0; // LED0, 1, 2, 3 = GRP0 |
wataaki | 0:a872e4dd8ec3 | 140 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 141 | |
wataaki | 0:a872e4dd8ec3 | 142 | |
wataaki | 0:a872e4dd8ec3 | 143 | cmd[0] = IREF_GRP0; |
wataaki | 0:a872e4dd8ec3 | 144 | cmd[1] = 0xF0; // Idrv = 240 * 40uA(Rext = 5.6k)=9.6mA |
wataaki | 0:a872e4dd8ec3 | 145 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 146 | |
wataaki | 0:a872e4dd8ec3 | 147 | cmd[0] = STEP_TIME_GRP0; |
wataaki | 0:a872e4dd8ec3 | 148 | cmd[1] = 0x3F; // 0.5ms * 64 = 32ms |
wataaki | 0:a872e4dd8ec3 | 149 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 150 | |
wataaki | 0:a872e4dd8ec3 | 151 | cmd[0] = RAMP_RATE_GRP0; |
wataaki | 0:a872e4dd8ec3 | 152 | cmd[1] = 0xc0 + 0x31; // Ramp up/down ON, Ramp rate = 50 |
wataaki | 0:a872e4dd8ec3 | 153 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 154 | |
wataaki | 0:a872e4dd8ec3 | 155 | cmd[0] = HOLD_CNTL_GRP0; |
wataaki | 0:a872e4dd8ec3 | 156 | cmd[1] = 0xc0 + (0x1 << 3) + 0x2; // Hold ON/OFF ON, ON = 0.25s, OFF = 0.5s |
wataaki | 0:a872e4dd8ec3 | 157 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 158 | |
wataaki | 0:a872e4dd8ec3 | 159 | cmd[0] = GRAD_CNTL; |
wataaki | 0:a872e4dd8ec3 | 160 | cmd[1] = 0x3; // Gradation ON, Continuous |
wataaki | 0:a872e4dd8ec3 | 161 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 162 | |
wataaki | 0:a872e4dd8ec3 | 163 | wait(15); // 15s 待つ |
wataaki | 0:a872e4dd8ec3 | 164 | |
wataaki | 0:a872e4dd8ec3 | 165 | cmd[0] = GRAD_CNTL; |
wataaki | 0:a872e4dd8ec3 | 166 | cmd[1] = 0x0; // Gradation OFF |
wataaki | 0:a872e4dd8ec3 | 167 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 168 | |
wataaki | 0:a872e4dd8ec3 | 169 | cmd[0] = GRAD_MODE_SEL0; |
wataaki | 0:a872e4dd8ec3 | 170 | cmd[1] = 0x0; // LED0, 4, 5 = Normal |
wataaki | 0:a872e4dd8ec3 | 171 | i2c.write(PCA9955A_ADDR, cmd, 2); // cmd[0]Regにcmd[1]を書込み |
wataaki | 0:a872e4dd8ec3 | 172 | |
wataaki | 0:a872e4dd8ec3 | 173 | pc.printf("グラデーション Sample End\r\n"); |
wataaki | 0:a872e4dd8ec3 | 174 | break; |
wataaki | 0:a872e4dd8ec3 | 175 | default: |
wataaki | 0:a872e4dd8ec3 | 176 | break; |
wataaki | 0:a872e4dd8ec3 | 177 | } |
wataaki | 0:a872e4dd8ec3 | 178 | } |
wataaki | 0:a872e4dd8ec3 | 179 | } |
wataaki | 0:a872e4dd8ec3 | 180 |