I'm posting some code here for Drizza on YouTube. Much of the original page text was lost, but I have the images and some text. So here's what I have.

I built the circuit on a dipmicro electronics PB1 proto board. Excellent little boards for building small one-off projects.

In these images I'm controlling the RTC with a PIC 18F2523. The display is a SparkFun serial 7-segment LED in SPI mode. The two red LEDs on the breadboard are debugging blinkers to help me get my code working right.

Here are some pics of the board. I built it on one end of the board so I could cut the other half off to use for something else. The battery holder was robbed off an obsolete PC mainboard.

In these images I'm controlling it (I think) with an 18F2550 on a TAP-28 board and displaying on a 16x2 LCD. I had a whole bunch of flakiness with the thing at this point. After some digging with the logic analyzer I discovered that the problem was the over long wiring. Added a ferrite ring and it was cured.

Video of a PIC 18F2523 using the RTC to display minutes/seconds on a SparkFun serial LED display using SPI.

Here's some DS3234 code for the 18F2523 and Sparkfun serial 7-segment LED. (Scroll way down for some 18F2550/LCD code.)
#include <system.h>
#pragma CLOCK_FREQ 8000000
#pragma DATA    _CONFIG1H, _OSC_INTIO67_1H
#pragma DATA    _CONFIG2H, _WDT_OFF_2H
#pragma DATA    _CONFIG3H, _MCLRE_ON_3H
#pragma DATA    _CONFIG4L, _LVP_OFF_4L
#pragma DATA    _CONFIG4L, _XINST_OFF_4L

#define CS  latc.2

void blink(void);
void qblink(void);
//ds3234 functions
unsigned char spi_read(void);
void spi_write(unsigned char);
unsigned char busycheck(void);
//display functions
void ser_string(const char *);
void rs_esc1(unsigned char);
void rs_esc2(unsigned char,unsigned char);
void rsdat(unsigned char,unsigned char,unsigned char,unsigned char,
    unsigned char,unsigned char,unsigned char,unsigned char,
    unsigned char,unsigned char,unsigned char,unsigned char);
void rscom(unsigned char,unsigned char);

unsigned char receive,rflag = 0,dflag = 0;
char *dayy[]={0,"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};

void interrupt(void){
    if(pir1.RCIF){          //RS-232 char received interrupt
        receive = rcreg;
        if(receive == 0x74)
            rflag = 1;
        pir1.RCIF = 0;
    }
    if(intcon.RBIF){        //RB4 interrupt-on-change
        dflag = 1;
        intcon.RBIF = 0;
    }
}

int main(void)
{
    unsigned char sec,sec10,min,min10,hour,hour10,temp1,temp2,temp3,temp4;
    unsigned char seconds,minutes,hours,temp_h,temp_l,x,y,z,am;
    unsigned char day,date,month,year,date_h,date_l,month_h,month_l,year_h,year_l;
    osccon = 0b01110010;        //8MHz internal
    adcon1 = 0b00001111;        //all digital
    cmcon = 0b00000111;         //comparators off
    trisa = 0;
    trisb = 0x10;               //RB4 input for interrupt on change
    trisc = 0b11000000;
    CS = 1;
    sspstat = 0b10000000;
    sspcon1 = 0b00110001;       //enable SPI, clock idle high, fosc/16
    spbrgh = 0x00;              //9600 baud
    spbrg = 0x22;
    txsta = 0b00100100;
    rcsta = 0b10010000;
    baudcon = 0b00001000;
    pie1.RCIE = 1;              //serial receive interrupt enable
    intcon = 0b11001000;        //enable interrupts, enable RB port change interrupt
    rs_esc2(0x32,0x4a);         //clear terminal
/*    CS = 0;
    spi_write(0x80);        //address & write enable
    spi_write(0x00);        //set seconds
    spi_write(0x15);        //set minutes
    spi_write(0x08);        //set 12 hour time & hours
    spi_write(0x04);        //set day
    spi_write(0x26);        //set date
    spi_write(0x01);        //set century/month
    spi_write(0x11);        //set year
    spi_write(0x00);        //set alarm1 sec
    spi_write(0x00);        //set alarm1 min
    spi_write(0x00);        //set alarm1 hour
    spi_write(0x00);        //set alarm1 day/date
    spi_write(0x00);        //set alarm2 min
    spi_write(0x00);        //set alarm2 hour
    spi_write(0x00);        //set alarm2 day/date
    spi_write(0x40);        //enable osc, enable sqw
    spi_write(0x00);
    CS = 1;*/
    while(1){
        if(rflag){
            intcon.RBIE = 0;
            rs_esc2(0x32,0x4a);         //clear terminal
            rs_esc1(0x48);
            x = porta;
            y = ((x & 0xf0) >> 4) + 0x30;
            if(y >> 0x39)
                y += 7;
            z = (x & 0x0f) + 0x30;
            if(z >> 0x39)
                z += 7;
            ser_string("PortA = ");
            rscom(y,z);
            rscom(0x0d,0x0a);

            x = portb;
            y = ((x & 0xf0) >> 4) + 0x30;
            if(y >> 0x39)
                y += 7;
            z = (x & 0x0f) + 0x30;
            if(z >> 0x39)
                z += 7;
            ser_string("PortB = ");
            rscom(y,z);
            rscom(0x0d,0x0a);

            x = portc;
            y = ((x & 0xf0) >> 4) + 0x30;
            if(y >> 0x39)
                y += 7;
            z = (x & 0x0f) + 0x30;
            if(z >> 0x39)
                z += 7;
            ser_string("PortC = ");
            rscom(y,z);
            rscom(0x0a,0x0d);

            delay_s(3);
            receive = 0;
            rflag = 0;
            intcon.RBIE = 1;
        }
        if(dflag){
            rs_esc2(0x32,0x4a);         //clear terminal
            rs_esc1(0x48);
            CS = 0;                     //read time & date
            spi_write(0x00);
            seconds = spi_read();
            minutes = spi_read();
            hours = spi_read();
            day = spi_read();
            date = spi_read();
            month = spi_read();
            year = spi_read();
            CS = 1;
            while(busycheck());         //check busy flag till clear
            CS = 0;                     //do temperature conversion
            spi_write(0x8e);
            spi_write(0x60);
            CS = 1;
            CS = 0;                     //read temp
            spi_write(0x11);
            temp_h = spi_read();
            temp_l = spi_read();
            CS = 1;

            sec = (seconds & 0x0f) + 0x30;          //do time digit prep
            sec10 = ((seconds & 0x70) >> 4) + 0x30;
            min = (minutes & 0x0f) + 0x30;
            min10 = ((minutes & 0x70) >> 4) + 0x30;
            hour = (hours & 0x0f) + 0x30;
            hour10 = ((hours & 0x10) >> 4) + 0x30;
            x = (hours & 0x20) >> 5;
            if(x)
                am = 0x41;      //A
            else
                am = 0x50;      //P
            rsdat(hour10,hour,0x3a,min10,min,0x3a,sec10,sec,am,0x4d,0x20,0x20);   //display time

            temp_l >>= 6;                           //do temp digit prep
            temp_l *= 25;
            temp4 = (temp_l % 10) + 0x30;
            temp3 = (temp_l / 10) + 0x30;
            temp2 = (temp_h % 10) + 0x30;
            temp1 = (temp_h / 10) + 0x30;
            rsdat(0x2d,0x20,0x20,temp1,temp2,0x2e,temp3,temp4,0xf8,0x43,0x0d,0x0a); //display temp

            x = day & 0x07;
            month_l = (month & 0x0f) + 0x30;
            month_h = ((month & 0x10) >> 4) + 0x30;
            date_l = (date & 0x0f) + 0x30;
            date_h = ((date & 0x30) >> 4) + 0x30;
            year_l = (year & 0x0f) + 0x30;
            year_h = ((year & 0xf0) >> 4) + 0x30;
            ser_string(dayy[x]);
            rsdat(0x20,month_h,month_l,0x2f,date_h,date_l,0x2f,0x32,0x30,year_h,year_l,0x0a);
            blink();
            dflag = 0;
        }
    }
}

unsigned char busycheck(void){
    unsigned char x;
    CS = 0;
    spi_write(0x0f);    //control/status register
    x = spi_read();
    CS = 1;
    x = (x & 0x04) >> 2;
    return x;
}

void blink(void){
    latb.0 = 0;
    delay_ms(20);
    latb.0 = 1;
}

void qblink(void){
    unsigned char x;
    for(x=0;x<25;x++){
        latb.0 = 0;
        delay_ms(20);
        latb.0 = 1;
        delay_ms(20);
    }
}

//*****************
//* spi functions *
//*****************
void spi_write(unsigned char x){
    unsigned char dummy;
    sspbuf = x;
    while(pir1.SSPIF == 0);
    dummy = sspbuf;
    pir1.SSPIF = 0;
}

unsigned char spi_read(void){
    unsigned char dat;
    sspbuf = 0x33;
    while(pir1.SSPIF == 0);
    dat = sspbuf;
    pir1.SSPIF = 0;
    return(dat);
}

//****************************
//* serial display functions *
//****************************

void ser_string(const char *str){
    while(*str){
        txreg = *str++;
        while(!txsta.TRMT);
    }
}

void rsdat(unsigned char n1,unsigned char n2,unsigned char n3,unsigned char n4,unsigned char n5,unsigned char n6,unsigned char n7,unsigned char n8,unsigned char n9,unsigned char n10,unsigned char n11,unsigned char n12){
    unsigned char j;
    unsigned char digit[12];
    digit[0] = n1; digit[1] = n2; digit[2] = n3; digit[3] = n4;
    digit[4] = n5; digit[5] = n6; digit[6] = n7; digit[7] = n8;
    digit[8] = n9; digit[9] = n10; digit[10] = n11; digit[11] = n12;
    for(j=0;j<12;j++){
        txreg = digit[j];
        while(!txsta.TRMT);
    }
}

void rscom(unsigned char num1, unsigned char num2){
    unsigned char j;
    unsigned char digit[1];
    digit[0] = num1; digit[1] = num2;
    for(j=0;j<2;j++){
        txreg = digit[j];
        while(!txsta.TRMT);
    }
}

void rs_esc1(unsigned char num1){
    unsigned char j;
    unsigned char digit[4];
    digit[0] = 0x1b; digit[1] = 0x5b; digit[2] = num1;
    for(j=0;j<3;j++){
        txreg = digit[j];
        while(!txsta.TRMT);
    }
}

void rs_esc2(unsigned char num1,unsigned char num2){
    unsigned char j;
    unsigned char digit[4];
    digit[0] = 0x1b; digit[1] = 0x5b; digit[2] = num1; digit[3] = num2;
    for(j=0;j<4;j++){
        txreg = digit[j];
        while(!txsta.TRMT);
    }
}



And here is the 18F2550/LCD code.
#include <system.h>
#include <stdio.h>
#pragma CLOCK_FREQ 4000000
//#pragma DATA    _CONFIG1H, _OSC_HS_1H
#pragma DATA    _CONFIG1H, _OSC_IRCIO67_1H
#pragma DATA    _CONFIG2H, _WDT_OFF_2H
#pragma DATA    _CONFIG3H, _MCLRE_ON_3H
#pragma DATA    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L

void blink(void);
//ds3234 functions
unsigned char spi_read(void);
void spi_write(unsigned char);
unsigned char busycheck(void);
//display functions
void lcd_cls();
void lcd_cmd(unsigned char);
void lcd_char(char);
void e_togg(void);
void lcd_init(void);
void lcd_string(char *);
void lcd_nybble(unsigned char,unsigned char);

#define LINE1   lcd_cmd(0x80);
#define LINE2   lcd_cmd(0xc0);
#define    CLOCK   latc.6
#define DATA    latc.7
#define CS      latc.2

char *dayy[]={0,"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
char string[] = "                ";
unsigned char dflag = 0;

void interrupt(void){
    if(intcon.RBIF){        //RB4 interrupt-on-change
        dflag = 1;
        intcon.RBIF = 0;
    }
}

int main(void)
{
    unsigned char sec,sec10,min,min10,hour,hour10,temp1,temp2,temp3,temp4;
    unsigned char seconds,minutes,hours,temp_h,temp_l,x,y,z,am;
    unsigned char day,date,month,year,date_h,date_l,month_h,month_l,year_h,year_l;
    osccon = 0b01100010;    //4MHz external osc
    adcon1 = 0b00001111;    //all digital
    trisa = 0;
    trisb = 0b00010000;
    trisc = 0b00010000;
    latb = 0;
    CS = 1;
    sspstat = 0b10000000;
    sspcon1 = 0b00110010;       //enable SPI, CLOCK idle high, fosc/64
    intcon2.RBPU = 0;           //enable portb pullups
    intcon = 0b10001000;        //enable interrupts, enable RB port change interrupt
    lcd_init();
/*    CS = 0;
    spi_write(0x80);        //address & write enable
    spi_write(0x00);        //set seconds
    spi_write(0x06);        //set minutes
    spi_write(0x41);        //set 12 hour time & hours
    spi_write(0x07);        //set day
    spi_write(0x12);        //set date
    spi_write(0x02);        //set century/month
    spi_write(0x11);        //set year
    spi_write(0x00);        //set alarm1 sec
    spi_write(0x00);        //set alarm1 min
    spi_write(0x00);        //set alarm1 hour
    spi_write(0x00);        //set alarm1 day/date
    spi_write(0x00);        //set alarm2 min
    spi_write(0x00);        //set alarm2 hour
    spi_write(0x00);        //set alarm2 day/date
    spi_write(0x40);        //enable osc, enable sqw
    spi_write(0x00);
    CS = 1;*/
    while(1){
        if(dflag){
            CS = 0;                     //read time & date
            spi_write(0x00);
            seconds = spi_read();
            minutes = spi_read();
            hours = spi_read();
            day = spi_read();
            date = spi_read();
            month = spi_read();
            year = spi_read();
            CS = 1;

            while(busycheck());         //check busy flag till clear
            CS = 0;                     //do temperature conversion
            spi_write(0x8e);
            spi_write(0x60);
            CS = 1;
            CS = 0;                     //read temp
            spi_write(0x11);
            temp_h = spi_read();
            temp_l = spi_read();
            CS = 1;

            sec = (seconds & 0x0f) + 0x30;          //do time digit prep
            sec10 = ((seconds & 0x70) >> 4) + 0x30;
            min = (minutes & 0x0f) + 0x30;
            min10 = ((minutes & 0x70) >> 4) + 0x30;
            hour = (hours & 0x0f) + 0x30;
            hour10 = ((hours & 0x10) >> 4) + 0x30;
            x = (hours & 0x20) >> 5;
            if(x)
                am = 0x41;      //A
            else
                am = 0x50;      //P
            //display time
            LINE1;
            lcd_char(hour10);
            lcd_char(hour);
            lcd_char(':');
            lcd_char(min10);
            lcd_char(min);
            lcd_char(':');
            lcd_char(sec10);
            lcd_char(sec);
            lcd_char(am);
            lcd_char('M');

            temp_l >>= 6;                           //do temp digit prep
            temp_l *= 25;
            temp4 = (temp_l % 10) + 0x30;
            temp3 = (temp_l / 10) + 0x30;
            temp2 = (temp_h % 10) + 0x30;
            temp1 = (temp_h / 10) + 0x30;
            //display temp
            LINE2;
            lcd_char(temp1);
            lcd_char(temp2);
            lcd_char('.');
            lcd_char(temp3);
            lcd_char(temp4);
            lcd_char(223);
            lcd_char('C');

            blink();
            dflag = 0;
        }
    }
}

unsigned char busycheck(void){
    unsigned char x;
    CS = 0;
    spi_write(0x0f);    //control/status register
    x = spi_read();
    CS = 1;
    x = (x & 0x04) >> 2;
    return x;
}

void blink(void){
    latb.0 = 1;
    delay_ms(20);
    latb.0 = 0;
}

//*****************
//* spi functions *
//*****************
void spi_write(unsigned char x){
    unsigned char dummy;
    sspbuf = x;
    while(pir1.SSPIF == 0);
    dummy = sspbuf;
    pir1.SSPIF = 0;
}

unsigned char spi_read(void){
    unsigned char dat;
    sspbuf = 0x33;
    while(pir1.SSPIF == 0);
    dat = sspbuf;
    pir1.SSPIF = 0;
    return(dat);
}

//*****************
//* lcd functions *
//*****************
void lcd_cls()
{
    LINE1;
    lcd_string("                ");
    LINE2;
    lcd_string("                ");
}

void lcd_string(char *senpoint)
{
    while(*senpoint != '\0')
    {
        lcd_char(*senpoint);
        senpoint++;
    }
}

void lcd_cmd(unsigned char letter)
{
    unsigned char temp;
    temp = letter;
    temp = temp>>4;
    lcd_nybble(temp,0);
    temp = letter;
    temp = temp&0x0f;
    lcd_nybble(temp,0);
}

void lcd_char(unsigned char letter)
{
    unsigned char temp;
    temp = letter;
    temp = temp >> 4;
    lcd_nybble(temp,1);
    temp = letter;
    temp = temp & 0x0f;
    lcd_nybble(temp,1);
}

void lcd_nybble(unsigned char nyb,unsigned char rs)
{
    int i;
    DATA = 0;                   //clear the 174
    for(i=0;i<6;i++){           //repeat for 6 bits
        CLOCK=1;delay_us(50);CLOCK=0;        //write 0's to the 174
    }
    DATA=1;                     //output the AND value
    CLOCK=1;delay_us(50);CLOCK=0;
    DATA=rs;                    //output the RS bit value
    CLOCK=1;delay_us(50);CLOCK=0;
    for(i=0;i<4;i++){           //output the nybble
        if((nyb & 0x08) != 0)
            DATA=1;
        else
            DATA=0;
        CLOCK=1;delay_us(50);CLOCK=0;
        nyb=nyb<<1;
    }
    e_togg();
}

void lcd_init(void)
{
    delay_ms(250);
    lcd_nybble(0x03,0);
    delay_ms(5);
    e_togg();
    delay_us(160);
    e_togg();
    delay_us(160);
    lcd_nybble(0x02,0);
    delay_us(160);
    lcd_cmd(0x28);                    //set 4-bit mode and 2 lines
    delay_us(160);
    lcd_cmd(0x10);                    //cursor move & shift left
    delay_us(160);
    lcd_cmd(0x06);                    //entry mode = increment
    delay_us(160);
    lcd_cmd(0x0d);                    //display on - cursor blink on
    delay_us(160);
    lcd_cmd(0x01);                    //clear display
    delay_us(160);
}

void e_togg(void)
{
    DATA=1;
    delay_us(50);
    DATA=0;
}

Next Post Previous Post