找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2811|回复: 1
打印 上一主题 下一主题
收起左侧

DS3231时钟芯片驱动资料

[复制链接]
跳转到指定楼层
楼主
ID:268888 发表于 2017-12-29 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg51.h>
#include <intrins.h>
#include <sys\sys.h>
#include <lcd\lcd.h>
#include <font\font.h>
typedef unsigned char BYTE;
typedef unsigned char uchar;
typedef unsigned int WORD;
#define FOSC 24000000L          //系统频率
#define BAUD 9600             //串口波特率
#define T1MS (65536-FOSC/1000)      //1T模式
WORD c=0,valv=0,vali=0;
bit flag=0, ack,flag1=0 ;
int HL,TL,dat_v,HLi,TLi,dat_i=1000;
sbit led=P5^4;
sbit SDA=P3^5;
sbit SCL=P3^7;
sbit key=P3^2;
#define DS3231_WriteAddress 0xD0    //器件写地址
#define DS3231_ReadAddress  0xD1    //器件读地址
#define DS3231_SECOND       0x00    //秒
#define DS3231_MINUTE       0x01    //分
#define DS3231_HOUR         0x02    //时
#define DS3231_WEEK         0x03    //星期
#define DS3231_DAY          0x04    //日
#define DS3231_MONTH        0x05    //月
#define DS3231_YEAR         0x06    //年
//闹铃1            
#define DS3231_SALARM1ECOND 0x07    //秒
#define DS3231_ALARM1MINUTE 0x08    //分
#define DS3231_ALARM1HOUR   0x09    //时
#define DS3231_ALARM1WEEK   0x0A    //星期/日
//闹铃2
#define DS3231_ALARM2MINUTE 0x0b    //分
#define DS3231_ALARM2HOUR   0x0c    //时
#define DS3231_ALARM2WEEK   0x0d    //星期/日
#define DS3231_CONTROL      0x0e    //控制寄存器
#define DS3231_STATUS       0x0f    //状态寄存器
#define BSY                 2       //忙
#define OSF                 7       //振荡器停止标志
#define DS3231_XTAL         0x10    //晶体老化寄存器
#define DS3231_TEMPERATUREH 0x11    //温度寄存器高字节(8位)
#define DS3231_TEMPERATUREL 0x12    //温度寄存器低字节(高2位)
uchar data dis_buf[8];
uchar data dis_index;
uchar data dis_digit;
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC电源控制位
#define ADC_FLAG    0x10            //ADC完成标志
#define ADC_START   0x08            //ADC起始控制位
#define ADC_SPEEDLL 0x00            //540个时钟
#define ADC_SPEEDL  0x20            //360个时钟
#define ADC_SPEEDH  0x40            //180个时钟
#define ADC_SPEEDHH 0x60            //90个时钟
#define ADC_P10  0x01 //IO引脚 Px.0
#define ADC_P11  0x02 //IO引脚 Px.1
#define ADC_P12  0x04 //IO引脚 Px.2
#define ADC_P13  0x08 //IO引脚 Px.3
#define ADC_P14  0x10 //IO引脚 Px.4
#define ADC_P15  0x20 //IO引脚 Px.5
#define ADC_P16  0x40 //IO引脚 Px.6
#define ADC_P17  0x80 //IO引脚 Px.7
#define ADC_P1_All 0xFF //IO所有引脚
//-----------------------------------------------
void InitADC();
BYTE GetADCResult(BYTE ch);
void Delay(WORD n);
BYTE GetADCResult(BYTE ch)
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; //ADC电源,转换时间,通道,ADC打开
    _nop_();                        //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC
    return ADC_RES;                 //返回ADC结果
}
void InitADC()
{                    
    P1ASF =0x03;                     //设置P1口为AD口  设置P1.0和P1.1位AD口
    ADC_RES = 0;                        //清除结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                           //ADC上电并延时                      //ADC power-on and delay
}
void Delay(WORD n)
{
   WORD x;
    while (n--)
    {
        x = 5000;
        while (x--);
    }
}
uchar BCD2HEX(uchar val)    //BCD???Byte
{
    uchar temp;
    temp=val&0x0f;
    val>>=4;
    val&=0x0f;
    val*=10;
    temp+=val;
   
    return temp;
}
uchar HEX2BCD(uchar val)    //B????BCD?
{
    uchar i,j,k;
    i=val/10;
    j=val%10;
    k=j+(i<<4);
    return k;
}
void delayus(WORD us)
{   
   _nop_();
   _nop_();
    while (us--);
}
void Start_I2C()
{
    SDA=1;                  //???????????
    delayus(3);
    SCL=1;
    delayus(27);             //??????????4.7us,??
   
    SDA=0;                  //??????
    delayus(27);             // ??????????4祍
      
    SCL=0;                  //??I2C??,?????????
    delayus(9);
}
void Stop_I2C()
{
    SDA=0;                  //???????????
    delayus(3);             //???????????
    SCL=1;                  //??????????4us
    delayus(27);
   
    SDA=1;                  //??I2C??????
    delayus(21);
}
void SendByte(uchar c)
{
    uchar BitCnt;
   
    for(BitCnt=0;BitCnt<8;BitCnt++)         //?????????8?
    {
        if((c<<BitCnt)&0x80)
            SDA=1;                          //?????
        else
            SDA=0;               
          delayus(3);
          SCL=1;                            //??????,????????????
          delayus(27);                       //???????????4祍   
          SCL=0;
    }
   
    delayus(9);
    SDA=1;                                  //8??????????,???????
    delayus(9);  
    SCL=1;
    delayus(15);
    if(SDA==1)
        ack=0;   
    else
        ack=1;                              //???????????
    SCL=0;
    delayus(9);
}
uchar RcvByte()
{
   uchar retc;
   uchar BitCnt;

   retc=0;
   SDA=1;                           //?????????
   for(BitCnt=0;BitCnt<8;BitCnt++)
   {
        delayus(3);  
        SCL=0;                      //??????,???????
      
        delayus(27);                 //?????????4.7祍
      
        SCL=1;                      //???????????????
        delayus(15);
        retc=retc<<1;
        if(SDA==1)
            retc=retc+1;            //????,????????retc?
        delayus(9);
   }
   SCL=0;
   delayus(9);
   return(retc);
}

void Ack_I2C(bit a)
{

    if(a==0)
        SDA=0;              //????????????
    else
        SDA=1;
    delayus(15);     
    SCL=1;
   
    delayus(27);             //?????????4祍
   
    SCL=0;                  //????,??I2C????????
    delayus(9);   
}

uchar write_byte(uchar addr, uchar write_data)
{
    Start_I2C();
    SendByte(DS3231_WriteAddress);
    if (ack == 0)
        return 0;
   
    SendByte(addr);   
    if (ack == 0)
        return 0;
   
    SendByte(write_data);
    if (ack == 0)
        return 0;
   
    Stop_I2C();
    delayus(57);      
    return 1;
}

uchar read_current()
{
    uchar read_data;
    Start_I2C();
    SendByte(DS3231_ReadAddress);
    if(ack==0)
        return(0);
   
    read_data = RcvByte();
    Ack_I2C(1);
    Stop_I2C();
    return read_data;
}

uchar read_random(uchar random_addr)
{
    Start_I2C();
    SendByte(DS3231_WriteAddress);
    if(ack==0)
        return(0);
   
    SendByte(random_addr);
    if(ack==0)
        return(0);
   
    return(read_current());
}

void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
{
    uchar temp=0;
   
    temp=HEX2BCD(yea);
    write_byte(DS3231_YEAR,temp);   //???
   
    temp=HEX2BCD(mon);
    write_byte(DS3231_MONTH,temp);  //???
   
    temp=HEX2BCD(da);
    write_byte(DS3231_DAY,temp);    //???
   
    temp=HEX2BCD(hou);
    write_byte(DS3231_HOUR,temp);   //???
   
    temp=HEX2BCD(min);
    write_byte(DS3231_MINUTE,temp); //???
   
    temp=HEX2BCD(sec);
    write_byte(DS3231_SECOND,temp); //???
}


void get_show_time(void)                 //显示时间
{
    uchar Htemp1,Htemp2,Mtemp1,Mtemp2,Stemp1,Stemp2;

    Htemp1=read_random(DS3231_HOUR);    //? 24???
    Htemp1&=0x3f;                  
    Htemp2=BCD2HEX(Htemp1);
   
    Mtemp1=read_random(DS3231_MINUTE);  //?
    Mtemp2=BCD2HEX(Mtemp1);
   
    Stemp1=read_random(DS3231_SECOND);  //?
    Stemp2=BCD2HEX(Stemp1);

      
        LCD_Show2Num(0,96,Htemp2,2);
       LCD_Show2Num(32,96,Mtemp2,2);
       LCD_Show2Num(64,96,Stemp2,2);
}

void get_show_date(void)                //显示年月日
{
    uchar Ytemp1,Ytemp2,Mtemp1,Mtemp2,Dtemp1,Dtemp2;
   
    Ytemp1=read_random(DS3231_YEAR);        //?
    Ytemp2=BCD2HEX(Ytemp1);
   
    Mtemp1=read_random(DS3231_MONTH);       //?
    Mtemp2=BCD2HEX(Mtemp1);
   
    Dtemp1=read_random(DS3231_DAY);         //?
    Dtemp2=BCD2HEX(Dtemp1);

       LCD_Show2Num(16,114,Ytemp2,2);
      
       LCD_Show2Num(48,114,Mtemp2,2);
        
       LCD_Show2Num(80,114,Dtemp2,2);
        
}


void get_show_Temperature(void)             //温度数据
{
    uchar Ttemp1,Ttemp_L,Ttemp3,Ttemp_H;
   
    Ttemp1=read_random(DS3231_TEMPERATUREH);    //温度高位
    Ttemp_H=Ttemp1;
   
    Ttemp3=read_random(DS3231_TEMPERATUREL);    //温度地位
    Ttemp_L=(Ttemp3>>6)*25;
if(Ttemp_H&0x80)
{
  flag1=1;
  Ttemp_H=Ttemp_H||0x7f;
}
else
  flag1=0;


        if(flag1==1)
        LCD_ShowString(40,130,"-") ;
     else
     LCD_ShowString(40,130," ") ;
   
     LCD_Show2Num(48,130,Ttemp_H,2);
        LCD_ShowString(64,130,".") ;
   
     LCD_Show2Num(72,130,Ttemp_L,2);
     
}
void init()       //串口以及定时器初始化程序
{
    SCON = 0x50;                    //8位可变波特率
    T2L = (65536 - (FOSC/4/BAUD));  //设置波特率重装值
    T2H = (65536 - (FOSC/4/BAUD))>>8;
    AUXR = 0x14;                    //T2为1T模式, 并启动定时器2
// AUXR |= 0x01;                   //选择定时器2为串口1的波特率发生器
AUXR |= 0x81;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式
    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    ES = 1;                         //使能串口1中断 刚开机的时候关闭串口中断防止串口有数据唤醒单片机           
    EA = 1;
}
void tm0_isr() interrupt 1 using 1    //1MS中断程序
{
c++;
if(c==10)
{
flag=1;
c=0;
}
}
void dat_bat()        //温湿度以及PM2.5程序处理程序
{
HL=GetADCResult(0);
TL=ADC_LOW2;
HL<<=2;
dat_v=HL|TL;
HLi=GetADCResult(1);
TLi=ADC_LOW2;
HLi<<=2;
dat_i=HLi|TLi;
vali=dat_i*5*4.65/1.024;
valv=dat_v*5*0.755/1.024;
}
void lcd_aux_init()
{
     showhanzi16(0,16,0);    //
      showhanzi16(16,16,1);    //
   LCD_ShowString(32,16,":") ;
   /////////////////////////
   LCD_ShowString(96,16,"mV") ;
   showhanzi16(0,32,0);    //
      showhanzi16(16,32,10);    //
   LCD_ShowString(32,32,":") ;
   //////////////////////////
   LCD_ShowString(80,32,"mA") ;
   LCD_ShowString(0,64,"DC SOURCE ") ;
   LCD_ShowString(0,80,"1-12V 0-3A") ;

      LCD_Show2Num(0,114,20,2);//   年月日
       showhanzi16(32,114,24);
       showhanzi16(64,114,25);
       showhanzi16(96,114,26);

      showhanzi16(0,130,20);    //温度参数
       showhanzi16(16,130,21);
       LCD_ShowString(32,130,":") ;
   
    LCD_ShowString(16,96,":") ;    //时间参数
      LCD_ShowString(48,96,":") ;
}
void show_time()
{
   LCD_Show2Num(48,16,vali,5);
   LCD_Show2Num(48,32,valv,4);
}
main()
{
char ii=3;
Lcd_Init();   //tft初始化
init();
LCD_Clear(WHITE); //清屏
InitADC();
  BACK_COLOR=WHITE ;
POINT_COLOR=BLACK ;
lcd_aux_init();
while(1)
{
if(flag==1)       //50ms更新一次数据
{
dat_bat();
flag=0;
  get_show_date();              //????
  get_show_Temperature();       //????
  get_show_time();   
}
  show_time();
if(key==0)
ModifyTime(17,3,23,14,05,00);
while(!key);

  led=~led;
  }

}

做了一个DC电源,加上这个时钟芯片驱动

12V3ADC-DC DS3231.rar

159.99 KB, 下载次数: 23, 下载积分: 黑币 -5

LCD加上时钟芯片驱动

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:371527 发表于 2018-12-26 07:08 | 只看该作者
名称该是采集显示时间温度程序PM2,5时间温度采用DS3231
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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