Text Clock

I purchased a couple of boards on Ebay populated with ten Siemens SP5-77 alphanumeric displays apiece.  Twenty displays is just enough to populate a text clock.  The top line is the hours (longest word, "Twelve"), the second is the tens of minutes (longest word, "Seventeen"), and the bottom line is the ones of minutes (longest word, "Seven").  I use a Dallas DS3231 integrated real time clock / temperature adjusted crystal for timekeeping, with a supercap for power backup.  Extracting the displays from the boards wasn't hard.  However, the SP5-77 is a parallel-load device, so wiring up twenty of them got pretty messy, as you can see below.  On the positive side, the AVR output pins are capable of driving twenty of the SP5-77s:

I had to write an I2C driver for the DS3231, which is listed below. The code uses the following I2C primitives:

#define DS3231_ADDR 0xD0 
void read_time(unsigned char *h, unsigned char *m, unsigned char *s){ 
	unsigned char c1, c2, c3; 
	i2c_start(); 
	i2c_write(DS3231_ADDR );
	ic_write(0); 
	i2c_stop(); 
	i2c_start(); 
	i2c_write(DS3231_ADDR | 1); 
	c1=i2c_read(1); 
	c2=i2c_read(1); 
	c3=i2c_read(0); 
	i2c_stop();
	*s=10*((c1&0x70)>>4) + (c1 & 0x0f); 
	*m=10*((c2&0x70)>>4) + (c2 & 0x0f); 
	*h=10*((c3&0x30)>>4) + (c3 & 0x0f); 
} 
void write_time(unsigned char h, unsigned char m, unsigned char s){ 
	unsigned char c1,c2,c3; 
	c1=(s%10)+((s/10)<<4); 
	c2=(m%10)+((m/10)<<4); 
	c3=(h%10)+((h/10)<<4); 
	i2c_start(); 
	i2c_write(DS3231_ADDR ); 
	i2c_write(0); 
	i2c_write(c1); 
	i2c_write(c2); 
	i2c_write(c3); 
	i2c_stop(); 
}