/* ** ################################################################### ** Filename : DS1307_test.c ** Compiler : CodeWarrior compiler ** DataSheet : DS1307 64x8, Serial, IIC Real-Time Clock ** REV: 071405 ** Processor : MC68HC908JL16CSPE ** Date/Time : 2.27.2008 ** Abstract : ** This is the complete program file for SPRING 2008 for ** EE459L - Embedded Systems Design Laboratory Senior Design ** Project. ** ** ** Omair Khan ** University of Southern California ** www.omair-khan.com ** ** ** Revisions: ** none ** ** ################################################################### */ #include /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #include "ds1307.h" /* include DS1307 definitions */ /* The following puts the dummy interrupt service routine at location MY_ISR_ROM which is defined in the PRM file as the start of the FLASH ROM */ #pragma CODE_SEG MY_ISR_ROM #pragma TRAP_PROC void dummyISR(void) { } /* This pragma sets the code storage back to default area of ROM as defined in the PRM file. */ #pragma CODE_SEG DEFAULT void init_uP(void); void del1m(int d); void wait_100ms(void); void blink_LED(int x); void init_LCD(void); void writeLCDcmd(unsigned char data,int a); void writeNUM(int a); void IIC_trans_start(unsigned char devAddress,unsigned char regAddrLSB); void IIC_trans_ack(unsigned char nextNextData); void IIC_rec_start(unsigned char devAddress); void IIC_rec_wait(void); void IIC_rec_disableAck(void); void IIC_stop(void); void DS1307_reg_init(void); void set_dummy_alarm(void); void DS1307_update_time(void); void DS1307_save_alarm(void); void DS1307_read_time(void); void display_curr_time(void); void alarm(void); #pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE unsigned int delay0; unsigned int delay1; unsigned char flag=0; /* ********************************** * * * Main * * * ********************************** */ void main(void) { int rc=0; init_uP(); init_LCD(); DS1307_reg_init(); DS1307_update_time(); set_dummy_alarm(); DS1307_save_alarm(); while (1) { DS1307_read_time(); display_curr_time(); alarm(); } /* please make sure that you never leave this function */ } /* ********************************************************************************* * * * Functions * * * ********************************************************************************* */ void init_uP(){ CONFIG1_COPD = 1; // disable COP reset CONFIG2_IICSEL=1; //Set MMIIC SDA on PTA2 & SCL on PTA3 DDRA_DDRA5=1; PTA_PTA5=0; // reset lcd DDRB = 0xFF; //set port B for output (LCD DATABUS) DDRA_DDRA0=1; //LED (NIGHTLIGHT) DDRA_DDRA1=1; //LCD /WR PTA_PTA1=1; DDRA_DDRA4=1; //LCD A0 PTA_PTA4=1; DDRD_DDRD1=1; //LCD /CS PTD_PTD1=1; MIMCR_MMBR2=0; //Set Baudrate to (internal clk / 32) MIMCR_MMBR1=1; //10MHZ/4 = 2500000 hz MIMCR_MMBR0=0; //2500000/32 = 78125 hz MMCR_MMEN=1; //Enable MMIIC } /* ********************************** * * * LCD * * * ********************************** */ void init_LCD() { int ra=0; PTA_PTA5=1; // deactivate reset writeLCDcmd(0x58,1); //turn off display writeLCDcmd(0x40,1); //initialize LCD writeLCDcmd(0x30,0); //Int CG, 32chr CGRAM, 8lines/char, single pane, No invert, lcd, normal shift clock writeLCDcmd(0x87,0); //8 pixel wide characters, 2 frame AC drive writeLCDcmd(0x07,0); //vertical char size=8 pixels writeLCDcmd(0x1F,0); //32 display bytes per line writeLCDcmd(0x23,0); //tot. addr range per line (4 extra for horz blk) writeLCDcmd(0x7F,0); //128 display lines writeLCDcmd(0x20,0); //low byte of virtual screen width writeLCDcmd(0x00,0); //high byte of virtual screen width writeLCDcmd(0x44,1); //send scroll cmd writeLCDcmd(0x00,0); //set layer 1 home addr to 0x0000 writeLCDcmd(0x00,0); writeLCDcmd(0x7F,0); //128 lines for layer 1 writeLCDcmd(0x00,0); //set layer 2 (graphic) home address to 0x1000 writeLCDcmd(0x10,0); writeLCDcmd(0x7F,0); //128 lines for layer 2 //layers 3 and 4 not used writeLCDcmd(0x5A,1); //set hor scroll cmd writeLCDcmd(0x00,0); //no hor scroll adjustment writeLCDcmd(0x5B,1); //set overlay selections cmd writeLCDcmd(0x00,0); //OR layers, text block 1, 2 layer (layer 2 can only be graphic) writeLCDcmd(0x4C,1); //auto cursor increment +1 cmd writeLCDcmd(0x46,1); //cursor write cmd writeLCDcmd(0x00,0); //0x00 addr writeLCDcmd(0x00,0); writeLCDcmd(0x42,1); //send mwrite cmd //for a total of 512 ascii spaces (0x20) for(ra=1;ra<512;++ra) writeLCDcmd(0x20,0); //send 7168 zeros of data to clr out CGRAM area //(28 x 256 = 7168) //from 0400h to 0FFFh and the graphics area from //1000h to 1FFFh for(ra=0; ra<3584; ++ra) writeLCDcmd(0x00,0); for(ra=0; ra<4096; ++ra) writeLCDcmd(0x00,0); writeLCDcmd(0x5D,1); //set cursor format writeLCDcmd(0x04,0); //five pixels wide writeLCDcmd(0x86,0); //vertical cursor size=7 pixels block cursor writeLCDcmd(0x59,1); //display ON writeLCDcmd(0b00010100,0); //(0b00010100) no layer 3, show layer 2, show layer 1, no cursor writeLCDcmd(0x5C,1); //set CGRAM addr cmd writeLCDcmd(0x00,0); //CGRAM addr = 0x0400 writeLCDcmd(0x04,0); //----- DISPLAY IS CLEARED AND ON ------ } void writeLCDcmd(unsigned char data,int a) { PTB = data; //put data on databus if(a==1) PTA_PTA4 = 1; //write to (0 = data, 1 = command) register if(a==0) PTA_PTA4 = 0; PTD_PTD1 = 0; //enable /CS PTA_PTA1 = 0; //enable /WR PTA_PTA1 = 1; //disable /WR PTD_PTD1 = 1; //disable /CS } void writeNUM(int a) { writeLCDcmd((0x30)+a,0); } /* del1m - Delay about 1msec times the "d" argument. */ void del1m(int d) { /* ; The following code delays 1 millisecond by looping. ; Total time is 4 + 2 * (3 + 256 * (4 + 3) + 4 + 3) = 3608 cycles ; A 12MHz external clock gives an internal CPU clock of 3MHz ; (333ns/cycle). Delay is then 1.2 milliseconds. Close enough. */ while (d--) { asm{ mov #$2,delay1 ; 4 cycles m1: clr delay0 ; 3 cycles m0: dec delay0 ; 4 cycles bne m0 ; 3 cycles dec delay1 ; 4 cycles bne m1 ; 3 cycles } } } void wait_100ms(void) { asm { LDA #97 ; 2 clocks STA delay1 ; 4 clocks w_del1: CLRA ; 1 clocks * 97 iterations STA delay0 ; 4 clocks * 97 iterations w_del0: LDA delay0 ; 4 clocks * 256 * 97 iterations DECA ; 1 clocks * 256 * 97 iterations STA delay0 ; 4 clocks * 256 * 97 iterations BNE w_del0 ; 3 clocks * 256 * 97 iterations LDA delay1 ; 4 clocks * 97 iterations DECA ; 1 clocks * 97 iterations STA delay1 ; 4 clocks * 97 iterations BNE w_del1 ; 3 clocks * 97 iterations } /* Total time is 2+4 + 97 * (1+4 + 256 * (4+1+4+3) + 4+1+4+3) = 299,639 cycles A 12MHz external clock gives an internal CPU clock of 3MHz (333ns/cycle). Delay is then .0997 seconds. Close enough. */ } void blink_LED(int x){ int ra=0,rc=0; //BLINK LED ON AND OFF x TIMES for(ra=0; ra