16-channel Fm+ I2C-bus 57 mA/20 V constant current LED driver

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
wataaki
Date:
Wed Feb 04 06:09:08 2015 +0000
Commit message:
Initial version

Changed in this revision

PCA9955A.cpp Show annotated file Show diff for this revision Revisions of this file
PCA9955A.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r a872e4dd8ec3 PCA9955A.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9955A.cpp	Wed Feb 04 06:09:08 2015 +0000
@@ -0,0 +1,180 @@
+#include "mbed.h"
+#include "PCA9955A.h"
+ 
+I2C i2c(p28,p27);        // sda, scl
+Serial pc(USBTX, USBRX); // tx, rx
+char cmd[32];
+int i, j, k;
+int sw;
+ 
+void set_ch(char sel)
+{    // PCA9541のサンプル
+        // MST_0側の自分にスレーブ側の制御権を得る場合
+    cmd[0] = 1;                     // PCA9541 コマンドコード Cont Reg
+    i2c.write( 0xe2, cmd, 1);       // Cont Regを指定
+    i2c.read( 0xe2, cmd, 1);        // Cont Regを読込み
+    wait(0.1);                      // 0.1s待つ
+    switch(cmd[0] & 0xf)
+    {
+    case 0:                         // bus off, has control
+    case 1:                         // bus off, no control
+    case 5:                         // bus on, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 4;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 2:                         // bus off, no control
+    case 3:                         // bus off, has control
+    case 6:                         // bus on, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 5;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 9:                         // bus on, no control
+    case 0xc:                       // bus on, no control
+    case 0xd:                       // bus off, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 0;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 0xa:                       // bus on, no control
+    case 0xe:                       // bus off, no control
+    case 0xf:                       // bus on, has control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 1;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    default:
+        break;
+    }
+
+    cmd[0] = sel;                   // PCA9546 Cont Reg sel channel enabled
+    i2c.write( 0xe8, cmd, 1);       // Send command string
+}
+
+int main ()
+{
+    i2c.frequency(100000);
+    pc.printf("PCA9955A Sample Program\r\n");
+    
+    set_ch(1);              // PCA9955Aはch0に接続
+    
+  // PCA9955A
+    while(1)
+    {
+        pc.printf("シーケンシャル … 1, グラデーション … 2 ? \r\n");
+        pc.scanf("%d", &sw);
+        pc.printf("%d\r\n", sw);
+        switch (sw)
+        {
+        case 1:
+            pc.printf("シーケンシャル Sample Start\r\n");
+
+            cmd[0] = MODE1;
+            cmd[1] = 0x0;           // SLEEP = 0
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = LEDOUT0 + 0x80;   // LEDOUT0, Auto incriment
+            cmd[1] = 0xaa;          // LED3,2,1,0 10= PWM
+            cmd[2] = 0xaa;          // LED7,6,5,4 10= PWM
+            cmd[3] = 0xaa;          // LED11,10,9,8 10= PWM
+            cmd[4] = 0xaa;          // LED15,14,13,12 10= PWM
+            i2c.write(PCA9955A_ADDR, cmd, 5);   // cmd[0]Regにcmd[1-4]を書込み
+
+            cmd[0] = IREF0 + 0x80;           // IREF0, Auto incriment
+            for(i=0; i<16; i++)  cmd[i+1] = 0x80;   // all IREF = 50%
+            i2c.write(PCA9955A_ADDR, cmd, 17);   // cmd[0]Regにcmd[1-16]を書込み
+
+            for(k=0; k<3; k++)      // 3回繰返す
+            {
+                for(i=0; i<16; i++) // チャネル0~15まで一つずつ点灯
+                {
+                    cmd[0] = PWM0 + 0x80;           // PWM0, Auto incriment
+                    for(j=0; j<16; j++)  cmd[j+1] = 0x0;   // all LED PWM = 0%
+                    cmd[i+1] = 0xff;   // iチャネルのLED PWM = 99.6%
+                    i2c.write(PCA9955A_ADDR, cmd, 17);   // cmd[0]Regにcmd[1-16]を書込み
+                    wait(0.5);
+                }
+            }
+            pc.printf("シーケンシャル Sample End\r\n");
+            break;
+        case 2:
+            pc.printf("グラデーション Sample Start\r\n");
+
+            cmd[0] = MODE1;
+            cmd[1] = 0x0;           // SLEEP = 0
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = LEDOUT0 + 0x80;   // LEDOUT0, Auto incriment
+            cmd[1] = 0x55;          // LED3,2,1,0 01= ON
+            cmd[2] = 0x05;          // LED7,6 00= OFF  LED5,4 01= ON 
+            cmd[3] = 0x00;          // LED11,10,9,8 00= OFF
+            cmd[4] = 0x00;          // LED15,14,13,12 00= OFF
+            i2c.write(PCA9955A_ADDR, cmd, 5);   // cmd[0]Regにcmd[1-4]を書込み
+
+/*            cmd[0] = PWMALL;
+            cmd[1] = 0xFF;           // PWM = 99.6%
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+*/
+            cmd[0] = GRAD_GRP_SEL1;
+            cmd[1] = 0x50;           // LED3, 4 = GRP0
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = IREFALL;         //
+            cmd[1] = 0x1;           // あとでIREF_GRP0で設定するので1以上であればよい
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+/*            cmd[0] = IREF4;         //
+            cmd[1] = 0x1;           // Idrv = 240 * 40uA(Rext = 5.6k)=9.6mA
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+*/
+            cmd[0] = GRAD_MODE_SEL0;
+            cmd[1] = 0x31;           // LED0, 4, 5 = Gradation
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = GRAD_GRP_SEL0;
+            cmd[1] = 0x0;           // LED0, 1, 2, 3 = GRP0
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+
+            cmd[0] = IREF_GRP0;
+            cmd[1] = 0xF0;           // Idrv = 240 * 40uA(Rext = 5.6k)=9.6mA
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = STEP_TIME_GRP0;
+            cmd[1] = 0x3F;           // 0.5ms * 64 = 32ms
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = RAMP_RATE_GRP0;
+            cmd[1] = 0xc0 + 0x31;    // Ramp up/down ON, Ramp rate = 50
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = HOLD_CNTL_GRP0;
+            cmd[1] = 0xc0 + (0x1 << 3) + 0x2;   // Hold ON/OFF ON, ON = 0.25s, OFF = 0.5s
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = GRAD_CNTL;
+            cmd[1] = 0x3;           // Gradation ON, Continuous
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            wait(15);               // 15s 待つ
+
+            cmd[0] = GRAD_CNTL;
+            cmd[1] = 0x0;           // Gradation OFF
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            cmd[0] = GRAD_MODE_SEL0;
+            cmd[1] = 0x0;           // LED0, 4, 5 = Normal
+            i2c.write(PCA9955A_ADDR, cmd, 2);   // cmd[0]Regにcmd[1]を書込み
+
+            pc.printf("グラデーション Sample End\r\n");
+            break;
+        default:
+            break;
+        }    
+    }
+}
+
diff -r 000000000000 -r a872e4dd8ec3 PCA9955A.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9955A.h	Wed Feb 04 06:09:08 2015 +0000
@@ -0,0 +1,77 @@
+//#define PCA9955_ADDR 0xEC
+#define PCA9955A_ADDR 0x02
+
+#define MODE1            0x00
+#define MODE2            0x01
+#define LEDOUT0          0x02
+#define LEDOUT1          0x03
+#define LEDOUT2          0x04
+#define LEDOUT3          0x05
+#define GRPPWM           0x06
+#define GRPFREQ          0x07
+#define PWM0             0x08
+#define PWM1             0x09
+#define PWM2             0x0A
+#define PWM3             0x0B
+#define PWM4             0x0C
+#define PWM5             0x0D
+#define PWM6             0x0E
+#define PWM7             0x0F
+#define PWM8             0x10
+#define PWM9             0x11
+#define PWM10            0x12
+#define PWM11            0x13
+#define PWM12            0x14
+#define PWM13            0x15
+#define PWM14            0x16
+#define PWM15            0x17
+#define IREF0            0x18
+#define IREF1            0x19
+#define IREF2            0x1A
+#define IREF3            0x1B
+#define IREF4            0x1C
+#define IREF5            0x1D
+#define IREF6            0x1E
+#define IREF7            0x1F
+#define IREF8            0x20
+#define IREF9            0x21
+#define IREF10           0x22
+#define IREF11           0x23
+#define IREF12           0x24
+#define IREF13           0x25
+#define IREF14           0x26
+#define IREF15           0x27
+#define RAMP_RATE_GRP0   0x28
+#define STEP_TIME_GRP0   0x29
+#define HOLD_CNTL_GRP0   0x2A
+#define IREF_GRP0        0x2B
+#define RAMP_RATE_GRP1   0x2C
+#define STEP_TIME_GRP1   0x2D
+#define HOLD_CNTL_GRP1   0x2E
+#define IREF_GRP1        0x2F
+#define RAMP_RATE_GRP2   0x30
+#define STEP_TIME_GRP2   0x31
+#define HOLD_CNTL_GRP2   0x32
+#define IREF_GRP2        0x33
+#define RAMP_RATE_GRP3   0x34
+#define STEP_TIME_GRP3   0x35
+#define HOLD_CNTL_GRP3   0x36
+#define IREF_GRP3        0x37
+#define GRAD_MODE_SEL0   0x38
+#define GRAD_MODE_SEL1   0x39
+#define GRAD_GRP_SEL0    0x3A
+#define GRAD_GRP_SEL1    0x3B
+#define GRAD_GRP_SEL2    0x3C
+#define GRAD_GRP_SEL3    0x3D
+#define GRAD_CNTL        0x3E
+#define OFFSET           0x3F
+#define SUBADR1          0x40
+#define SUBADR2          0x41
+#define SUBADR3          0x42
+#define ALLCALLADR       0x43
+#define PWMALL           0x44
+#define IREFALL          0x45
+#define EFLAG0           0x46
+#define EFLAG1           0x47
+#define EFLAG2           0x48
+#define EFLAG3           0x49
diff -r 000000000000 -r a872e4dd8ec3 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Feb 04 06:09:08 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file