找回密码
 立即注册

QQ登录

只需一步,快速开始

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

四脚OLED 12864,ds1302闹钟,按键调闹钟,调时间单片机程序

  [复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1. //////////////////////////////////////////////////////////////////////////////////        
  2. //
  3. //  文 件 名   : main.c
  4. //  版 本 号   : v2.0
  5. //  作    者   : HuangKai
  6. //  生成日期   : 2014-0101
  7. //  最近修改   :
  8. //  功能描述   : OLED 4接口演示例程(51系列)
  9. //              说明:
  10. //              ----------------------------------------------------------------
  11. //              GND    电源地
  12. //              VCC  接5V或3.3v电源
  13. //              D0   P1^0(SCL)
  14. //              D1   P1^1(SDA)
  15. //              RES  接P12
  16. //              DC   接P13
  17. //              CS   接P14               
  18. //              ----------------------------------------------------------------
  19. //All rights reserved
  20. //******************************************************************************/
  21. #include "REG51.h"
  22. #include "oled.h"
  23. #include "bmp.h"


  24. #define uchar unsigned char
  25. #define uint  unsigned int
  26.         //DS1302引脚定义,可根据实际情况自行修改端口定义
  27. sbit RST=P3^1;
  28. sbit IO=P3^2;
  29. sbit SCK=P3^3;
  30. //DS1302地址定义
  31. #define ds1302_sec_add                        0x80                //秒数据地址
  32. #define ds1302_min_add                        0x82                //分数据地址
  33. #define ds1302_hr_add                        0x84                //时数据地址
  34. #define ds1302_date_add                        0x86                //日数据地址
  35. #define ds1302_month_add                0x88                //月数据地址
  36. #define ds1302_day_add                        0x8a                //星期数据地址
  37. #define ds1302_year_add                        0x8c                //年数据地址
  38. #define ds1302_control_add                0x8e                //控制数据地址
  39. #define ds1302_charger_add                0x90                                          
  40. #define ds1302_clkburst_add                0xbe
  41. //初始时间定义
  42. uchar time_buf[8] = {0x20,0x10,0x09,0x14,0x23,0x59,0x50,0x02};//初始时间
  43. uchar readtime[14];//当前时间
  44. uchar set[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x03,0x00};//年月日的每一位
  45. uchar sec_buf=0;  //秒缓存
  46. uchar sec_flag=0; //秒标志位
  47. //功能:延时1毫秒
  48. //入口参数:x
  49. //出口参数:无
  50. //说明:晶振为12M

  51. /***********************按键定义*************************************************/
  52. sbit key1=P2^0;
  53. sbit key2=P2^1;
  54. sbit key3=P2^2;
  55. uchar status=0,sta=0;//按键功能选择定义(年0,月1,日2,时3,分4 )
  56. /////////////////////////////////////////////
  57. sbit led = P0^0;
  58. sbit key_stop = P0^1;
  59. sbit nao1 = P0^2;
  60. sbit nao2 = P0^3;
  61. ////////////////

  62. void delay(uint t)  
  63. {
  64. uint b;
  65. for(;t;t--)
  66.   for(b=0;b<121;b++);
  67. }
  68. void Delay_xms(uint x)
  69. {
  70.   uint i,j;
  71.   for(i=0;i<x;i++)
  72.     for(j=0;j<112;j++);
  73. }
  74. //DS1302初始化函数
  75. void ds1302_init(void)
  76. {
  77.         RST=0;                        //RST脚置低
  78.         SCK=0;                        //SCK脚置低
  79. }
  80. //向DS1302写入一字节数据
  81. void ds1302_write_byte(uchar addr, uchar d)
  82. {
  83.         uchar i;
  84.         RST=1;                                        //启动DS1302总线        
  85.         //写入目标地址:addr
  86.         addr = addr & 0xFE;   //最低位置零,寄存器0位为0时写,为1时读
  87.         for (i = 0; i < 8; i ++) {
  88.                 if (addr & 0x01) {
  89.                         IO=1;
  90.                         }
  91.                 else {
  92.                         IO=0;
  93.                         }
  94.                 SCK=1;      //产生时钟
  95.                 SCK=0;
  96.                 addr = addr >> 1;
  97.                 }        
  98.         //写入数据:d
  99.         for (i = 0; i < 8; i ++) {
  100.                 if (d & 0x01) {
  101.                         IO=1;
  102.                         }
  103.                 else {
  104.                         IO=0;
  105.                         }
  106.                 SCK=1;    //产生时钟
  107.                 SCK=0;
  108.                 d = d >> 1;
  109.                 }
  110.         RST=0;                //停止DS1302总线
  111. }

  112. //从DS1302读出一字节数据
  113. uchar ds1302_read_byte(uchar addr) {

  114.         uchar i,temp;        
  115.         RST=1;                                        //启动DS1302总线
  116.         //写入目标地址:addr
  117.         addr = addr | 0x01;    //最低位置高,寄存器0位为0时写,为1时读
  118.         for (i = 0; i < 8; i ++) {
  119.                 if (addr & 0x01) {
  120.                         IO=1;
  121.                         }
  122.                 else {
  123.                         IO=0;
  124.                         }
  125.                 SCK=1;
  126.                 SCK=0;
  127.                 addr = addr >> 1;
  128.                 }        
  129.         //输出数据:temp
  130.         for (i = 0; i < 8; i ++) {
  131.                 temp = temp >> 1;
  132.                 if (IO) {
  133.                         temp |= 0x80;
  134.                         }
  135.                 else {
  136.                         temp &= 0x7F;
  137.                         }
  138.                 SCK=1;
  139.                 SCK=0;
  140.                 }        
  141.         RST=0;                                        //停止DS1302总线
  142.         return temp;
  143. }
  144. //向DS302写入时钟数据
  145. void ds1302_write_time(void)
  146. {
  147.         time_buf[1]=(set[0]<<4)|set[1];
  148.         time_buf[2]=(set[2]<<4)|set[3];
  149.         time_buf[3]=(set[4]<<4)|set[5];
  150.         time_buf[4]=(set[6]<<4)|set[7];
  151.         time_buf[5]=(set[8]<<4)|set[9];
  152.         time_buf[6]=(set[10]<<4)|set[11];
  153.         time_buf[7]=(set[12]<<4)|set[13];
  154.         
  155.         ds1302_write_byte(ds1302_control_add,0x00);                        //关闭写保护
  156.         ds1302_write_byte(ds1302_sec_add,0x80);                                //暂停时钟
  157.         //ds1302_write_byte(ds1302_charger_add,0xa9);            //涓流充电
  158.         ds1302_write_byte(ds1302_year_add,time_buf[1]);                //年
  159.         ds1302_write_byte(ds1302_month_add,time_buf[2]);        //月
  160.         ds1302_write_byte(ds1302_date_add,time_buf[3]);                //日
  161.         ds1302_write_byte(ds1302_hr_add,time_buf[4]);                //时
  162.         ds1302_write_byte(ds1302_min_add,time_buf[5]);                //分
  163.         ds1302_write_byte(ds1302_sec_add,time_buf[6]);                //秒
  164.         ds1302_write_byte(ds1302_day_add,time_buf[7]);                //周
  165.         ds1302_write_byte(ds1302_control_add,0x80);                        //打开写保护     
  166. }
  167. //从DS302读出时钟数据
  168. void ds1302_read_time(void)  
  169. {
  170.         time_buf[1]=ds1302_read_byte(ds1302_year_add);                //年
  171.         time_buf[2]=ds1302_read_byte(ds1302_month_add);                //月
  172.         time_buf[3]=ds1302_read_byte(ds1302_date_add);                //日
  173.         time_buf[4]=ds1302_read_byte(ds1302_hr_add);                //时
  174.         time_buf[5]=ds1302_read_byte(ds1302_min_add);                //分
  175.         time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59
  176.         time_buf[7]=ds1302_read_byte(ds1302_day_add);                //周         
  177.         
  178.         readtime[0]=(time_buf[0]>>4);   //分离出年千位
  179.   readtime[1]=(time_buf[0]&0x0F); //分离出年百位
  180.   readtime[2]=(time_buf[1]>>4);   //分离出年十位
  181.   readtime[3]=(time_buf[1]&0x0F); //分离出年个位

  182.   readtime[4]=(time_buf[2]>>4);   //分离出月十位
  183.   readtime[5]=(time_buf[2]&0x0F); //分离出月个位

  184.   readtime[6]=(time_buf[3]>>4);   //分离出日十位
  185.   readtime[7]=(time_buf[3]&0x0F); //分离出日个位

  186.   readtime[8]=(time_buf[4]>>4);   //分离出小时十位
  187.   readtime[9]=(time_buf[4]&0x0F); //分离出小时个位
  188.   readtime[10]=(time_buf[5]>>4);   //分离出分钟十位
  189.   readtime[11]=(time_buf[5]&0x0F); //分离出分钟个位
  190.   readtime[12]=(time_buf[6]>>4);   //分离出秒钟十位
  191.   readtime[13]=(time_buf[6]&0x0F); //分离出秒钟个位
  192. }
  193. /////////////////////////////分离日期函数//////////////////////////


  194.         

  195. /******************************************************************************/
  196. /*****************************按键功能函数*************************************/
  197. void key_1()     //选择变量函数
  198. {
  199.         
  200.          key1=1;
  201.          if(key1==0)
  202.           delay(10);                                                                                                                                                                                                                                
  203.          {
  204.           if(key1==0)
  205.           {
  206.            if(++status>12)status=0; //1控制年千位的变化,2控制年百位的变化,3控制年十位的变化
  207.           }       //4控制年个位的变化,5控制月十位的变化,6月个位,
  208.           while(key1==0);
  209.          }
  210. }
  211. /******************************************************************************/
  212. void key_2()       //加函数
  213. {
  214.         
  215.          key2=1;
  216.          if(key2==0)
  217.          {
  218.                   delay(10);
  219.                   if(key2==0)
  220.                   {
  221.                    switch(status)
  222.                    {
  223.                             case 1:if(++set[0]>9)set[0]=0;break;
  224.                             case 2:if(++set[1]>9)set[1]=0;break;
  225.                             case 3:if(++set[2]>1)set[2]=0;break;
  226.                             case 4:if(++set[3]>9)set[3]=1;break;
  227.                             case 5:if(++set[4]>9)set[4]=0;break;
  228.                                   case 6:if(++set[5]>9)set[5]=0;break;
  229.                                   case 7:if(++set[6]>9)set[6]=0;break;
  230.                                   case 8:if(++set[7]>9)set[7]=0;break;
  231.                                   case 9:if(++set[8]>9)set[8]=0;break;
  232.                                  case 10:if(++set[9]>9)set[9]=0;break;
  233.                                  case 11:if(++set[10]>9)set[10]=0;break;
  234.                                  case 12:if(++set[11]>9)set[11]=0;break;
  235.                                  
  236.                                  
  237.                    }
  238.           }
  239.         while(key2==0);
  240.          }
  241. }
  242. /*****************************************************************************/
  243. void key_3()//减函数
  244. {
  245.         
  246.           key3=1;
  247.          if(key3==0)
  248.          {
  249.                   delay(10);
  250.                   if(key3==0)
  251.                   {
  252.                    switch(status)
  253.                    {
  254.                             case 1:if((set[0]--)<=0)set[0]=9;break;
  255.                             case 2:if((set[1]--)<=0)set[1]=9;break;
  256.                             case 3:if((set[2]--)<=0)set[2]=1;break;
  257.                             case 4:if((set[3]--)<1)set[3]=9;break;
  258.                             case 5:if((set[4]--)<=0)set[4]=9;break;
  259.                                   case 6:if((set[5]--)<=0)set[5]=9;break;
  260.                                   case 7:if((set[6]--)<=0)set[6]=9;break;
  261.                                   case 8:if((set[7]--)<=0)set[7]=9;break;
  262.                                   case 9:if((set[8]--)<=0)set[8]=9;break;
  263.                                   case 10:if((set[9]--)<=0)set[9]=9;break;
  264.                                  case 11:if((set[10]--)<=0)set[10]=9;break;
  265.                                  case 12:if((set[11]--)<=0)set[11]=9;break;
  266. //                                 case 13:if((set[12]--)<=0)set[12]=9;break;
  267. //                                 case 14:if((set[13]--)<=0)set[13]=9;break;
  268. //                                 case 15:if((set[14]--)<=0)set[14]=9;break;
  269. //                                 case 16:if((set[15]--)<=0)set[15]=9;break;
  270.                                  
  271.         
  272.                    }
  273.                   }
  274.                   while(key3==0);
  275.          }
  276. }

  277. /*****************************************************************************/
  278. void key_time()    //按键设置时间的处理
  279. {
  280. if(status>0)
  281. {
  282.          ds1302_write_time();
  283. }
  284. }
  285. ///////////////////////////////闹钟/////////////////////

  286. void naozhong()    //闹钟
  287. {
  288.         if((readtime[8]==set[12])&&(readtime[9]==set[13])&&(readtime[10]==set[14])&&(readtime[11]==set[15])&&(readtime[12]==0)&&(readtime[13]==0))
  289.            led = 0;
  290. }

  291. void stop()
  292. {
  293.         
  294.          key_stop=1;
  295.          if(key_stop==0)
  296.           delay(10);                                                                                                                                                                                                                                
  297.          {
  298.           if(key_stop==0)
  299.           {
  300.            led =1;
  301.           }      
  302.           while(key_stop==0);
  303.          }
  304. }
  305. /////////////////////////////////////
  306. void nao_key1()
  307. {
  308.         nao1=1;
  309.          if(nao1==0)
  310.           delay(10);                                                                                                                                                                                                                                
  311.          {
  312.           if(nao1==0)
  313.           {
  314.            if(++sta>4)sta=0;
  315.           }      
  316.           while(nao1==0);
  317.          }
  318. }
  319. void nao_key2()       //加函数
  320. {
  321.         
  322.         nao2=1;
  323.          if(nao2==0)
  324.          {
  325.                   delay(10);
  326.                   if(nao2==0)
  327.                   {
  328.                    switch(sta)
  329.                    {
  330.                            case 1:if(++set[12]>9)set[12]=0;break;
  331.                                  case 2:if(++set[13]>9)set[13]=0;break;
  332.                                  case 3:if(++set[14]>9)set[14]=0;break;
  333.                                  case 4:if(++set[15]>9)set[15]=0;break;         
  334.                    }
  335.           }
  336.         while(nao2==0);
  337.          }
  338. }


  339. /////////////////////////////////////////////////////////
  340. int main(void)
  341. {        u8 t;
  342.          Delay_xms(50);//等待系统稳定
  343. ds1302_init(); //DS1302初始化
  344. // Uart_init(0); //波特率初始化为2400
  345. Delay_xms(10);
  346. ds1302_write_time(); //写入初始值
  347.                         OLED_Init();                        //初始化OLED  
  348.                 OLED_Clear()          ;
  349.         
  350.                 t=' ';
  351. //                OLED_ShowCHinese(0,2,0);//中
  352. //                                OLED_ShowCHinese(18,2,1);//景
  353. //                OLED_ShowCHinese(36,2,2);//园
  354. //                OLED_ShowCHinese(54,2,3);//电
  355. //                OLED_ShowCHinese(72,2,4);//子
  356. //                OLED_ShowCHinese(90,2,5);//科
  357. //                OLED_ShowCHinese(108,2,6);//技
  358.          led = 1;
  359.         while(1)
  360.         {               
  361.                 ds1302_read_time();  //读取时间
  362.    
  363.   
  364.   
  365.                   
  366. //                OLED_Clear();
  367. //                 if(readtime[13]!=sec_buf)      
  368. //   {
  369. //
  370. //      sec_flag=0;   
  371. //            sec_buf=readtime[13];        
  372.                   OLED_ShowNum(0,0,readtime[0],1,16);          //年千位
  373.             OLED_ShowNum(17,0,readtime[1],1,16);  //年百位
  374.                   OLED_ShowNum(33,0,readtime[2],1,16);        //年十位
  375.                   OLED_ShowNum(49,0,readtime[3],1,16);        //年个位
  376.                  
  377.                   OLED_ShowNum(33,2,readtime[4],1,16);        //月十位
  378.                   OLED_ShowNum(49,2,readtime[5],1,16);        //月个位
  379.                  
  380.                   OLED_ShowNum(33,4,readtime[6],1,16);        //月十位
  381.                   OLED_ShowNum(49,4,readtime[7],1,16);        //月个位
  382.                  
  383.      OLED_ShowNum(0,6,readtime[8],1,16);        //小时十位
  384.                  OLED_ShowNum(17,6,readtime[9],1,16);        //小时个位
  385.                  OLED_ShowString(33,6,":",16);
  386.                  OLED_ShowNum(49,6,readtime[10],1,16);//分钟十位
  387.                  OLED_ShowNum(65,6,readtime[11],1,16);//分钟个位
  388.      OLED_ShowString(81,6,":",16);//冒号                 
  389.                  OLED_ShowNum(97,6,readtime[12],1,16);        //秒钟十位
  390.                  OLED_ShowNum(113,6,readtime[13],1,16);//秒钟个位
  391.            
  392. //   }
  393.                 OLED_ShowCHinese(65,0,0);//年
  394.                 OLED_ShowCHinese(65,2,1);//月
  395. ……………………

  396. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
ds1302&amp;&amp;OLED.rar (98.06 KB, 下载次数: 319)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:362076 发表于 2019-1-30 18:54 | 只看该作者
挺好的,界面UI可以再优化一下
回复

使用道具 举报

板凳
ID:692368 发表于 2020-2-18 17:25 | 只看该作者
很有参考价值
回复

使用道具 举报

地板
ID:430492 发表于 2020-2-29 17:54 | 只看该作者
挺好的,界面UI确实可以再优化一下,这样看起来更舒服些。
回复

使用道具 举报

5#
ID:110278 发表于 2020-3-6 16:13 | 只看该作者
参考参考
回复

使用道具 举报

6#
ID:476465 发表于 2020-3-19 10:48 | 只看该作者
显示了时间,但计时总是会停下来不动
回复

使用道具 举报

7#
ID:315554 发表于 2020-3-19 17:57 | 只看该作者
OLED时钟程序比较少见,看起来不错,学习了,谢谢!
回复

使用道具 举报

8#
ID:723958 发表于 2020-4-21 07:21 来自手机 | 只看该作者
ak333 发表于 2020-3-19 17:57
OLED时钟程序比较少见,看起来不错,学习了,谢谢!

谢谢分享
回复

使用道具 举报

9#
ID:526108 发表于 2020-4-21 09:57 | 只看该作者
钟,按键调闹钟,调时间单片机程序 [修改]
回复

使用道具 举报

10#
ID:805457 发表于 2020-7-19 15:40 | 只看该作者
这个代码能有少一点的吗
回复

使用道具 举报

11#
ID:976703 发表于 2021-11-8 15:52 | 只看该作者
您好,下载里面和您上面描述的不一致,这个时间不可调,只有重量加温度
回复

使用道具 举报

12#
ID:976703 发表于 2021-11-8 15:53 | 只看该作者
你好,这个下载里面的程序和上面描述不一致,有上面描述的程序吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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