找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4994|回复: 21
收起左侧

做了一个oled时钟

  [复制链接]
ID:849826 发表于 2021-1-14 23:26 来自手机 | 显示全部楼层 |阅读模式
单片机用的STC89C52,时钟模块用的是ds3231,带万年历,温度显示。oled用的是0.96吋四脚蓝色的。
6ccf08a26a772b8c.jpg
回复

使用道具 举报

ID:849826 发表于 2021-1-14 23:28 | 显示全部楼层
本帖最后由 6313 于 2021-1-14 23:41 编辑

下载压缩包,解压,里面是HEX文件,直接下载到单片机就可以用了
回复

使用道具 举报

ID:673647 发表于 2021-1-15 08:02 | 显示全部楼层
谢谢分享!只是好像没有附件啊!
回复

使用道具 举报

ID:16255 发表于 2021-1-15 08:21 | 显示全部楼层
很好。只是屏幕有点小。
回复

使用道具 举报

ID:390416 发表于 2021-1-15 20:47 | 显示全部楼层
DS3231+WS2812全彩RGB挂钟资料分享 http://www.51hei.com/bbs/dpj-200965-1.html
回复

使用道具 举报

ID:849826 发表于 2021-1-16 09:24 来自手机 | 显示全部楼层
cwb2038 发表于 2021-1-15 08:02
谢谢分享!只是好像没有附件啊!

用手机传了好几次,传不上去
回复

使用道具 举报

ID:856401 发表于 2021-1-16 22:58 | 显示全部楼层
楼主期待你的原理图,很代码。很实用的东西,很想做一个
回复

使用道具 举报

ID:95809 发表于 2021-1-17 05:57 | 显示全部楼层
3486635230 发表于 2021-1-16 22:58
楼主期待你的原理图,很代码。很实用的东西,很想做一个

很简单,OLED和DS3231共用I2C总线,你单片机有两个IO就行,我是使用的15单片机,

原理图

原理图

PCB

PCB

PCB背面

PCB背面

效果

效果
回复

使用道具 举报

ID:230742 发表于 2021-1-17 12:49 | 显示全部楼层
好东西啊。留个记号,我也做一个。
回复

使用道具 举报

ID:684871 发表于 2021-1-17 23:55 来自手机 | 显示全部楼层
很实用,感谢楼主分享
回复

使用道具 举报

ID:46750 发表于 2021-1-19 09:10 | 显示全部楼层
bxyyhan 发表于 2021-1-17 05:57
很简单,OLED和DS3231共用I2C总线,你单片机有两个IO就行,我是使用的15单片机,

@楼主,代码可以开源吗?
回复

使用道具 举报

ID:471297 发表于 2021-1-19 12:26 | 显示全部楼层
6313 发表于 2021-1-14 23:28
下载压缩包,解压,里面是HEX文件,直接下载到单片机就可以用了

很不错,可是看不到附件,能上次论坛吗?谢谢。这个是读取DS3231温度,不知能改成DS18B02吗?不影响现有的农历星期日期。网上看到有的用18B02 但没有农历
回复

使用道具 举报

ID:471297 发表于 2021-1-19 12:35 | 显示全部楼层
bxyyhan 发表于 2021-1-17 05:57
很简单,OLED和DS3231共用I2C总线,你单片机有两个IO就行,我是使用的15单片机,

请问这个能改成不影响其他内容,读取DS18B02温度吗?这样温度就更精准对吧,这个电路板是自己做的,还是网上淘来的呢,很漂亮
回复

使用道具 举报

ID:423238 发表于 2021-1-20 08:07 来自手机 | 显示全部楼层
原理图
08-01-34-165443dya44r7uu23q24z7.jpg
回复

使用道具 举报

ID:95809 发表于 2021-1-20 21:07 | 显示全部楼层
zenghl 发表于 2021-1-19 09:10
@楼主,代码可以开源吗?

代码不是我写的,原帖子在此:http://www.51hei.com/bbs/dpj-148510-1.html
PCB是自己画的,打样的时候顺便打了几块,代码如下:

#include "STC15.h"
#include "intrins.h"
#include "codetab.h"
#include "nongli.h"
#define uint  unsigned int
#define uchar unsigned char

// ------------------------------------------------------------
// IO口模拟I2C通信

// ------------------------------------------------------------
sbit SCL=P1^0; //串行时钟
sbit SDA=P1^1; //串行数据

sbit KEY1=  P3^0;                  //调整
sbit KEY2=  P3^1;                  //++
sbit KEY3=  P3^2;                  //--
sbit KEY4=  P3^5;                  //退出

uchar  a1,a2,a3,a4;                      //按键消抖用
uchar  disflag=0; //时间调整相关



#define        Brightness        0xcf //
#define X_WIDTH         128
#define Y_WIDTH         64

/********************************************************************************************************
**         DS3231常数定义
********************************************************************************************************/
#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    //年

#define DS3231_TEMPERATUREH 0x11    //温度寄存器高字节(8位)        整数部分
#define DS3231_TEMPERATUREL 0x12    //温度寄存器低字节(低2位) 小数部分



#define NACK    1
#define ACK     0

uchar shan_count; //:号闪烁计时变量
uchar shan_js;    //校时闪烁计时变量
bit flag;                //校时闪烁标志
char hour,minute,second,year,month,day,date,week;
uint TH3231;
bit        ack;                //应答标志位
/*********************OLED驱动程序用的延时程序************************************/
/*void delay(unsigned int z)
{
        unsigned int x,y;
        for(x=z;x>0;x--)
                for(y=1100;y>0;y--);  
}        */
void        Delay5US()           //@12.000MHz           延时5us
{
   _nop_(); _nop_();        _nop_();_nop_(); //1T单片机用4个nop,12T用1个nop
}


/**************************/
void Timer0Init(void)                //10毫秒@11.0592MHz
{
//        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器0,16位模式
        TL0 = 0x00;                //设置定时初值
        TH0 = 0xDC;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        ET0 = 1;
        EA = 1;
}

/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
   SCL = 1;               
   SDA = 1;
   SDA = 0;
   SCL = 0;
}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
   SCL = 0;
   SDA = 0;
   SCL = 1;
   SDA = 1;
}


/********************************************************************************************************
**         3231
********************************************************************************************************/


uchar        BCD2HEX(uchar val)
{
        return        ((val>>4)*10)+(val&0x0f);
}

uchar        HEX2BCD(uchar val)
{
        return        (((val%100)/10)<<4)|(val%10);
}


void SendByte(uchar c)
{
    uchar BitCnt;

    for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
    {
        if((c<<BitCnt)&0x80)
            SDA=1;                          //判断发送位
        else
            SDA=0;     
        SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
        Delay5US();                       //保证时钟高电平周期大于4μs   
        SCL=0;
    }
    SDA=1;                                  //8位发送完后释放数据线,准备接收应答位
    SCL=1;
    Delay5US();
    if(SDA==1)
        ack=0;   
    else
        ack=1;                              //判断是否接收到应答信号
    SCL=0;
    Delay5US();
}          

uchar RcvByte()
{
   uchar retc;
   uchar BitCnt;

   retc=0;
   SDA=1;                           //置数据线为输入方式
   for(BitCnt=0;BitCnt<8;BitCnt++)
   {
        SCL=0;                      //置时钟线为低,准备接收数据位      
        Delay5US();                 //时钟低电平周期大于4.7μs                       
        SCL=1;                      //置时钟线为高使数据线上数据有效
        Delay5US();
        retc=retc<<1;
        if(SDA==1)
            retc=retc+1;            //读数据位,接收的数据位放入retc中
        Delay5US();
   }
   SCL=0;
   return(retc);
}                            

void Ack_I2C(bit a)
{
        SDA        =        a;  
    SCL=1;                     
    Delay5US();             //时钟低电平周期大于4us   
    SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
    Delay5US();   
}                                            

uchar write_byte(uchar addr, uchar write_data)
{
    IIC_Start();
    SendByte(DS3231_WriteAddress);
    if (ack == 0)
        return 0;

    SendByte(addr);   
    if (ack == 0)
        return 0;

    SendByte(write_data);
    if (ack == 0)
        return 0;

    IIC_Stop();
    Delay5US();      
    Delay5US();      
    return 1;
}                                          

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

uchar read_random(uchar random_addr)
{
    uchar Tmp;
        IIC_Start();
    SendByte(DS3231_WriteAddress);
    if(ack==0)
        return(0);            
    SendByte(random_addr);
    if(ack==0)
        return(0);
        Tmp=read_current();
        if(random_addr==DS3231_HOUR)
                Tmp&=0x3f;
                                            
    return(BCD2HEX(Tmp));//都转10进制输出
}

/***********************/
uchar read_random1(uchar random_addr)  //这个是读温度函数
{
    uchar Tmp;
        write_byte(0x0e,0x20);//0x0e寄存器的CONV位置1开启温度转换,要这句,温度实时刷新,这句不要,温度要64s才刷新1次
        IIC_Start();
    SendByte(DS3231_WriteAddress);
    if(ack==0)
        return(0);            
    SendByte(random_addr);
    if(ack==0)
        return(0);
        Tmp=read_current();
        return Tmp;
}                                  

void ModifyTime(uchar address,uchar num)
{
    uchar temp=0;
           if(address>6 && address <0) return;
    temp=HEX2BCD(num);
        write_byte(address,temp);
}

/*
uint read_temp()      
{
                int     itemp;
                float   ftemp;
                //温度数据是以2 进制格式存储的并不需要数制转换
                write_byte(0x0e,0x20);//0x0e寄存器的CONV位置1开启温度转换

        itemp = ( (int) read_random(0x11) << 5 );          //放大32倍
        itemp += ( read_random(0x12)>> 3);
        IIC_Stop();
        if(itemp & 0x1000)
                        itemp += 0xe000;      

        ftemp = 0.3125 * (float) itemp+0.5;    //放大10倍
                return  (uint) ftemp;
}          */

/*********************OLED写数据************************************/
void OLED_WrDat(unsigned char IIC_Data)
{
        IIC_Start();
        SendByte(0x78);
        SendByte(0x40);                        //write data
        SendByte(IIC_Data);
        IIC_Stop();
}
/*********************OLED写命令************************************/
void OLED_WrCmd(unsigned char IIC_Command)
{
        IIC_Start();
        SendByte(0x78);            //Slave address,SA0=0
        SendByte(0x00);                        //write command
        SendByte(IIC_Command);
        IIC_Stop();
}
/*********************OLED 设置坐标************************************/
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
        OLED_WrCmd(0xb0+y);
        OLED_WrCmd(((x&0xf0)>>4)|0x10);
        OLED_WrCmd((x&0x0f)|0x01);
}
/*********************OLED全屏************************************/
void OLED_Fill(unsigned char bmp_dat)
{
        unsigned char y,x;
        for(y=0;y<8;y++)
        {
                OLED_WrCmd(0xb0+y);
                OLED_WrCmd(0x01);
                OLED_WrCmd(0x10);
                for(x=0;x<X_WIDTH;x++)
                OLED_WrDat(bmp_dat);
        }
}
/*********************OLED复位************************************/
void OLED_CLS(void)
{
        unsigned char y,x;
        for(y=0;y<8;y++)
        {
                OLED_WrCmd(0xb0+y);
                OLED_WrCmd(0x01);
                OLED_WrCmd(0x10);
                for(x=0;x<X_WIDTH;x++)
                OLED_WrDat(0);
        }
}
/*********************OLED初始化************************************/
void OLED_Init(void)
{
        Delay5US();//初始化之前的延时很重要!
        OLED_WrCmd(0xae);//--turn off oled panel
        OLED_WrCmd(0x00);//---set low column address
        OLED_WrCmd(0x10);//---set high column address
        OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
        OLED_WrCmd(0x81);//--set contrast control register
        OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
        OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
        OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
        OLED_WrCmd(0xa6);//--set normal display
        OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
        OLED_WrCmd(0x3f);//--1/64 duty
        OLED_WrCmd(0xd3);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
        OLED_WrCmd(0x00);//-not offset
        OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
        OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
        OLED_WrCmd(0xd9);//--set pre-charge period
        OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
        OLED_WrCmd(0xda);//--set com pins hardware configuration
        OLED_WrCmd(0x12);
        OLED_WrCmd(0xdb);//--set vcomh
        OLED_WrCmd(0x40);//Set VCOM Deselect Level
        OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
        OLED_WrCmd(0x02);//
        OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
        OLED_WrCmd(0x14);//--set(0x10) disable
        OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
        OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
        OLED_WrCmd(0xaf);//--turn on oled panel
        OLED_Fill(0x00); //初始清屏
        OLED_Set_Pos(0,0);
}

/*******************功能描述:显示8*16一组标准ASCII字符串         显示的坐标(x,y),y为页范围0~7****************/
/*void OLED_P8x16List(unsigned char x, y,unsigned char ch[])
{
        unsigned char c=0,i=0,j=0;
        while (ch[j]!='\0')
        {
                c =ch[j]+;
                if(x>120){x=0;y++;}
                OLED_Set_Pos(x,y);
                for(i=0;i<8;i++)
                OLED_WrDat(F8X16[c*16+i]);
                OLED_Set_Pos(x,y+1);
                for(i=0;i<8;i++)
                OLED_WrDat(F8X16[c*16+i+8]);
                x+=8;
                j++;
        }
}        */
void OLED_P8x16Str(unsigned char x, y,unsigned char dat)
{
        unsigned char i=0;
       
               
                if(x>120){x=0;y++;}
                OLED_Set_Pos(x,y);
                for(i=0;i<8;i++)
                OLED_WrDat(F8X16[dat*16+i]);
                OLED_Set_Pos(x,y+1);
                for(i=0;i<8;i++)
                OLED_WrDat(F8X16[dat*16+i+8]);
                x+=8;
       
       
}
void OLED_hzStr(unsigned char x, y,unsigned char N)
{
        unsigned char wm=0;
        unsigned int  adder=32*N;
        OLED_Set_Pos(x , y);
        for(wm = 0;wm < 16;wm++)
        {
                OLED_WrDat(hz[adder]);
                adder += 1;
        }
        OLED_Set_Pos(x,y + 1);
        for(wm = 0;wm < 16;wm++)
        {
                OLED_WrDat(hz[adder]);
                adder += 1;
        }
       
}
void OLED_P32x64Str(unsigned char x, y,unsigned char dat)
{
        unsigned char i=0;
        unsigned int adder=64*dat;
               
                if(x>128){x=0;y++;}
                OLED_Set_Pos(x,y);
                for(i=0;i<16;i++)
                {
                OLED_WrDat(F32X64[adder]);       
                  adder += 1;
                }
               
                OLED_Set_Pos(x,y+1);
                for(i=0;i<16;i++)
                {
                OLED_WrDat(F32X64[adder]);       
                  adder += 1;
                }

                OLED_Set_Pos(x,y+2);
                for(i=0;i<16;i++)
                {
                OLED_WrDat(F32X64[adder]);       
                  adder += 1;
                }
               
                OLED_Set_Pos(x,y+3);
                for(i=0;i<16;i++)
                {
                OLED_WrDat(F32X64[adder]);       
                  adder += 1;
                }
                //x+=1;
}
/*****************功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7**************************
void OLED_P16x16Ch(unsigned char x, y, N)
{
        unsigned char wm=0;
        unsigned int adder=32*N;
        OLED_Set_Pos(x , y);
        for(wm = 0;wm < 16;wm++)
        {
                OLED_WrDat(F16x16[adder]);
                adder += 1;
        }
        OLED_Set_Pos(x,y + 1);
        for(wm = 0;wm < 16;wm++)
        {
                OLED_WrDat(F16x16[adder]);
                adder += 1;
        }                  
}                                                                                                                                                                                          **/


void Set(unsigned char sel,unsigned char selby)
{
    unsigned char address;
        char item;
    unsigned char max,min;


    if(sel==1)  {address=DS3231_HOUR; max=23;min=0;}    //小时
        if(sel==2)  {address=DS3231_MINUTE; max=59;min=0;}    //分钟
    if(sel==3)  {address=DS3231_SECOND; max=59;min=0;}    //秒
       
    if(sel==4)  {address=DS3231_YEAR; max=99;min=0;}    //年
        if(sel==5)  {address=DS3231_MONTH; max=12;min=1;}    //月
        if(sel==6)                                                                                         //日
        {
                if(month==2)
                {
                        if(month == 2 && year % 4 != 0)
                        {
                                  {address=DS3231_DAY; max=28;min=1;}
                        }
                        else
                        {
                                  {address=DS3231_DAY; max=27;min=1;}
                        }
                }
                else
                {
                           if(month==1|month==3|month==5|month==7|month==8|month==10|month==12)
                        {   
                                  {address=DS3231_DAY; max=31;min=1;}
                        }
                        if(month==4|month==6|month==9|month==11)
                        {   
                                  {address=DS3231_DAY; max=30;min=1;}
                        }
                }
        }


    if(sel==7)  {address=DS3231_WEEK; max=7; min=1;}    //星期

           item= read_random(address);
    if (selby==0) item++;  else item--;
    if(item>max) item=min;   
    if(item<min) item=max;

    ModifyTime(address, item);
}         

void KEY()
{
        if(a1==0)
   {
        if(KEY1==0)
        {
                Delay5US();
                if(KEY1==0)
                {
       
                disflag++;
                if(disflag>=8 || KEY4==0)
                {
                        disflag=0;
                       
                }
            a1=1;
               
                }
        }
   }
   if(KEY1==1)
   {
   a1=0;
   }
/********************************/
        if(a4==0)
   {
        if(KEY4==0)
        {
                Delay5US();
                if(KEY4==0 && disflag!=0 )
                {
                        disflag=0;
                }
            a4=1;
        }
   }
   if(KEY4==1)
   {
   a4=0;
   }


///////////////////////   
        if(a2==0)
        {
                if(KEY2==0)
                {
                        Delay5US();
                        if(KEY2==0)
                        {               
                                Set(disflag,0);
                            a2=1;
                        }
                }
        }
   if(KEY2==1)
   {
           a2=0;
   }


   if(a3==0)
   {
        if(KEY3==0)
        {
                Delay5US();
                if(KEY3==0)
                {               
                       
                        Set(disflag,1);        
                    a3=1;
               
                }
        }
   }
   if(KEY3==1)
   {
   a3=0;
   }
}          

/**********农历显示***********/       
void display_nl()
{
        Conversion(year,month,day);        //公历转农历
        if (month_moon==1) OLED_hzStr(0,6,15); //农历一月,显示“正”
        if (month_moon==2) OLED_hzStr(0,6,2);  //农历二月,显示“二”
        if (month_moon==3) OLED_hzStr(0,6,3);  //农历三月,显示“三”
        if (month_moon==4) OLED_hzStr(0,6,4);  //农历四月,显示“四”
        if (month_moon==5) OLED_hzStr(0,6,5);  //农历五月,显示“五”
        if (month_moon==6) OLED_hzStr(0,6,6);  //农历六月,显示“六”
        if (month_moon==7) OLED_hzStr(0,6,7);  //农历七月,显示“七”
        if (month_moon==8) OLED_hzStr(0,6,8);  //农历八月,显示“八”
        if (month_moon==9) OLED_hzStr(0,6,9);  //农历九月,显示“九”
        if (month_moon==10) OLED_hzStr(0,6,10);//农历十月,显示“十”
        if (month_moon==11) OLED_hzStr(0,6,16);//农历十一月,显示“冬”
        if (month_moon==12) OLED_hzStr(0,6,17);//农历十二月,显示“腊”

        OLED_hzStr(16,6,18);  //显示“月”字

        if (day_moon==1){OLED_hzStr(32,6,19); OLED_hzStr(48,6,1);}        //农历一日,显示“初一”
        if (day_moon==2){OLED_hzStr(32,6,19); OLED_hzStr(48,6,2);}        //农历二日,显示“初二”
        if (day_moon==3){OLED_hzStr(32,6,19); OLED_hzStr(48,6,3);}        //农历三日,显示“初三”
        if (day_moon==4){OLED_hzStr(32,6,19); OLED_hzStr(48,6,4);}        //农历四日,显示“初四”
        if (day_moon==5){OLED_hzStr(32,6,19); OLED_hzStr(48,6,5);}        //农历五日,显示“初五”
        if (day_moon==6){OLED_hzStr(32,6,19); OLED_hzStr(48,6,6);}        //农历六日,显示“初六”
        if (day_moon==7){OLED_hzStr(32,6,19); OLED_hzStr(48,6,7);}        //农历七日,显示“初七”
        if (day_moon==8){OLED_hzStr(32,6,19); OLED_hzStr(48,6,8);}        //农历八日,显示“初八”
        if (day_moon==9){OLED_hzStr(32,6,19); OLED_hzStr(48,6,9);}        //农历九日,显示“初九”
        if (day_moon==10){OLED_hzStr(32,6,19); OLED_hzStr(48,6,10);}//农历十日,显示“初十”
        if (day_moon==11){OLED_hzStr(32,6,10); OLED_hzStr(48,6,1);}        //农历十一日,显示“十一”
        if (day_moon==12){OLED_hzStr(32,6,10); OLED_hzStr(48,6,2);}        //农历十二日,显示“十二”
        if (day_moon==13){OLED_hzStr(32,6,10); OLED_hzStr(48,6,3);}        //农历十三日,显示“十三”
        if (day_moon==14){OLED_hzStr(32,6,10); OLED_hzStr(48,6,4);}        //农历十四日,显示“十四”
        if (day_moon==15){OLED_hzStr(32,6,10); OLED_hzStr(48,6,5);}        //农历十五日,显示“十五”
        if (day_moon==16){OLED_hzStr(32,6,10); OLED_hzStr(48,6,6);}        //农历十六日,显示“十六”
        if (day_moon==17){OLED_hzStr(32,6,10); OLED_hzStr(48,6,7);}        //农历十七日,显示“十七”
        if (day_moon==18){OLED_hzStr(32,6,10); OLED_hzStr(48,6,8);}        //农历十八日,显示“十八”
        if (day_moon==19){OLED_hzStr(32,6,10); OLED_hzStr(48,6,9);}        //农历十九日,显示“十九”
        if (day_moon==20){OLED_hzStr(32,6,2); OLED_hzStr(48,6,10);}        //农历二十日,显示“二十”
        if (day_moon==21){OLED_hzStr(32,6,20); OLED_hzStr(48,6,1);}        //农历二十一日,显示“廿一”
        if (day_moon==22){OLED_hzStr(32,6,20); OLED_hzStr(48,6,2);}        //农历二十二日,显示“廿二”
        if (day_moon==23){OLED_hzStr(32,6,20); OLED_hzStr(48,6,3);}        //农历二十三日,显示“廿三”
        if (day_moon==24){OLED_hzStr(32,6,20); OLED_hzStr(48,6,4);}        //农历二十四日,显示“廿四”
        if (day_moon==25){OLED_hzStr(32,6,20); OLED_hzStr(48,6,5);}        //农历二十五日,显示“廿五”
        if (day_moon==26){OLED_hzStr(32,6,20); OLED_hzStr(48,6,6);}        //农历二十六日,显示“廿六”
        if (day_moon==27){OLED_hzStr(32,6,20); OLED_hzStr(48,6,7);}        //农历二十七日,显示“廿七”
        if (day_moon==28){OLED_hzStr(32,6,20); OLED_hzStr(48,6,8);}        //农历二十八日,显示“廿八”
        if (day_moon==29){OLED_hzStr(32,6,20); OLED_hzStr(48,6,9);}        //农历二十九日,显示“廿九”
        if (day_moon==30){OLED_hzStr(32,6,3); OLED_hzStr(48,6,10);}        //农历三十日,显示“三十”
}

/*********************/       
void get_Temperature()         //温度获取 显示
{
    uchar Tem_L;
        uchar Tem_H;
    Tem_H=read_random1(DS3231_TEMPERATUREH);    //温度 高字节 整数部分
        Tem_L=read_random1(DS3231_TEMPERATUREL);         //温度 低字节 小数部分
       
        Tem_L = (Tem_L>>6)*0.25*100;         //
       
        OLED_hzStr(64,6,21);                   //显示温度图标  大
       
        //Tem_H = 0xf7;         //-13的补码,测试用
        //        Tem_H = 0xf7;         //-9的补码,测试用
       
        if(!(Tem_H & 0x80))        //正温度
        {
       
                /********显示温度*********/
                if(Tem_H/10 > 0)
                        OLED_P8x16Str(80,6,Tem_H/10);  //显示温度十位
                else
                        OLED_P8x16Str(80,6,12);             //否则温度十位为0不显示
                OLED_P8x16Str(88,6,Tem_H%10);  //显示温度个位
                OLED_P8x16Str(96,6,14);                   //显示小数点
                OLED_P8x16Str(104,6,Tem_L/10); //显示温度小数第1位
//                OLED_P8x16Str(112,6,Tem_L%10); //显示温度小数第2位
        }
        else
        {
                if(Tem_H & 0x80)         //负温度
                {
                        Tem_H =(~Tem_H)+1; //换算成实际温度值
                        OLED_P8x16Str(80,6,11);        //显示“-”负号
                        if(Tem_H/10 > 0)
                                OLED_P8x16Str(88,6,Tem_H/10);//显示负温度十位
                        else
                                OLED_P8x16Str(88,6,12);         //负温度十位为0不显
                        OLED_P8x16Str(96,6,Tem_H%10);//显示负温度个位       
                }
        }
        OLED_hzStr(112,6,14);                   //显示℃符号

}       

                                                       
void main(void)
{
        OLED_Init(); //OLED初始化
        OLED_CLS();         //OLED复位
        Timer0Init();//定时器初始化
        while(1)
        {
                year = read_random(DS3231_YEAR);               
            month = read_random(DS3231_MONTH);       
            day = read_random(DS3231_DAY);       
            week = read_random(DS3231_WEEK);
                hour = read_random(DS3231_HOUR);
                minute = read_random(DS3231_MINUTE) ;
                second = read_random(DS3231_SECOND);
//                TH3231=        get_Temperature();
               
                OLED_P8x16Str(0,0,2);                //显示 2       
                OLED_P8x16Str(8,0,0);                //显示 0
                if(disflag==4 && flag==0)  //校时是 的候年闪烁
                {       
                        OLED_P8x16Str(16,0,12);        //不显
                        OLED_P8x16Str(24,0,12);        //不显
                }
                else
                {
                        OLED_P8x16Str(16,0,year/10); //显示年 十位
                        OLED_P8x16Str(24,0,year%10); //显示年 个位
               
                }       
               
                OLED_P8x16Str(32,0,11);                   //显示 -
               
                if(disflag==5 && flag==0)  //校时 的时候月闪烁
                {       
                        OLED_P8x16Str(40,0,12);        //不显
                        OLED_P8x16Str(48,0,12);        //不显
                }
                else
                {
                        OLED_P8x16Str(40,0,month/10); //显示 月十位
                        OLED_P8x16Str(48,0,month%10); //显示 月个位
               
                }
                OLED_P8x16Str(56,0,11);                //显示 -
       
                if(disflag==6 && flag==0)  //校时的时候日闪烁
                {
                        OLED_P8x16Str(64,0,12);        //不显
                        OLED_P8x16Str(72,0,12);        //不显
                }
                else
                {
                        OLED_P8x16Str(64,0,day/10);        //显示 日十位
                        OLED_P8x16Str(72,0,day%10);        //显示 日个位
               
                }
               
                OLED_hzStr(80,0,11);        // 显示‘星’
                OLED_hzStr(96,0,12);        // 显示“期”
       
                if(disflag==7 && flag==0)  //校时的时候星期闪烁
                {
                        OLED_hzStr(112,0,13);  //不显
                }
                else
                {
                        if(week==7) week=0;           //如果星期等于7,显示“日”
                        OLED_hzStr(112,0,week);//显示 星期
               
                }
       
                if(disflag==1 && flag==0)  //校时的时候小时闪烁
                {
                        OLED_P32x64Str(0,2,11);         //不显
                        OLED_P32x64Str(16,2,11); //不显       
                }
                else
                {
                        OLED_P32x64Str(0,2,hour/10);       
                        OLED_P32x64Str(16,2,hour%10);       
                }
       
//                if(shan_count >= 50 && disflag==0)         //正常走时,如果shan_count>=50        ,冒号闪烁晃眼,将其屏蔽
                OLED_P32x64Str(32,2,10);                          //就显示“:”号
//                else OLED_P32x64Str(32,2,11);                 //否则不显冒号
       
                if(disflag==2 && flag==0)  //校时的时候分闪烁
                {
                        OLED_P32x64Str(48,2,11);        //不显       
                        OLED_P32x64Str(64,2,11);        //不显
                }
                else
                {
                        OLED_P32x64Str(48,2,minute/10);        //显示分十位
                        OLED_P32x64Str(64,2,minute%10);        //显示分个位
               
                }
       
       
//                if(shan_count >= 50 && disflag==0)        //正常走时,如果shan_count>=50
                OLED_P32x64Str(80,2,10);                        //就显示“:”号
//                else OLED_P32x64Str(80,2,11);                //否则不显冒号
               
                if(disflag==3 && flag==0)  //校时的时候秒闪烁
                {
                        OLED_P32x64Str(96,2,11);        //不显
                        OLED_P32x64Str(112,2,11);        //不显
                }
                else
                {
                        OLED_P32x64Str(96,2,second/10);         //显示秒十位
                        OLED_P32x64Str(112,2,second%10); //显示秒个位
               
                }
       
//           OLED_P8x16Str(80,6,13);                      //显示温度图标
//           if(TH3231/10 > 0)
//           OLED_P8x16Str(96,6,TH3231/10);  //显示温度十位
//           else       
//           OLED_P8x16Str(96,6,12);                      //温度十位不显
//           OLED_P8x16Str(104,6,TH3231%10); //显示温度个位
//           OLED_hzStr(112,6,14);        //显示℃符号
       
                get_Temperature();

           display_nl();         //显示农历

           KEY();           //按键程序
               
        }
}

/**************定时器0 中断函数******************/

void timer0() interrupt 1
{
        TL0 = 0x00;                //重装定时初值10ms
        TH0 = 0xDC;                //重装定时初值

        shan_count++;
        if(shan_count == 100)        //:号闪烁,亮0.5秒,灭0.5秒;闪烁频率可调。
        {
                shan_count = 0;
        }

        shan_js++;                   //校时闪烁
        if(shan_js == 25)  //250ms闪烁一次
        {
                shan_js = 0;
                flag = !flag;
        }

}


回复

使用道具 举报

ID:372579 发表于 2021-3-11 14:01 来自手机 | 显示全部楼层
这个做个记号到时候自己也做一个
回复

使用道具 举报

ID:81196 发表于 2021-3-11 16:24 | 显示全部楼层
源码清晰,设计也可以,还外加了保护壳,真不错.
回复

使用道具 举报

ID:143767 发表于 2021-3-20 20:02 | 显示全部楼层
6313 发表于 2021-1-14 23:28
下载压缩包,解压,里面是HEX文件,直接下载到单片机就可以用了

压缩包在哪里?
回复

使用道具 举报

ID:828712 发表于 2021-3-23 12:36 | 显示全部楼层
压缩包在哪里?
回复

使用道具 举报

ID:385637 发表于 2021-3-24 11:55 | 显示全部楼层
好东东,51黑有你更精彩
回复

使用道具 举报

ID:900587 发表于 2021-4-25 21:38 | 显示全部楼层
求源代码!!!!
回复

使用道具 举报

ID:903667 发表于 2021-4-27 00:13 | 显示全部楼层
是否有类比指针方式?~~~~

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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