//define bidirectional address-data bus #define ad0 2 #define ad1 3 #define ad2 4 #define ad3 5 #define ad4 6 #define ad5 7 #define ad6 8 #define ad7 9 //ALE or address strobe (AS pin) #define as 10 //RD or OE (DS pin ) #define ds 12 //WR or (RW pin) #define rw 11 #define regA 0x0A #define regB 0x0B //RO registers C,D #define regC 0x0C #define regD 0x0D void bus2out(); void bus2in(); byte readbyte(byte address); void writebyte(byte address,byte value); boolean adjust(byte address); char msgs[7][4] = {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; void setup() { Serial.begin(9600); pinMode(as, OUTPUT); pinMode(ds, OUTPUT); pinMode(rw, OUTPUT); //delay after power up to start-up digitalWrite(as,LOW); digitalWrite(ds,LOW); digitalWrite(rw,LOW); delay(200);//to finish power set up } void loop() { if (Serial.available() > 0) { int inByte = Serial.read(); switch (inByte) { case 'h': if (adjust(4)) Serial.println("Hours updated"); break; case 'm': if (adjust(2)) Serial.println("Minutes updated"); break; case 'D': if (adjust(7)) Serial.println("Day updated"); break; case 'M': if (adjust(8)) Serial.println("Month updated"); break; case 'Y': if (adjust(9)) Serial.println("Year updated"); break; case 's': if (adjust(0)) Serial.println("Seconds reset"); break; case 't': //show current time and date //test UIP (update in progress) bit in Reg A if (!bitRead(readbyte(regA),7)) { Serial.print(readbyte(4),DEC); Serial.print(':'); Serial.print(readbyte(2),DEC); Serial.print(':'); Serial.print(readbyte(0),DEC); Serial.print(' '); Serial.print(readbyte(7),DEC); Serial.print('.'); Serial.print(readbyte(8),DEC); Serial.print('.'); Serial.print(readbyte(9),DEC); Serial.print(' '); byte day = readbyte(6)-1; // 1=Sunday char* msg = msgs[day]; Serial.print(msg); Serial.println(); } break; case 'R': //show regs values Serial.print("A: "); Serial.print(readbyte(regA),BIN); Serial.println(); Serial.print("B: "); Serial.print(readbyte(regB),BIN); Serial.println(); Serial.print("C: "); Serial.print(readbyte(regC),BIN); Serial.println(); Serial.print("D: "); Serial.print(readbyte(regD),BIN); Serial.println(); break; case 'i': //initalize byte b = readbyte(regB); b = b|0x80; writebyte(regB,b); b=b|0x07; writebyte(regB,b); writebyte(0,0x15); writebyte(1,0x15); writebyte(2,0x3A); writebyte(3,0x3A); writebyte(4,0x05); writebyte(5,0x05); writebyte(6,0x05); writebyte(7,0x03); writebyte(8,0x0C); writebyte(9,0x09); b=b&0x7F; writebyte(regB,b); Serial.print("init done"); Serial.println(); break; // default: } } }//end of loop void bus2out(){ pinMode(ad0,OUTPUT); pinMode(ad1,OUTPUT); pinMode(ad2,OUTPUT); pinMode(ad3,OUTPUT); pinMode(ad4,OUTPUT); pinMode(ad5,OUTPUT); pinMode(ad6,OUTPUT); pinMode(ad7,OUTPUT); } void bus2in(){ pinMode(ad0,INPUT); pinMode(ad1,INPUT); pinMode(ad2,INPUT); pinMode(ad3,INPUT); pinMode(ad4,INPUT); pinMode(ad5,INPUT); pinMode(ad6,INPUT); pinMode(ad7,INPUT); } byte readbyte(byte address){ byte readb=0; //set address pins to output bus2out(); //start READ cycle digitalWrite(rw,HIGH); //prepare to set address on bus digitalWrite(ds,HIGH); //delayMicroseconds(1); //set ALE high, on fall address latches digitalWrite(as,HIGH); //delayMicroseconds(1); //set address on bus digitalWrite(ad0,bitRead(address,0)); digitalWrite(ad1,bitRead(address,1)); digitalWrite(ad2,bitRead(address,2)); digitalWrite(ad3,bitRead(address,3)); digitalWrite(ad4,bitRead(address,4)); digitalWrite(ad5,bitRead(address,5)); digitalWrite(ad6,bitRead(address,6)); digitalWrite(ad7,bitRead(address,7)); //delayMicroseconds(1); //set ALE low, latch address digitalWrite(as,LOW); bus2in(); //delayMicroseconds(1); //finish address setting digitalWrite(ds,LOW); //wait for data from address //set bus for input //delayMicroseconds(1); //start reading data readb = digitalRead(ad0)|(digitalRead(ad1)<<1)|(digitalRead(ad2)<<2)|(digitalRead(ad3)<<3)|(digitalRead(ad4)<<4)|(digitalRead(ad5)<<5)|(digitalRead(ad6)<<6)|(digitalRead(ad7)<<7); digitalWrite(ds,HIGH); //delayMicroseconds(1); return readb; } void writebyte(byte address,byte value){ //set address pins to output bus2out(); //start READ cycle digitalWrite(rw,HIGH); //prepare to set address on bus digitalWrite(ds,HIGH); //delayMicroseconds(1); //set ALE high, on fall address latches digitalWrite(as,HIGH); //set address on bus digitalWrite(ad0,bitRead(address,0)); digitalWrite(ad1,bitRead(address,1)); digitalWrite(ad2,bitRead(address,2)); digitalWrite(ad3,bitRead(address,3)); digitalWrite(ad4,bitRead(address,4)); digitalWrite(ad5,bitRead(address,5)); digitalWrite(ad6,bitRead(address,6)); digitalWrite(ad7,bitRead(address,7)); //set ALE low, latche address //delayMicroseconds(1); digitalWrite(as,LOW); //delayMicroseconds(1); digitalWrite(rw,LOW); //set byte to write digitalWrite(ad0,bitRead(value,0)); digitalWrite(ad1,bitRead(value,1)); digitalWrite(ad2,bitRead(value,2)); digitalWrite(ad3,bitRead(value,3)); digitalWrite(ad4,bitRead(value,4)); digitalWrite(ad5,bitRead(value,5)); digitalWrite(ad6,bitRead(value,6)); digitalWrite(ad7,bitRead(value,7)); //delayMicroseconds(1); //finish write, latch data digitalWrite(rw,HIGH); //delayMicroseconds(1); } boolean adjust(byte address){ //read current value byte value=0; byte b; if ( (address<0) || (address > 10)) return false; if (!bitRead(readbyte(regA),7)) value = readbyte(address); b = readbyte(regB); //set SET bit of register B that will prevent double buffer update from internal buffer b=b|0x80; writebyte(regB,b); if (bitRead(readbyte(regB),7)) {//start upd switch (address){ case 0: //seconds writebyte(address,0); //min break; case 1: //seconds alarm if (value == 59) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; case 2: //minutes if (value == 59) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; case 3: //minutes alarm if (value == 59) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; case 4: //hours if (value == 23) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; case 5: //hours alarm if (value == 23) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; case 6: //day of week if (value == 7) {writebyte(address,1);} else { value++; writebyte(address,value); //min } break; case 7: //day of month, this must be modified in future!!!! if (value == 31) {writebyte(address,1);} else { value++; writebyte(address,value); //min } break; case 8: //month if (value == 12) {writebyte(address,1);} else { value++; writebyte(address,value); //min } break; case 9: //year if (value == 99) {writebyte(address,0);} else { value++; writebyte(address,value); //min } break; // default: }//end switch }//end upd //mask regA and clear SET bit b=b&0x7F; writebyte(regB,b); return true; }