找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6367|回復: 21
打印 上一主題 下一主題
收起左側

做了一個oled時鐘

  [復制鏈接]
跳轉到指定樓層
樓主
ID:849826 發(fā)表于 2021-1-14 23:26 來自手機 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機用的STC89C52,時鐘模塊用的是ds3231,帶萬年歷,溫度顯示。oled用的是0.96吋四腳藍色的。

6ccf08a26a772b8c.jpg (322.53 KB, 下載次數: 101)

6ccf08a26a772b8c.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:849826 發(fā)表于 2021-1-14 23:28 | 只看該作者
本帖最后由 6313 于 2021-1-14 23:41 編輯

下載壓縮包,解壓,里面是HEX文件,直接下載到單片機就可以用了
回復

使用道具 舉報

板凳
ID:673647 發(fā)表于 2021-1-15 08:02 | 只看該作者
謝謝分享!只是好像沒有附件。
回復

使用道具 舉報

地板
ID:16255 發(fā)表于 2021-1-15 08:21 | 只看該作者
很好。只是屏幕有點小。
回復

使用道具 舉報

5#
ID:390416 發(fā)表于 2021-1-15 20:47 | 只看該作者
DS3231+WS2812全彩RGB掛鐘資料分享 http://www.torrancerestoration.com/bbs/dpj-200965-1.html
回復

使用道具 舉報

6#
ID:849826 發(fā)表于 2021-1-16 09:24 來自手機 | 只看該作者
cwb2038 發(fā)表于 2021-1-15 08:02
謝謝分享!只是好像沒有附件。

用手機傳了好幾次,傳不上去
回復

使用道具 舉報

7#
ID:856401 發(fā)表于 2021-1-16 22:58 | 只看該作者
樓主期待你的原理圖,很代碼。很實用的東西,很想做一個
回復

使用道具 舉報

8#
ID:95809 發(fā)表于 2021-1-17 05:57 | 只看該作者
3486635230 發(fā)表于 2021-1-16 22:58
樓主期待你的原理圖,很代碼。很實用的東西,很想做一個

很簡單,OLED和DS3231共用I2C總線,你單片機有兩個IO就行,我是使用的15單片機,

2021-01-17_05-54-33.jpg (52.63 KB, 下載次數: 74)

原理圖

原理圖

51hei圖片_202101170553332.jpg (137.27 KB, 下載次數: 85)

PCB

PCB

51hei圖片_20210117055333.jpg (136.74 KB, 下載次數: 77)

PCB背面

PCB背面

51hei圖片_202101170553331.jpg (148.32 KB, 下載次數: 66)

效果

效果
回復

使用道具 舉報

9#
ID:230742 發(fā)表于 2021-1-17 12:49 | 只看該作者
好東西啊。留個記號,我也做一個。
回復

使用道具 舉報

10#
ID:684871 發(fā)表于 2021-1-17 23:55 來自手機 | 只看該作者
很實用,感謝樓主分享
回復

使用道具 舉報

11#
ID:46750 發(fā)表于 2021-1-19 09:10 | 只看該作者
bxyyhan 發(fā)表于 2021-1-17 05:57
很簡單,OLED和DS3231共用I2C總線,你單片機有兩個IO就行,我是使用的15單片機,

@樓主,代碼可以開源嗎?
回復

使用道具 舉報

12#
ID:471297 發(fā)表于 2021-1-19 12:26 | 只看該作者
6313 發(fā)表于 2021-1-14 23:28
下載壓縮包,解壓,里面是HEX文件,直接下載到單片機就可以用了

很不錯,可是看不到附件,能上次論壇嗎?謝謝。這個是讀取DS3231溫度,不知能改成DS18B02嗎?不影響現有的農歷星期日期。網上看到有的用18B02 但沒有農歷
回復

使用道具 舉報

13#
ID:471297 發(fā)表于 2021-1-19 12:35 | 只看該作者
bxyyhan 發(fā)表于 2021-1-17 05:57
很簡單,OLED和DS3231共用I2C總線,你單片機有兩個IO就行,我是使用的15單片機,

請問這個能改成不影響其他內容,讀取DS18B02溫度嗎?這樣溫度就更精準對吧,這個電路板是自己做的,還是網上淘來的呢,很漂亮
回復

使用道具 舉報

14#
ID:423238 發(fā)表于 2021-1-20 08:07 來自手機 | 只看該作者
原理圖

08-01-34-165443dya44r7uu23q24z7.jpg (184.06 KB, 下載次數: 75)

08-01-34-165443dya44r7uu23q24z7.jpg
回復

使用道具 舉報

15#
ID:95809 發(fā)表于 2021-1-20 21:07 | 只看該作者
zenghl 發(fā)表于 2021-1-19 09:10
@樓主,代碼可以開源嗎?

代碼不是我寫的,原帖子在此:http://www.torrancerestoration.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    //溫度寄存器高字節(jié)(8位)        整數部分
#define DS3231_TEMPERATUREL 0x12    //溫度寄存器低字節(jié)(低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;                          //判斷發(fā)送位
        else
            SDA=0;     
        SCL=1;                            //置時鐘線為高,通知被控器開始接收數據位
        Delay5US();                       //保證時鐘高電平周期大于4μs   
        SCL=0;
    }
    SDA=1;                                  //8位發(fā)送完后釋放數據線,準備接收應答位
    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總線以便繼續(xù)接收
    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);    //溫度 高字節(jié) 整數部分
        Tem_L=read_random1(DS3231_TEMPERATUREL);         //溫度 低字節(jié) 小數部分
       
        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;
        }

}


回復

使用道具 舉報

16#
ID:372579 發(fā)表于 2021-3-11 14:01 來自手機 | 只看該作者
這個做個記號到時候自己也做一個
回復

使用道具 舉報

17#
ID:81196 發(fā)表于 2021-3-11 16:24 | 只看該作者
源碼清晰,設計也可以,還外加了保護殼,真不錯.
回復

使用道具 舉報

18#
ID:143767 發(fā)表于 2021-3-20 20:02 | 只看該作者
6313 發(fā)表于 2021-1-14 23:28
下載壓縮包,解壓,里面是HEX文件,直接下載到單片機就可以用了

壓縮包在哪里?
回復

使用道具 舉報

19#
ID:828712 發(fā)表于 2021-3-23 12:36 | 只看該作者
壓縮包在哪里?
回復

使用道具 舉報

20#
ID:385637 發(fā)表于 2021-3-24 11:55 | 只看該作者
好東東,51黑有你更精彩
回復

使用道具 舉報

21#
ID:900587 發(fā)表于 2021-4-25 21:38 | 只看該作者
求源代碼!。。
回復

使用道具 舉報

22#
ID:903667 發(fā)表于 2021-4-27 00:13 | 只看該作者
是否有類比指針方式?~~~~

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表