搜索
bottom↓
回复: 4

DS3231 时钟芯片 C语言程序

[复制链接]

出0入0汤圆

发表于 2012-12-21 15:01:32 | 显示全部楼层 |阅读模式
谁能给一个此芯片的C51完整程序,谢谢拉

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-12-21 17:07:46 | 显示全部楼层
看着芯片手册写它的驱动程序应该不难吧

出0入0汤圆

 楼主| 发表于 2012-12-22 16:09:24 | 显示全部楼层
liushenyoko 发表于 2012-12-21 17:07
看着芯片手册写它的驱动程序应该不难吧

好难,许多专业术语不懂,尤其是应答信号不知怎么写,写驱动程序有什么好方法吗?

出0入0汤圆

发表于 2012-12-22 16:45:02 | 显示全部楼层
网上找的。。自己改下吧。。



/***************************************************************************/   
/* DEMO3231.C                                                              */   
/***************************************************************************/   
#include    <stdio.h>     /* Prototypes for I/O functions */   
#include    <DS5000.h>        /* Register declarations for DS5000 */   
/************************* bit definitions ****************************/   
sbit    scl = P0^0;     /* I2C pin definitions */   
sbit    sda = P0^1;   
sbit    E = P1^0;       /* DCM LCD module control signal definitions */   
sbit    RS = P1^1;   
sbit    RW = P1^2;   
sbit    CLK = P2^5;     /* DS1267 control signal definitions */   
sbit    RSTb = P2^6;   
sbit    DQ = P2^7;   
sbit    int0 = P3^2;   
/**************************** defines *******************************/   
#define ADDRTC  0xd0    /* DS3231 slave address (write) */   
#define ACK 0   
#define NACK    1   
/*********************** Function Prototypes **************************/   
void    start();   
void    stop();   
uchar   i2cwrite(uchar d);   
uchar   i2cread(char);   
void    wr_dsp_dat(uchar);   
void    wr_dsp_ins(uchar);   
uchar   rd_dsp_ins();   
void    hex2asc(uchar);   
void    dsp_adj(uchar pos);   
void    init_dsp();   
void    writebyte();   
void    initialize_DS3231();   
void    disp_regs();   
void    rd_temp();   
void    frq_out_tog();   
void    init_alrm();   
void    comm_init();   
/************************* Global Variables ***************************/   
xdata   uchar   sec, min, hr, dy, dt, mn, yr;   
/**************************** functions ******************************/   
void start()        /* --------- Initiate start condition ---------- */   
{   
    sda = 1;  scl = 1;   
    sda = 0;   
}   
void stop()     /* ---------- Initiate stop condition ----------- */   
{   
    sda = 0;  sda = 0;   
    scl = 1;  scl = 1;  sda = 1;   
}   
uchar i2cwrite(uchar d)     /* ----------------------------- */   
{   
uchar i;   
   
    scl = 0;   
    for (i = 0;i < 8; i++)   
    {   
        if (d & 0x80)   
            sda = 1; /* Send the msbits first */   
        else   
            sda = 0;   
        scl = 0;   
        scl = 1;   
        d = d << 1;   /* do shift here to increase scl high time */   
        scl = 0;   
    }   
    sda = 1;    /* Release the sda line */   
    scl = 0;   
    scl = 1;   
    i = sda;   
    if (i) printf("Ack bit missing  %02X\n",(unsigned int)d);   
    scl = 0;   
    return(i);   
}   
uchar i2cread(char b)   /* ----------------------------------- */   
{   
uchar i, d;   
   
    d = 0;   
    sda = 1;             /* Let go of sda line */   
    scl = 0;   
    for (i = 0; i < 8; i++)  /* read the msb first */   
    {   
        scl = 1;   
        d = d << 1;   
        d = d | (unsigned char)sda;   
        scl = 0;   
    }   
    sda = b;          /* low for ack, high for nack */   
    scl = 1;   
    scl = 0;   
   
    sda = 1;          /* Release the sda line */   
    return d;   
}   
void    wr_dsp_dat(uchar dat)   /* -------- write one byte to the display --------- */   
{   
    P0 = dat;   
    RS = 1; /* data register */   
    RW = 0; /* write */   
    E = 1;   
    E = 0;      /* latch data in */   
}   
void    wr_dsp_ins(uchar dat)   /* ---- write one byte to the display instruction ----- */   
{   
    P0 = dat;   
    RS = 0; /* instruction register */   
    RW = 0; /* write */   
    E = 1;   
    E = 0;      /* latch data in */   
}   
uchar   rd_dsp_ins()    /* ---- read one byte from the instruction registers ----- */   
{   
uchar   dat;   
    P0 = 0xff;  /* set up for read */   
    RS = 0; /* instruction register */   
    RW = 1; /* read */   
    E = 1;   
    dat = P0;   
    E = 0;   
    return(dat);   
}   
void    init_dsp()  /* -------- initialize DMC-16207 LCD display ------- */   
{   
    while((rd_dsp_ins() & 0x80));   /* wait for display */   
   
    wr_dsp_ins(0x38);   /* Set 8-bit data, 2-line display, 5X7 font */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_ins(0x0c);   /* Display on, cursor off, blink off */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_ins(0x06);   /* Entry mode set: increment, no display shift */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_ins(0x01);   /* clear display */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_ins(0x80);   /* move to start of line 1 */   
    while((rd_dsp_ins() & 0x80));   
   
    wr_dsp_ins(0x50);   /* Set CG RAM address */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x07);   /* write 1st line of custom char to CG RAM */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x05);   /* write 2nd line */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x07);   /* write 3rd line */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x00);   /* write 4th line */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x00);   /* write 5th line */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x00);   /* write 6th line */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(0x00);   /* write 7th line */   
    while((rd_dsp_ins() & 0x80));   
}   
void    hex2asc(uchar hex)  /* -- convert the upper and lower nibbles to 2 ascii characters -- */   
{   
    if( ( (hex & 0xf0) >> 4) < 0x0a)   
        wr_dsp_dat( ( (hex & 0xf0) >> 4) + 48 );  /* prints 0-9 */   
    else   
        wr_dsp_dat( ( (hex & 0xf0) >> 4) + 55 );  /* prints A-F */   
    while((rd_dsp_ins() & 0x80));   
   
    if( (hex & 0x0f) < 0x0a)   
        wr_dsp_dat( (hex & 0x0f) + 48 );   
    else   
        wr_dsp_dat( (hex & 0x0f) + 55 );   
    while((rd_dsp_ins() & 0x80));   
}   
void    dsp_adj(uchar pos)  /* ------ adjust contrast on LCD display ------- */   
{   
char    inc;   
   
    RSTb = CLK = 0;         /* initialize for 1st pass */   
    RSTb = 1;               /* enable DS1267 */   
    DQ = 0;             /* write stack select bit */   
    CLK = 1;                /* toggle clk with data valid */   
    CLK = 0;   
   
    for (inc = 7; inc >= 0; inc--)   /* write wiper 0 */   
    {   
        DQ = ((pos >> inc) & 0x01);   /* shift x bits left */   
        CLK = 0;            /* toggle clk with data valid */   
        CLK = 1;   
    }   
    for (inc = 7; inc >= 0; inc--)   /* write wiper 1 */   
    {   
        DQ = ((pos >> inc) & 0x01);   /* shift x bits left */   
        CLK = 0;            /* toggle clk with data valid */   
        CLK = 1;   
    }   
    RSTb = 0;               /* reset the 1267 (/RST & CLK low) */   
    CLK = 0;   
}   
void writebyte()    /* ----------------------------------------------- */   
{   
uchar Add, Data;   
   
    printf("\nADDRESS (hex):");     /* Get Address & Data */   
    scanf("%bx", &Add);   
    printf("DATA (hex):");   
    scanf("%bx", &Data);   
   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(Add);   
    i2cwrite(Data);   
    stop();   
}   
void    initialize_DS3231() /* ----- set time & date; user data entry ------ */   
/* Note: NO error checking is done on the user entries! */   
{   
    printf("\nEnter the year (0-99): ");   
    scanf("%bx", &yr);   
    printf("Enter the month (1-12): ");   
    scanf("%bx", &mn);   
    printf("Enter the date (1-31): ");   
    scanf("%bx", &dt);   
    printf("Enter the day (1-7): ");   
    scanf("%bx", &dy);   
    printf("Enter the hour (1-23): ");   
    scanf("%bx", &hr);   
    /* hr = hr & 0x3f;  /* force clock to 24 hour mode */   
    printf("Enter the minute (0-59): ");   
    scanf("%bx", &min);   
    printf("Enter the second (0-59): ");   
    scanf("%bx", &sec);   
   
    start();   
    i2cwrite(ADDRTC);   /* write slave address, write 1339 */   
    i2cwrite(0x00); /* write register address, 1st clock register */   
    i2cwrite(sec);   
    i2cwrite(min);   
    i2cwrite(hr);   
    i2cwrite(dy);   
    i2cwrite(dt);   
    i2cwrite(mn);   
    i2cwrite(yr);   
    i2cwrite(0x10); /* enable sqw, 1hz output */   
    stop();   
}   
void    disp_regs() /* --- display date/time on LCD display --- */   
{   
uchar   age, prv_sec=99;   
   
    while(!RI)  /* Read & Display Clock Registers */   
    {   
        while(int0);    /* loop until int pin goes low */   
        start();   
        i2cwrite(ADDRTC);   
        i2cwrite(0x0f);   
        i2cwrite(0);        /* clear alarm flags */   
        stop();   
   
        start();   
        i2cwrite(ADDRTC);   
        i2cwrite(0);   
        start();   
        i2cwrite(ADDRTC | 1);   
        sec = i2cread(ACK);   
        min = i2cread(ACK);   
        hr = i2cread(ACK);   
        dy = i2cread(ACK);   
        dt = i2cread(ACK);   
        mn = i2cread(ACK);   
        yr = i2cread(NACK);   
        stop();   
   
        wr_dsp_ins(0x80);   /* move to start of line 1 */   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(yr);   
        wr_dsp_dat('/');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(mn);   
        wr_dsp_dat('/');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(dt);   
        wr_dsp_dat(' ');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(dy);   
        wr_dsp_dat(' ');   
        while((rd_dsp_ins() & 0x80));   
   
        start();   
        i2cwrite(ADDRTC);   
        i2cwrite(0x10);   
        start();   
        i2cwrite(ADDRTC | 1);   
        age = i2cread(NACK);   
        stop();   
   
        wr_dsp_dat(' ');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(age);   
   
        wr_dsp_ins(0xc0);   /* move to start of line 2 */   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(hr);   
        wr_dsp_dat(':');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(min);   
        wr_dsp_dat(':');   
        while((rd_dsp_ins() & 0x80));   
        hex2asc(sec);   
   
        rd_temp();   
    }   
    RI = 0;  /* Swallow keypress to exit loop */   
}   
void    rd_temp()   /* -------- display temperature -------- */   
{   
char    str[8];   
int itemp;   
float   ftemp;   
   
    do   
    {   
        start();   
        i2cwrite(ADDRTC);   
        i2cwrite(0x0e);     /* address of control register */   
        start();   
        i2cwrite(ADDRTC + 1);   /* send the device address for read */   
        itemp = i2cread(NACK);  /* get the control register value */   
        stop();   
    }   while(itemp & 0x20);        /* wait until CNVT bit goes inactive */   
   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(0x11);         /* address of temperature MSB */   
    start();   
    i2cwrite(ADDRTC + 1);       /* send the device address for read */   
    itemp = ( (int) i2cread(ACK) << 5 );   
    itemp += ( i2cread(NACK) >> 3);   
    stop();   
    if(itemp & 0x1000)  itemp += 0xe000;    /* if sign bit set, make 16 bit 2's comp */   
   
    ftemp = 0.03125 * (float) itemp;    /* convert to degrees C */   
    /* ftemp = ftemp * 9 / 5 + 32;  /* skip this if you don't want degrees F */   
   
    sprintf(str, "%5.2f", ftemp);   
   
    wr_dsp_ins(0xc9);           /* go to line 2, column 10 */   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(str[0]);   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(str[1]);   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(str[2]);   
    while((rd_dsp_ins() & 0x80));   
    wr_dsp_dat(str[3]);   
    while((rd_dsp_ins() & 0x80));   
   
    wr_dsp_dat(0x02);   /* display programed 3rd char in CG RAM */   
    while((rd_dsp_ins() & 0x80));   
}   
void    frq_out_tog()   /* --- toggle en32khz bit to enable/disable sqw --- */   
{   
uchar   val;   
   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(0x0f);         /* control/status reg address */   
    start();   
    i2cwrite(ADDRTC + 1);       /* send the device address for read */   
    val = i2cread(NACK);   
    stop();   
    val ^= 0x08;    /* toggle en32khz bit */   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(0x0f);         /* control/status reg address */   
    i2cwrite(val);   
    stop();   
}   
void    init_alrm() /* --- enable alarm 1 for once-per-second --- */   
{   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(7);        /* 1st alarm 1 reg address */   
    i2cwrite(0x80); /* mask alarm register */   
    i2cwrite(0x80);   
    i2cwrite(0x80);   
    i2cwrite(0x80);   
    stop();   
   
    start();   
    i2cwrite(ADDRTC);   
    i2cwrite(0x0e); /* control/status reg address */   
    i2cwrite(0x05); /* enable interrupts, alarm 1 output */   
}   
void    comm_init() /* ------ reset DS3231 comm interface ------ */   
{   
    do  /* because the DS3231 I2C interface is active for both supplies */   
    {   /*  after a micro reset, we must get the comm into a known state */   
        sda = 1;    /* make sure master has released SDA */   
        scl = 1;   
        if(sda) /* if sda is high, generate a start */   
        {   
            sda = 0;    /* The DS3231 will recognize a valid start */   
            sda = 1;    /*  condition anywhere in a I2C data transfer */   
        }   
        scl = 0;   
    }   while(sda == 0);    /* if the DS3231 is holding sda low, try again */   
}   
void    main    (void)  /* ------------------------------------------------ */   
{   
uchar i, M, M1;   
   
    dsp_adj(0x10);  /* adjust contrast on LCD display */   
    init_dsp();     /* initialize LCD display */   
    comm_init();   
    init_alrm();        /* enable alarm */   
    disp_regs();   
   
    while(1)   
    {   
        printf("\nDS3231 build date: %s\n", __DATE__);   
        printf("I Init DS3231 S Show temp\n");   
        printf("R Read Time   W Write Byte\n");   
        printf("F Frq out     D Display adj\n");   
        printf("Enter Menu Selection: ");   
   
        M = _getkey();   
   
        switch(M)   
        {   
            case 'D':   
            case 'd':   printf("val: ");    scanf("%bx", &M1);   
                    dsp_adj(M1);    break;   
   
            case 'F':   
            case 'f':   frq_out_tog();  break;   
   
            case 'I':   
            case 'i':   initialize_DS3231();    break;   
   
            case 'R':   
            case 'r':   disp_regs();    break;   
   
            case 'S':   
            case 's':   rd_temp();  break;   
   
            case 'W':   
            case 'w':   writebyte();    break;   
        }   
    }   

出0入0汤圆

 楼主| 发表于 2012-12-23 15:39:30 | 显示全部楼层
liujinhan 发表于 2012-12-22 16:45
网上找的。。自己改下吧。。

太感谢了,参考下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 15:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表