DM13A 16-bit Constant Current LED Driver

used products:

1. Arduino UNO
2. DM13A

Arduino:

#define PIN_LATCH 8 #define PIN_CLOCK 10 #define PIN_DAI 11 void setup() { pinMode(PIN_LATCH, OUTPUT); pinMode(PIN_CLOCK, OUTPUT); pinMode(PIN_DAI, OUTPUT); digitalWrite(PIN_LATCH, LOW); digitalWrite(PIN_DAI, LOW); digitalWrite(PIN_CLOCK, LOW); for (int i = 0; i < 16; i++) { doLow(); doLatch(); } } void loop() { for (int i = 0; i < 8; i++) { doHigh(); doLatch(); delay(100); doLow(); doLatch(); delay(100); } for (int i = 0; i < 16; i++) { doHigh(); doLatch(); delay(100); } for (int i = 0; i < 16; i++) { doLow(); doLatch(); delay(100); } } void doLatch() { digitalWrite(PIN_LATCH, HIGH); digitalWrite(PIN_LATCH, LOW); } void doClock() { digitalWrite(PIN_CLOCK, HIGH); digitalWrite(PIN_CLOCK, LOW); } void doLow() { digitalWrite(PIN_DAI, LOW); doClock(); } void doHigh() { digitalWrite(PIN_DAI, HIGH); doClock(); }

C:

#ifndef F_CPU #define F_CPU 1000000UL #endif #define PIN_LATCH PB0 #define PIN_CLOCK PB2 #define PIN_DAI PB3 #include <avr/io.h> #include <util/delay.h> void doLatch(); void doClock(); void doLow(); void doHigh(); int main(void) { DDRB |= (1<<PIN_LATCH); DDRB |= (1<<PIN_CLOCK); DDRB |= (1<<PIN_DAI); PORTB &= ~(1<<PIN_LATCH); PORTB &= ~(1<<PIN_CLOCK); PORTB &= ~(1<<PIN_DAI); for (int i = 0; i < 16; i++) { doLow(); doLatch(); } while (1) { for (int i = 0; i < 8; i++) { doHigh(); doLatch(); _delay_ms(100); doLow(); doLatch(); _delay_ms(100); } for (int i = 0; i < 16; i++) { doHigh(); doLatch(); _delay_ms(100); } for (int i = 0; i < 16; i++) { doLow(); doLatch(); _delay_ms(100); } } return 0; } void doLatch() { PORTB |= (1<<PIN_LATCH); PORTB &= ~(1<<PIN_LATCH); } void doClock() { PORTB |= (1<<PIN_CLOCK); PORTB &= ~(1<<PIN_CLOCK); } void doLow() { PORTB &= ~(1<<PIN_DAI); doClock(); } void doHigh() { PORTB |= (1<<PIN_DAI); doClock(); }

Assembler:

.nolist .include "./m328Pdef.inc" .list .equ PIN_LATCH = PB0 .equ PIN_CLOCK = PB2 .equ PIN_DAI = PB3 .def temp = r16 .org 0x0000 rjmp start start: ldi temp, high(RAMEND) out sph, temp ldi temp, low(RAMEND) out spl, temp ldi temp, (1<<PIN_LATCH)|(1<<PIN_CLOCK)|(1<<PIN_DAI) out DDRB, temp cbi PORTB, PIN_LATCH cbi PORTB, PIN_CLOCK cbi PORTB, PIN_DAI ldi temp, 16 clear: rcall doLow rcall doLatch dec temp cpi temp, 0 brne clear loop: ldi temp, 8 updown: rcall doHigh rcall doLatch rcall delay_500ms rcall doLow rcall doLatch rcall delay_500ms dec temp cpi temp, 0 brne updown ldi temp, 16 up: rcall doHigh rcall doLatch rcall delay_500ms dec temp cpi temp, 0 brne up ldi temp, 16 down: rcall doLow rcall doLatch rcall delay_500ms dec temp cpi temp, 0 brne down rcall delay_500ms rjmp loop doLatch: sbi PORTB, PIN_LATCH cbi PORTB, PIN_LATCH ret doClock: sbi PORTB, PIN_CLOCK cbi PORTB, PIN_CLOCK ret doLow: cbi PORTB, PIN_DAI rcall doClock ret doHigh: sbi PORTB, PIN_DAI rcall doClock ret delay_500ms: ; the subroutine: ldi r18, 8 ; load r18 with 31 OUTER_LOOP: ; outer loop label ldi r24, 0xfd ; load registers r24:r25 with 1021, our new ; init value ldi r25, 0x03 ; the loop label DELAY_LOOP: ; "add immediate to word": r24:r25 are ; incremented adiw r24, 1 ; if no overflow ("branch if not equal"), go ; back to "delay_loop" brne DELAY_LOOP dec r18 ; decrement r18 brne OUTER_LOOP ; and loop if outer loop not finished ret ; return from subroutine

Great Cow BASIC:

#chip mega328p #define PIN_LATCH PortB.0 #define PIN_CLOCK PortB.2 #define PIN_DAI PortB.3 Dir PIN_LATCH Out Dir PIN_CLOCK Out Dir PIN_DAI Out PIN_LATCH = 0 PIN_CLOCK = 0 PIN_DAI = 0 for ii = 1 to 16 doLow() doLatch() next Do Forever for ii = 1 to 8 doHigh() doLatch() Wait 100 ms doLow() doLatch() Wait 100 ms next for ii = 1 to 16 doHigh() doLatch() Wait 100 ms next for ii = 1 to 16 doLow() doLatch() Wait 100 ms next Loop sub doLatch() PIN_LATCH = 1 PIN_LATCH = 0 end sub sub doClock() PIN_CLOCK = 1 PIN_CLOCK = 0 end sub sub doLow() PIN_DAI = 0 doClock() end sub sub doHigh() PIN_DAI = 1 doClock() end sub