找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
楼主: lids
打印 上一主题 下一主题
收起左侧

OLED12864+DS3231的万年历制作,带农历,大字体(单片机源码+实物)

  [复制链接]
跳转到指定楼层
楼主
最近逛论坛,看到有做OLED 屏幕显示的万年历,但都没有把农历加进去;我这个把农历加上了,时分秒大字体显示;温度是读的DS3231的温度显示出来的;OLED12864和DS3231时钟芯片都是IIC通信的,共用时钟线和数据线,接线简单;4个按键(设置,+,-,退出),校时的时候,按设置键,相应的位会闪烁,再按+-调整,设置键按到第8次就退出设置,设置的位较多,中途按退出键也可以退出设置。单片机:用12T,或1T的都可以,我用的STC12C5A60S2,1T刷新快些;DS3231是买的模块;OLED是0.96寸黄蓝双色的,实物比照片好看,就是太小了,
附件里有完整的源代码。

制作出来的实物图如下:


部分源代码:
  1. #include "reg51.h"
  2. #include "intrins.h"
  3. #include "codetab.h"
  4. #include "nongli.h"


  5. #define uint  unsigned int
  6. #define uchar unsigned char

  7. // ------------------------------------------------------------
  8. // IO口模拟I2C通信

  9. // ------------------------------------------------------------
  10. sbit SCL=P3^6; //串行时钟
  11. sbit SDA=P3^7; //串行数据

  12. sbit KEY1=  P3^0;                  //调整
  13. sbit KEY2=  P3^1;                  //++
  14. sbit KEY3=  P3^2;                  //--
  15. sbit KEY4=  P3^3;                  //退出

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



  18. #define        Brightness        0xcf //
  19. #define X_WIDTH         128
  20. #define Y_WIDTH         64

  21. /********************************************************************************************************
  22. **         DS3231常数定义
  23. ********************************************************************************************************/
  24. #define DS3231_WriteAddress 0xD0    //器件写地址
  25. #define DS3231_ReadAddress  0xD1    //器件读地址
  26. #define DS3231_SECOND       0x00    //秒
  27. #define DS3231_MINUTE       0x01    //分
  28. #define DS3231_HOUR         0x02    //时
  29. #define DS3231_WEEK         0x03    //星期
  30. #define DS3231_DAY          0x04    //日
  31. #define DS3231_MONTH        0x05    //月
  32. #define DS3231_YEAR         0x06    //年

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



  35. #define NACK    1
  36. #define ACK     0

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


  54. /**************************/
  55. void Timer0Init(void)                //10毫秒@11.0592MHz
  56. {
  57. //        AUXR &= 0x7F;                //定时器时钟12T模式
  58.         TMOD &= 0xF0;                //设置定时器模式
  59.         TMOD |= 0x01;                //设置定时器0,16位模式
  60.         TL0 = 0x00;                //设置定时初值
  61.         TH0 = 0xDC;                //设置定时初值
  62.         TF0 = 0;                //清除TF0标志
  63.         TR0 = 1;                //定时器0开始计时
  64.         ET0 = 1;
  65.         EA = 1;
  66. }

  67. /**********************************************
  68. //IIC Start
  69. **********************************************/
  70. void IIC_Start()
  71. {
  72.    SCL = 1;               
  73.    SDA = 1;
  74.    SDA = 0;
  75.    SCL = 0;
  76. }

  77. /**********************************************
  78. //IIC Stop
  79. **********************************************/
  80. void IIC_Stop()
  81. {
  82.    SCL = 0;
  83.    SDA = 0;
  84.    SCL = 1;
  85.    SDA = 1;
  86. }


  87. /********************************************************************************************************
  88. **         3231
  89. ********************************************************************************************************/


  90. uchar        BCD2HEX(uchar val)
  91. {
  92.         return        ((val>>4)*10)+(val&0x0f);
  93. }

  94. uchar        HEX2BCD(uchar val)
  95. {
  96.         return        (((val%100)/10)<<4)|(val%10);
  97. }


  98. void SendByte(uchar c)
  99. {
  100.     uchar BitCnt;
  101.    
  102.     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  103.     {
  104.         if((c<<BitCnt)&0x80)
  105.             SDA=1;                          //判断发送位
  106.         else
  107.             SDA=0;     
  108.         SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  109.         Delay5US();                       //保证时钟高电平周期大于4μs   
  110.         SCL=0;
  111.     }
  112.     SDA=1;                                  //8位发送完后释放数据线,准备接收应答位
  113.     SCL=1;
  114.     Delay5US();
  115.     if(SDA==1)
  116.         ack=0;   
  117.     else
  118.         ack=1;                              //判断是否接收到应答信号
  119.     SCL=0;
  120.     Delay5US();
  121. }           

  122. uchar RcvByte()
  123. {
  124.    uchar retc;
  125.    uchar BitCnt;

  126.    retc=0;
  127.    SDA=1;                           //置数据线为输入方式
  128.    for(BitCnt=0;BitCnt<8;BitCnt++)
  129.    {
  130.         SCL=0;                      //置时钟线为低,准备接收数据位      
  131.         Delay5US();                 //时钟低电平周期大于4.7μs                       
  132.         SCL=1;                      //置时钟线为高使数据线上数据有效
  133.         Delay5US();
  134.         retc=retc<<1;
  135.         if(SDA==1)
  136.             retc=retc+1;            //读数据位,接收的数据位放入retc中
  137.         Delay5US();
  138.    }
  139.    SCL=0;
  140.    return(retc);
  141. }                           

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

  150. uchar write_byte(uchar addr, uchar write_data)
  151. {
  152.     IIC_Start();
  153.     SendByte(DS3231_WriteAddress);
  154.     if (ack == 0)
  155.         return 0;
  156.    
  157.     SendByte(addr);   
  158.     if (ack == 0)
  159.         return 0;
  160.    
  161.     SendByte(write_data);
  162.     if (ack == 0)
  163.         return 0;
  164.    
  165.     IIC_Stop();
  166.     Delay5US();      
  167.     Delay5US();      
  168.     return 1;
  169. }                                          

  170. uchar read_current()
  171. {
  172.     uchar read_data;
  173.     IIC_Start();
  174.     SendByte(DS3231_ReadAddress);
  175.     if(ack==0)
  176.         return(0);              
  177.     read_data = RcvByte();
  178.     Ack_I2C(1);
  179.     IIC_Stop();
  180.     return read_data;
  181. }                                                

  182. uchar read_random(uchar random_addr)
  183. {
  184.     uchar Tmp;
  185.         IIC_Start();
  186.     SendByte(DS3231_WriteAddress);
  187.     if(ack==0)
  188.         return(0);            
  189.     SendByte(random_addr);
  190.     if(ack==0)
  191.         return(0);
  192.         Tmp=read_current();
  193.         if(random_addr==DS3231_HOUR)
  194.                 Tmp&=0x3f;
  195.                                             
  196.     return(BCD2HEX(Tmp));//都转10进制输出
  197. }

  198. /***********************/
  199. uchar read_random1(uchar random_addr)  //这个是读温度函数
  200. {
  201.     uchar Tmp;
  202.         write_byte(0x0e,0x20);//0x0e寄存器的CONV位置1开启温度转换,要这句,温度实时刷新,这句不要,温度要64s才刷新1次
  203.         IIC_Start();
  204.     SendByte(DS3231_WriteAddress);
  205.     if(ack==0)
  206.         return(0);            
  207.     SendByte(random_addr);
  208.     if(ack==0)
  209.         return(0);
  210.         Tmp=read_current();
  211.         return Tmp;
  212. }                                 

  213. void ModifyTime(uchar address,uchar num)
  214. {
  215.     uchar temp=0;
  216.            if(address>6 && address <0) return;
  217.     temp=HEX2BCD(num);
  218.         write_byte(address,temp);
  219. }
复制代码

全部资料51hei下载地址:
OLED 万年历 (显示正负温度版).rar (224.28 KB, 下载次数: 1627)




评分

参与人数 7黑币 +186 收起 理由
wenzedong + 15
slhslhhao + 8 共享资料的黑币奖励!
HJJQQ + 8 共享资料的黑币奖励!
凌净清河 + 15 美观和功能兼有,真是佳作了!
清风兑酒 + 10 很给力!
溯行 + 30 最近刚好在找^O^
admin + 100 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:140489 发表于 2019-2-18 11:59 | 显示全部楼层
ygnlhxyzj 发表于 2019-2-15 11:04
请问楼主,农历如何计算

资料里面有农历转换的程序,你下载看看就知道了
回复

使用道具 举报

板凳
ID:140489 发表于 2019-2-18 16:23 | 显示全部楼层
YQS 发表于 2019-2-18 12:56
谢谢楼主分享好资料,请问可否加入GPS或WIFI主动校时?

DS3231内部带温补晶振,精度已经很高了,没必要加GPS校时了
回复

使用道具 举报

地板
ID:140489 发表于 2019-2-18 16:27 | 显示全部楼层
YQS 发表于 2019-2-18 12:56
谢谢楼主分享好资料,请问可否加入GPS或WIFI主动校时?

DS3231供电用3.3V,精度很高的,测试了2个月,与手机时间对比1秒不差
回复

使用道具 举报

5#
ID:140489 发表于 2019-3-28 16:55 | 显示全部楼层

电路图

OLED.jpg (49.3 KB, 下载次数: 211)

OLED.jpg
回复

使用道具 举报

6#
ID:140489 发表于 2019-4-1 12:34 | 显示全部楼层
luxianjun 发表于 2019-3-29 08:06
手上没有12c5a60s2.用15f2k60s2芯片测试了一下,显示不正常,要更改那里。

改接口定义就可以了,sbit SCL=P?^?; //串行时钟
sbit SDA=P?^?; //串行数据
把?号改为你硬件连接的端口
回复

使用道具 举报

7#
ID:140489 发表于 2019-4-9 12:06 | 显示全部楼层
晴天彡小霖 发表于 2019-4-8 20:21
急。。调试没反应,就是按键没反应,还有时钟也没有反应。

看下你接线有没有错,只要线接对了,不会有问题的
回复

使用道具 举报

8#
ID:140489 发表于 2019-4-11 09:21 | 显示全部楼层
晴天彡小霖 发表于 2019-4-10 16:01
它一直保持这个图片,就是不会开始运行

时钟模块的sck,sda和oled的sck,sda是接在一起的,看图片,时钟模块的数据是读出来了的,具体原因靠你自己查找了
回复

使用道具 举报

9#
ID:140489 发表于 2019-4-11 09:26 | 显示全部楼层
可爱的小丹宝 发表于 2019-4-10 18:30
楼主 这个用纽扣电池供电可以吗?

你选用3.3V供电的单片机应该可以的,你可以试一下
回复

使用道具 举报

10#
ID:140489 发表于 2019-9-27 14:53 | 显示全部楼层
youchuang 发表于 2019-9-2 23:19
感谢楼主的分享!我DIY了一个,感觉挺漂亮的,只是个人觉得0.96寸的屏小了一点。

我自己也觉得有点小
回复

使用道具 举报

11#
ID:140489 发表于 2019-10-17 16:51 | 显示全部楼层
dvxchen 发表于 2019-10-16 16:22
OLED 和 DS3231共用SDA和SCL吗?

是的,第1页有原理图
回复

使用道具 举报

12#
ID:140489 发表于 2021-1-12 08:18 | 显示全部楼层
快乐a123 发表于 2021-1-11 18:53
温度需要单独的模块吗?还是时钟模块带温度测试功能?

温度是时钟模块自带的
回复

使用道具 举报

13#
ID:140489 发表于 2021-1-15 14:43 | 显示全部楼层
6313 发表于 2021-1-14 04:42
压缩包里面的文件,解压后,keil加载C文件编译不通过。HEX文件下载到89C52里面,按键会变的异常迟钝,不知 ...

89C52S是12T单片机,延时要调整一下才行的,程序里面都有注释的
回复

使用道具 举报

14#
ID:140489 发表于 2021-1-28 08:45 | 显示全部楼层
墨小铭 发表于 2021-1-27 09:15
显示是对的,但是屏幕一直在闪是怎么回事呢

你用的是1T的还是12T的单片机
回复

使用道具 举报

15#
ID:140489 发表于 2021-4-28 08:20 | 显示全部楼层
了凡命馆 发表于 2021-4-26 11:56
STC12C5A60S2
麻烦问一下,oled12864  各端口定义在源文件没看到啊。楼主能否指点下

你看下本帖的28楼,有原理图的
回复

使用道具 举报

16#
ID:140489 发表于 2022-11-28 09:21 | 显示全部楼层
leezll 发表于 2022-11-26 10:28
我用STC8G1K的单片机运行就点不亮OLED,单片机的频率和程序频率都调整为6.000MHZ了,还是不能运行。。。求 ...

STC8G1K单片机要设置端口的模式才行的
回复

使用道具 举报

17#
ID:140489 发表于 2022-11-28 09:29 | 显示全部楼层
leezll 发表于 2022-11-26 10:28
我用STC8G1K的单片机运行就点不亮OLED,单片机的频率和程序频率都调整为6.000MHZ了,还是不能运行。。。求 ...

仔细看下STC8G的规格书

51hei截图20221128092655.png (34.79 KB, 下载次数: 116)

51hei截图20221128092655.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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