/* Bit-banging serial output routine for shift registers like the 74HC595 * Matt Sarnoff (www.msarnoff.org) * * Note that setting or clearing a bit in an I/O register (SBI/CBI instructions) * takes two cycles, but loading an I/O register (OUT instruction) * only takes one. */ #define set_bit(v,b) v |= _BV(b) #define clear_bit(v,b) v &= ~_BV(b) #define pulse_bit(v,b) do { set_bit(v,b); clear_bit(v,b); } while(0) #define pulse_bit_low(v,b) do { clear_bit(v,b); set_bit(v,b); } while(0) #define CLK 6 #define DATA 7 #define STROBE 1 void serialout16(unsigned int c) { register uint8_t port = PORTD; register uint8_t portdata = port | _BV(DATA); if (c & _BV(15)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(14)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(13)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(12)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(11)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(10)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(9)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(8)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(7)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(6)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(5)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(4)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(3)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(2)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(1)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; if (c & _BV(0)) PORTD = portdata; set_bit(PORTD, CLK); PORTD = port; pulse_bit(PORTB, STROBE); }