找回密码
 立即注册

QQ登录

只需一步,快速开始

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

CEPARK多功能开发学习板万年历电子钟简单设计

[复制链接]
跳转到指定楼层
楼主
ID:362238 发表于 2018-6-30 12:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
万年历简单设计,基于lcd液晶显示屏和ds18b20,以及时钟电路和八位键盘,实现它的闹钟,年月日和温度功能

单片机源程序如下:
  1. /*******************************************************

  2. /*******************************************************

  3. 程序功能:DS1302时钟走时

  4. 开发环境:Keil3

  5. 硬件环境:CEPARK多功能开发学习板/实验箱(2013版),STC12C5A60S2,11.0592M晶振
  6.                                                                                                                                                                                           
  7. 接线说明:单片机P10~P14口与底板JP51相连,分别为:P10-DIN,P11-SCK,P12-DC,P13-RES,P14-CS.
  8.           单片机P20~P22口与底板JP45相连        ,分别为:P20-SCLK,P21-IO,P22-RST
  9.                   将OLED屏插到相应接口

  10. 跳线说明:无

  11. 实验现象:OLED第一行显示:“ -DS1302 TEST- ”
  12.           第二行显示:年-月-日
  13.                   第三行显示:时:分:秒
  14.                   第四行显示:电子园



  15. *******************************************************/

  16. #include "STC12C5A60S2.h"

  17. //秒、分、时、日、月、星期、年的读地址
  18. #define ADDR_SEC_R 0x81
  19. #define ADDR_MIN_R 0x83
  20. #define ADDR_HOUR_R 0x85
  21. #define ADDR_DAY_R 0x87
  22. #define ADDR_MONTH_R 0x89
  23. #define ADDR_WEEK_R         0x8B
  24. #define ADDR_YEAR_R 0x8D

  25. //秒、分、时、日、月、星期、年的写地址
  26. #define ADDR_SEC_W 0x80
  27. #define ADDR_MIN_W 0x82
  28. #define ADDR_HOUR_W 0x84
  29. #define ADDR_DAY_W 0x86
  30. #define ADDR_MONTH_W 0x88
  31. #define ADDR_WEEK_W         0x8A
  32. #define ADDR_YEAR_W 0x8C

  33. #define uchar unsigned char
  34. #define uint unsigned int


  35. sbit DS1302_CLK = P2^0;
  36. sbit DS1302_IO = P2^1;
  37. sbit DS1302_RST = P2^2;
  38. sbit ACC0=ACC^0;
  39. sbit ACC7=ACC^7;

  40. sbit SEG_DS = P2^3;                //74HC595芯片的数据引脚
  41. sbit SEG_SHCP = P2^4;        //74HC595芯片的控制引脚,上升沿移入数据
  42. sbit SEG_STCP = P2^5;        //74HC595芯片的控制引脚,上升沿更新数据

  43. //各时间的个位和十位
  44. char years,yearg,months,monthg,days,dayg,week,hours,hourg,minutes,minuteg,seconds,secondg;
  45. uchar a[8];// 存放要在数码管显示的时间
  46. uchar resettime[7];//存放要重设的时间
  47. uchar b[2]={0,0};
  48. uchar d=1;
  49. uchar i,key,num,change_key1,change_key2,c;
  50. char pos=8;//闪烁位标志
  51. void DisplayOneCharOnAddr(unsigned char Data,unsigned char Addr);//单位显示函数,那个数码管Addr显示那个数Data
  52. void displayHour();//显示时分秒
  53. void displayYear();//显示年月日
  54. void displayHour1();//修改时显示的时分秒(静止)
  55. void displayYear1();//修改时显示的年月日(静止)
  56. void SEG_Send595OneByte(unsigned char ucData);         //向74HC595写入一个8位的数据
  57. void delayms(uint xms);//延时函数
  58. void matrixkeyscanz();//行列反转扫描矩阵键盘及相关按键功能的实现
  59. void reset();//重设时间函数

  60. unsigned char code Seg_Data[]={         //共阳数码管的编码,并将数据定义在CODE区
  61.                                                             0xc0,/*0*/
  62.                                                 0xF9,/*1*/
  63.                                                 0xA4,/*2*/
  64.                                                 0xB0,/*3*/
  65.                                                 0x99,/*4*/
  66.                                                 0x92,/*5*/
  67.                                                 0x82,/*6*/
  68.                                                 0xF8,/*7*/
  69.                                                 0x80,/*8*/
  70.                                                 0x90,/*9*/                                  
  71.                                                 0x88,/*A*/
  72.                                                 0x83,/*b*/
  73.                                                 0xC6,/*C*/
  74.                                                 0xA1,/*d*/
  75.                                                 0x86,/*E*/
  76.                                                 0x8E,/*F*/
  77.                                                       0xff, //数码管灭
  78.                         0x7f   //小数点亮
  79.                                                         };

  80. unsigned char code Seg_Addr[]={            //数码管位选编码,控制显示8位中的第几位
  81.                                                         0x01,
  82.                                                         0x02,
  83.                                                         0x04,
  84.                                                         0x08,
  85.                                                         0x10,
  86.                                                         0x20,
  87.                                                         0x40,
  88.                                                         0x80,
  89.                                                         0xFF,//ALL ON
  90.                                                         0x00 //OFF
  91.                                                         };


  92. unsigned char code ucInitTime[7]={0x55,0x53,0x11,0x31,0x10,0x01,0x16};         //初始化后设置为:16年10月31日星期1 11点53分55秒



  93. void DS1302_WriteOneByte(unsigned char d); //向DS1302中写入一个数据
  94. unsigned char DS1302_ReadOneByte(void);           //从DS1302读出一个数据
  95. void DS1302_WriteOneByteAtAddr(unsigned char ucAddr, unsigned char ucDa);        //在指定地址写入一个数据
  96. unsigned char DS1302_ReadOneByteAtAddr(unsigned char ucAddr);                //从指定一个位置读取一个数据
  97. void DS1302_SetInit(unsigned char *pClk);                 //初始化时间


  98. /******************************************************************************
  99. 函数名称:main
  100. 函数功能:程序主函数
  101. 入口参数:无
  102. 返回值:无
  103. 备注:无
  104. *******************************************************************************/
  105. void main(void)
  106. {
  107.   DS1302_WriteOneByteAtAddr(0x8e,0x00);           /* 控制命令,WP=0,写操作*/
  108.         DS1302_SetInit(ucInitTime);
  109.         P1=0xff;
  110.         TMOD=0x01;
  111.         TH0=(65536-45872)/256;
  112.         TL0=(65536-45872)%256;
  113.         EA=1;
  114.         ET0=1;
  115.         while(1)                 //程序循环
  116.         {
  117.             matrixkeyscanz();
  118.             switch(change_key2)
  119.                   {
  120.                      case 0://修改键没有被按下
  121.                            switch(change_key1)
  122.                            {  //change_key1=0表示显示时分秒,change_key1=1表示显示年月日
  123.                             case 0:displayHour();break;
  124.                                   case 1:displayYear();break;
  125.                            }
  126.                            break;
  127.                                  
  128.                          case 1://修改键被按下
  129.                            switch(change_key1)
  130.                            {
  131.                             case 0:displayHour1();break;
  132.                                   case 1:displayYear1();break;
  133.                            }
  134.                            break;
  135.                   }       
  136.         }
  137. }

  138. //显示时分秒的函数,从左到右依次为星期、时、分、秒
  139. void displayHour()
  140. {
  141.     hours=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)/16;
  142.     hourg=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)%16;
  143.     minutes=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)/16;
  144.     minuteg=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)%16;
  145.     seconds=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)/16;
  146.     secondg=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)%16;
  147.     week=DS1302_ReadOneByteAtAddr(ADDR_WEEK_R)%16;       
  148.           a[0]=week;
  149.           a[1]=16;//空一格不显示
  150.           a[2]=hours;
  151.           a[3]=hourg;
  152.           a[4]=minutes;
  153.           a[5]=minuteg;
  154.     a[6]=seconds;
  155.           a[7]=secondg;       
  156.           for(i=0;i<8;i++)
  157.           {
  158.                   if(i==3||i==5)
  159.           DisplayOneCharOnAddr(17,i);//显示小数点
  160.             DisplayOneCharOnAddr(a[i],i);
  161.           }          
  162. }

  163. //显示按下修改键时的时分秒
  164. void displayHour1()
  165. {
  166.           a[0]=week;
  167.           a[1]=16;
  168.           a[2]=hours;
  169.           a[3]=hourg;
  170.           a[4]=minutes;
  171.           a[5]=minuteg;
  172.       a[6]=seconds;
  173.           a[7]=secondg;       
  174.          for(i=0;i<pos;i++)
  175.          {
  176.                  if(i==3||i==5)
  177.          DisplayOneCharOnAddr(17,i);       
  178.            DisplayOneCharOnAddr(a[i],i);
  179.                  //num的值由定时器1控制,不断闪烁要修改的两位数字
  180.                  if(num>0)
  181.                  {
  182.                          if(num<=10)
  183.                          {
  184.          DisplayOneCharOnAddr(a[pos],pos);
  185.                DisplayOneCharOnAddr(a[pos+1],pos+1);
  186.                          }
  187.                          else
  188.                          {
  189.          DisplayOneCharOnAddr(16,pos);
  190.                DisplayOneCharOnAddr(16,pos+1);
  191.        }
  192.      }
  193.          }
  194.          
  195.          for(i=pos+2;i<8;i++)
  196.          {
  197.                  if(i==3||i==5)
  198.           DisplayOneCharOnAddr(17,i);       
  199.            DisplayOneCharOnAddr(a[i],i);
  200.                  if(num>0)
  201.                  {
  202.                          if(num<=10)
  203.                          {
  204.          DisplayOneCharOnAddr(a[pos],pos);
  205.                DisplayOneCharOnAddr(a[pos+1],pos+1);
  206.                          }
  207.                          else
  208.                          {
  209.          DisplayOneCharOnAddr(16,pos);
  210.                DisplayOneCharOnAddr(16,pos+1);
  211.        }
  212.      }
  213.          }                       
  214. }

  215. //显示年月日的函数,从左到右依次为年、月、日
  216. void displayYear()
  217. {
  218.           years=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)/16;
  219.           yearg=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)%16;
  220.     months=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)/16;
  221.           monthg=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)%16;
  222.           days=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)/16;
  223.           dayg=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)%16;
  224.           a[0]=2;
  225.           a[1]=0;
  226.           a[2]=years;
  227.           a[3]=yearg;
  228.           a[4]=months;
  229.           a[5]=monthg;
  230.           a[6]=days;
  231.           a[7]=dayg;
  232.           for(i=0;i<8;i++)
  233.          {
  234.                  if(i==3||i==5)
  235.           DisplayOneCharOnAddr(17,i);
  236.            DisplayOneCharOnAddr(a[i],i);
  237.          }
  238. }

  239. //显示按下修改键时的年月日
  240. void displayYear1()
  241. {
  242.           a[0]=2;
  243.           a[1]=0;
  244.           a[2]=years;
  245.           a[3]=yearg;
  246.           a[4]=months;
  247.           a[5]=monthg;
  248.           a[6]=days;
  249.           a[7]=dayg;
  250.           for(i=0;i<pos;i++)
  251.          {
  252.                  if(i==3||i==5)
  253.          DisplayOneCharOnAddr(17,i);
  254.            DisplayOneCharOnAddr(a[i],i);
  255.                  if(num>0)
  256.                  {
  257.                          if(num<=10)
  258.                          {
  259.          DisplayOneCharOnAddr(a[pos],pos);
  260.                DisplayOneCharOnAddr(a[pos+1],pos+1);
  261.                          }
  262.                          else
  263.                          {
  264.          DisplayOneCharOnAddr(16,pos);
  265.                DisplayOneCharOnAddr(16,pos+1);
  266.        }
  267.      }
  268.          }       
  269.          
  270.           for(i=pos;i<8;i++)
  271.          {
  272.                  if(i==3||i==5)
  273.          DisplayOneCharOnAddr(17,i);
  274.            DisplayOneCharOnAddr(a[i],i);
  275.                  if(num>0)
  276.                  {
  277.                          if(num<=10)
  278.                          {
  279.          DisplayOneCharOnAddr(a[pos],pos);
  280.                DisplayOneCharOnAddr(a[pos+1],pos+1);
  281.                          }
  282.                          else
  283.                          {
  284.          DisplayOneCharOnAddr(16,pos);
  285.                DisplayOneCharOnAddr(16,pos+1);
  286.        }
  287.      }
  288.          }               
  289. }

  290. /*******************************************************
  291. 行列反转,判断是哪个按键按下,并在相应的键中实现相关的功能
  292. *******************************************************/
  293. void matrixkeyscanz()
  294. {
  295.   uchar temp,col,row;
  296.   P0=0xff;
  297.   P0=0xf0;
  298.         temp=P0;
  299.   if(temp!=0xf0)
  300.   {
  301.    delayms(50);
  302.          temp=P0;
  303.          if(temp!=0xf0)
  304.          {
  305.           switch(temp)
  306.           {   //判断列
  307.            case 0xe0:col=0;break;
  308.                  case 0xd0:col=1;break;
  309.                  case 0xb0:col=2;break;
  310.                  case 0x70:col=3;break;
  311.           }
  312.     P0=0xff;
  313.           P0=0x0f;
  314.           temp=P0;
  315.     if(temp!=0x0f)
  316.           {
  317.            switch(temp)
  318.                  {   //判断行
  319.             case 0x0e:row=0;break;
  320.                   case 0x0d:row=1;break;
  321.                   case 0x0b:row=2;break;
  322.                   case 0x07:row=3;break;
  323.                  }
  324.           }
  325.           
  326.   key=(row<<2)+col+1; //按键key的值为1到16
  327.         d=1;
  328.         switch(key)
  329.   {
  330.          case 1://按键1:切换时分秒和年月日
  331.          {
  332.           change_key1=change_key1+1;        //切换按钮
  333.                 if(change_key1==2)
  334.                                 change_key1=0;
  335.                 if(change_key2==1);
  336.                                  change_key2=0;
  337.                 pos=8;
  338.          }
  339.          break;
  340.          
  341.          case 2://按键2:修改或修改确认按键
  342.    {
  343.                 change_key2++;//修改/确认变量
  344.                 if(change_key2==2)
  345.                                 change_key2=0;
  346.                 c=0;
  347.                 switch(change_key2)
  348.                 {
  349.                  case 0://确认
  350.      {
  351.       pos=8;
  352.                   TR0=0;
  353.                         reset();
  354.                  }
  355.                 break;
  356.                 case 1://修改
  357.           {
  358.                  //读当前的时间
  359.                  years=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)/16;
  360.            yearg=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)%16;
  361.      months=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)/16;
  362.            monthg=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)%16;
  363.            days=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)/16;
  364.            dayg=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)%16;
  365.                  hours=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)/16;
  366.      hourg=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)%16;
  367.      minutes=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)/16;
  368.      minuteg=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)%16;
  369.      seconds=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)/16;
  370.      secondg=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)%16;
  371.      week=DS1302_ReadOneByteAtAddr(ADDR_WEEK_R)%16;       
  372.                  pos=6;//闪烁位标志为6、7位
  373.                  TR0=1;//启动定时器1
  374.                 }       
  375.                 break;
  376.                 }                               
  377.    }
  378.          break;
  379.          
  380.          case 3://按键3:左移按键(改变闪烁位的值)
  381.          {
  382.                 c=0;
  383.     pos=pos-2;
  384.                 if((pos<2)&&(change_key1==1)) //若当前显示年月日
  385.                                 pos=6;
  386.                 else if((pos<0)&&(change_key1==0)) //若当前显示时分秒
  387.                                 pos=6;                               
  388.     }
  389.           break;
  390.                
  391.                 case 4://按键4:右移按键(改变闪烁位的值)
  392.           {
  393.                  c=0;
  394.      pos=pos+2;
  395.                  if((pos>6)&&(change_key1==1))
  396.                                         pos=2;
  397.                  else if((pos>6)&&(change_key1==0))
  398.                                         pos=0;
  399.      }
  400.            break;
  401.                  
  402.                  case 5://按键5:加
  403.                  {
  404.                         //若按下了修改键且当前显示时分秒
  405.       if((change_key1==0)&&(change_key2==1)&&(d==1))
  406.                         {
  407.                          d=2;
  408.                          //根据当前闪烁的位置改变对应的时间
  409.                          switch(pos)
  410.                          {
  411.                                 case 6://秒位置
  412.                                 {
  413.                                  secondg++;
  414.                                  if(secondg==10)
  415.                                  {
  416.                                         secondg=0;
  417.                                         seconds++;
  418.                                         if(seconds==6)
  419.                                            seconds=0;
  420.                                  }
  421.                                 }
  422.                                 break;
  423.                                 case 4://分位置
  424.                           {
  425.                                  minuteg++;
  426.                                  if(minuteg==10)
  427.                                  {
  428.                                         minuteg=0;
  429.                                         minutes++;
  430.                                         if(minutes==6)
  431.                                            minutes=0;
  432.                                  }
  433.                                 }
  434.                                 break;
  435.                                 case 2://时位置
  436.                                 {
  437.                                  hourg++;
  438.                                  if(hourg==10)
  439.                                  {
  440.                                         hourg=0;
  441.                                         hours++;
  442.                                         if(hours==3)
  443.                                                  hours=0;
  444.                                  }
  445.                                 }
  446.                                 break;
  447.                                 case 0://星期位置
  448.                                 {
  449.                                  week++;
  450.                                  if(week==8)
  451.                                                 week=0;
  452.                                 }
  453.                                 break;
  454.        }
  455.             }
  456.                 //若按下了修改键且当前显示年月日       
  457.                 if((change_key1==1)&&(change_key2==1)&&(d==1))
  458.                 {
  459.                  d=2;
  460.                  switch(pos)
  461.                  {
  462.                   case 6://日位置
  463.                         {
  464.                          dayg++;
  465.                          if(dayg==10)
  466.                          {
  467.                                 dayg=0;
  468.                                 days++;
  469.                                 if(days==4)
  470.                                          days=0;
  471.                          }
  472.                         }
  473.                         break;
  474.                         case 4://月位置
  475.                         {
  476.                          monthg++;
  477.                          if(monthg==10)
  478.                          {
  479.                                 monthg=0;
  480.                                 months++;
  481.                                 if(months==2)
  482.                                          months=0;
  483.                          }
  484.                         }
  485.                         break;
  486.                         case 2:
  487.                         {
  488.                          yearg++;
  489.                          if(yearg==10)
  490.                          {
  491.                                 yearg=0;
  492.                                 years++;
  493.                                 if(years==10)
  494.                                                 years=0;
  495.                          }
  496.                         }
  497.                         break;
  498.      }
  499.     }
  500.          }
  501.          break;
  502.          
  503.          case 6://按键6:减
  504.          {
  505.                 //若按下了修改键且当前显示时分秒
  506.     if((change_key1==0)&&(change_key2==1)&&(d==1))
  507.                 {
  508.                  d=2;
  509.                  switch(pos)
  510.                  {
  511.       case 6://秒位置
  512.                         {
  513.                          secondg--;
  514.                          if(secondg==-1)
  515.                          {
  516.                                 secondg=9;
  517.                                 seconds--;
  518.                                 if(seconds==-1)
  519.                                          seconds=5;
  520.                          }
  521.                         }
  522.                         break;
  523.                         case 4://分位置
  524.                         {
  525.                          minuteg--;
  526.                          if(minuteg==-1)
  527.                          {
  528.                                 minuteg=9;
  529.                                 minutes--;
  530.                                 if(minutes==-1)
  531.                                                 minutes=5;
  532.                          }
  533.                         }
  534.                         break;
  535.                         case 2://时位置
  536.                         {
  537.                          hourg--;
  538.                          if(hourg==-1)
  539.                          {
  540.                                 hourg=9;
  541.                                 hours--;
  542.                                 if(hours==-1)
  543.                                 hours=2;
  544.                          }
  545.                         }
  546.                         break;
  547.                         case 0:
  548.                         {
  549.                          week--;
  550.                          if(week==-1)
  551.                          week=7;
  552.                         }
  553.                         break;
  554.                  }
  555.     }
  556.                 //若按下了修改键且当前显示年月日
  557.                 if((change_key1==1)&&(change_key2==1)&&(d==1))
  558.                 {
  559.                  d=2;
  560.                  switch(pos)
  561.      {
  562.                         case 6://日的位置
  563.                         {
  564.                          dayg--;
  565.                          if(dayg==-1)
  566.                          {
  567.                                 dayg=9;
  568.                                 days--;
  569.                                 if(days==-1)
  570.                                 days=3;
  571.                          }
  572.                         }
  573.                         break;
  574.                         case 4://月的位置
  575.                         {
  576.                          monthg--;
  577.                          if(monthg==-1)
  578.                          {
  579.                                 monthg=9;
  580.                                 months--;
  581.                                 if(months==-1)
  582.                                 months=1;
  583.                          }
  584.                         }
  585.                         break;
  586.                         case 2://年的位置
  587.                         {
  588.                          yearg--;
  589.                          if(yearg==-1)
  590.                          {
  591.                                 yearg=9;
  592.                                 years--;
  593.                                 if(years==-1)
  594.                                 years=9;
  595.                          }
  596.                         }
  597.                         break;
  598.      }
  599.                 }
  600.    }
  601.          break;
  602.          
  603.          case 7://按键7:数字键0
  604.   {
  605.     c++;//输入的数是个位还是十位,c%2==1为个位,c%2==0为十位
  606.                 if(c%2==1)
  607.        b[0]=0;
  608.                 else if(c%2==0)
  609.                 {
  610.                         b[1]=b[0];
  611.                         b[0]=0;
  612.                 }
  613.    }
  614.          break;
  615.          
  616.          case 8://按键8:数字键1
  617.          {
  618.     c++;
  619.                 if(c%2==1)
  620.                          b[0]=1;
  621.                 else if(c%2==0)
  622.                 {
  623.                         b[1]=b[0];
  624.                         b[0]=1;
  625.                 }
  626.    }
  627.          break;
  628.          
  629.          case 9://按键9:数字键2
  630.          {
  631.     c++;
  632.                 if(c%2==1)
  633.                          b[0]=2;
  634.                 else if(c%2==0)
  635.                 {
  636.                         b[1]=b[0];
  637.                         b[0]=2;
  638.                 }
  639.    }
  640.          break;
  641.          
  642.          case 10://按键10:数字键3
  643.          {
  644.     c++;
  645.                 if(c%2==1)
  646.                          b[0]=3;
  647.                 else if(c%2==0)
  648.                 {
  649.                   b[1]=b[0];
  650.                         b[0]=3;
  651.                 }
  652.    }
  653.          break;
  654.          
  655.          case 11://按键11:数字键4
  656.          {
  657.     c++;
  658.                 if(c%2==1)
  659.                                 b[0]=4;
  660.                 else if(c%2==0)
  661.                 {
  662.                         b[1]=b[0];
  663.                         b[0]=4;
  664.                 }
  665.    }
  666.          break;
  667.          
  668.          case 12://按键12:数字键5
  669.          {
  670.     c++;
  671.                 if(c%2==1)
  672.                                 b[0]=5;
  673.                 else if(c%2==0)
  674.                 {
  675.                         b[1]=b[0];
  676.                         b[0]=5;
  677.                 }
  678.    }
  679.          break;
  680.          
  681.          case 13://按键13:数字键6
  682.          {
  683.     c++;
  684.                 if(c%2==1)
  685.                                 b[0]=6;
  686.                 else if(c%2==0)
  687.                 {
  688.                         b[1]=b[0];
  689.                         b[0]=6;
  690.                 }
  691.    }
  692.          break;
  693.          
  694.          case 14://按键14:数字键7
  695.          {
  696.     c++;
  697.                 if(c%2==1)
  698.                                 b[0]=7;
  699.                 else if(c%2==0)
  700.                 {
  701.                         b[1]=b[0];
  702.                         b[0]=7;
  703.                 }
  704.    }
  705.          break;
  706.          
  707.          case 15://按键15:数字键8
  708.          {
  709.     c++;
  710.                 if(c%2==1)
  711.                                 b[0]=8;
  712.                 else if(c%2==0)
  713.                 {
  714.                         b[1]=b[0];
  715.                         b[0]=8;
  716.                 }
  717.    }
  718.          break;
  719.          
  720.          case 16://按键16:数字键9
  721.          {
  722.     c++;
  723.                 if(c%2==1)
  724.                                 b[0]=9;
  725.                 else if(c%2==0)
  726.                 {
  727.                         b[1]=b[0];
  728.                         b[0]=9;
  729.                 }
  730.    }
  731.          break;
  732.         }
  733.        
  734.         //将数组b中的值赋给各时间数
  735.         if((change_key1==0)&&(change_key2==1)&&(key>6))
  736.         {
  737.    switch(pos)
  738.          {
  739.     case 6:
  740.                 {
  741.       secondg=b[0];
  742.                         seconds=b[1];               
  743.     }
  744.                 break;
  745.                 case 4:
  746.                 {
  747.       minuteg=b[0];
  748.                         minutes=b[1];
  749.     }
  750.                 break;
  751.                 case 2:
  752.                 {
  753.       hourg=b[0];
  754.                         hours=b[1];
  755.     }
  756.                 break;
  757.                 case 0:
  758.                 {
  759.                  if(c%2==1)
  760.          week=b[0];
  761.                  else if(c%2==1)
  762.                      week=b[1];
  763.     }
  764.                 break;       
  765.    }
  766.   }
  767.                
  768.         if((change_key1==1)&&(change_key2==1)&&(key>6))
  769.   {
  770.    switch(pos)
  771.          {
  772.     case 6:
  773.                 {
  774.       dayg=b[0];
  775.                         days=b[1];
  776.     }
  777.                 break;
  778.                 case 4:
  779.                 {
  780.       monthg=b[0];
  781.                         months=b[1];
  782.     }
  783.                 break;
  784.                 case 2:
  785.                 {
  786.       yearg=b[0];
  787.                         years=b[1];
  788.     }
  789.                 break;
  790.    }
  791.   }
  792.         P0=0x0f;
  793.         temp=P0;
  794.         temp=temp&0x0f;
  795.         while(temp!=0x0f)
  796.           {
  797.            temp=P0;
  798.            temp=temp&0x0f;
  799.           }
  800.    }
  801.   }
  802. }

  803. //重设时间函数,将修改后的时间再次设置
  804. void reset()
  805. {
  806.   uchar year,month,day,week1,hour,minute,second;
  807.         //将时间数转换为16进制
  808.         year=years*16+yearg;
  809.         month=months*16+monthg;
  810.         day=days*16+dayg;
  811.         week1=week;
  812.         hour=hours*16+hourg;
  813.         minute=minutes*16+minuteg;
  814.         second=seconds*16+secondg;
  815.         resettime[0]=second;
  816.   resettime[1]=minute;
  817.   resettime[2]=hour;
  818.   resettime[3]=day;
  819.   resettime[4]=month;
  820.   resettime[5]=week1;
  821.   resettime[6]=year;
  822.   DS1302_SetInit(resettime);
  823. }

  824. //延时函数
  825. void delayms(uint xms)
  826. {
  827.    uint i,j;
  828.    for(i=xms;i>0;i--)
  829.         for(j=110;j>0;j--);
  830. }


  831. void T0_time() interrupt 1
  832. {
  833.    TH0=(65536-45872)/256;
  834.    TL0=(65536-45872)%256;
  835.    num++;
  836.          if(num==20)
  837.                  num=0;
  838. }  
  839.   
  840. /******************************************************************************
  841. 函数名称:DS1302_WriteOneByte
  842. 函数功能:向DS1302写入一个字符
  843. 入口参数:ucData-数据
  844. 返回值:无
  845. 备注:无
  846. *******************************************************************************/
  847. void DS1302_WriteOneByte(unsigned char ucData)
  848. {
  849.     unsigned char i;
  850.     ACC = ucData;
  851.     DS1302_RST = 1;
  852.     for(i=8; i>0; i--)
  853.     {
  854.         DS1302_IO = ACC0;         
  855.         DS1302_CLK = 0;
  856.         DS1302_CLK = 1;                                //先写入最低位,上升沿写入
  857.         ACC = ACC >> 1;
  858.     }
  859. }

  860. /******************************************************************************
  861. 函数名称:DS1302_ReadOneByte
  862. 函数功能:从DS1302读取一个数据
  863. 入口参数:无
  864. 返回值:读取的数据
  865. 备注:无
  866. *******************************************************************************/
  867. unsigned char DS1302_ReadOneByte(void)
  868. {
  869.     unsigned char i;
  870.     DS1302_RST = 1;
  871.     for(i=8; i>0; i--)
  872.     {
  873.         ACC = ACC >>1;         //相当于汇编中的 RRC
  874.         DS1302_IO = 1;
  875.         DS1302_CLK = 1;
  876.         DS1302_CLK = 0;                           //下降沿读取,先读最低位
  877.         ACC7 = DS1302_IO;
  878.     }
  879.     return(ACC);
  880. }

  881. /******************************************************************************
  882. 函数名称:DS1302_WriteOneByteAtAddr
  883. 函数功能:在DS1302的指定位置写入一个数据
  884. 入口参数:ucAddr-地址          ;  ucData-数据
  885. 返回值:无
  886. 备注:无
  887. *******************************************************************************/
  888. void DS1302_WriteOneByteAtAddr(unsigned char ucAddr, unsigned char ucData)
  889. {
  890.     DS1302_RST = 0;
  891.     DS1302_CLK = 0;
  892.     DS1302_RST = 1;
  893.     DS1302_WriteOneByte(ucAddr);      
  894.     DS1302_WriteOneByte(ucData);      
  895.     DS1302_CLK = 1;
  896.     DS1302_RST = 0;
  897.     DS1302_IO = 0;
  898. }

  899. /******************************************************************************
  900. 函数名称:DS1302_ReadOneByteAtAddr
  901. 函数功能:在指定的位置读取一个数据
  902. 入口参数:ucAddr-地址
  903. 返回值:读取的数据
  904. 备注:无
  905. *******************************************************************************/
  906. unsigned char DS1302_ReadOneByteAtAddr(unsigned char ucAddr)
  907. {
  908.     unsigned char ucBackValue;
  909.     DS1302_RST = 0;
  910.     DS1302_CLK = 0;
  911.     DS1302_RST = 1;
  912.     DS1302_WriteOneByte(ucAddr);            
  913.     ucBackValue = DS1302_ReadOneByte();         
  914.     DS1302_CLK = 1;
  915.     DS1302_RST = 0;
  916.     return(ucBackValue);
  917. }

  918. /******************************************************************************
  919. 函数名称:DS1302_SetInit
  920. 函数功能:设置初始化
  921. 入口参数:pClk-初始化数组的指针
  922. 返回值:无
  923. 备注:无
  924. *******************************************************************************/
  925. void DS1302_SetInit(unsigned char *pClk)
  926. {
  927.     unsigned char i;
  928.     unsigned char ucAddr = 0x80;
  929.     DS1302_WriteOneByteAtAddr(0x8e,0x00);           /* 控制命令,WP=0,写操作*/
  930.     for(i =7; i>0; i--)
  931.     {
  932.         DS1302_WriteOneByteAtAddr(ucAddr,*pClk);  /* 秒 分 时 日 月 星期 年 */
  933.         pClk++;
  934.         ucAddr +=2;
  935.     }
  936.     DS1302_WriteOneByteAtAddr(0x8e,0x80);           /* 控制命令,WP=1,写保护*/
  937. }

  938. //向HC595发送一个字节
  939. void SEG_Send595OneByte(unsigned char ucData)
  940. {
  941.         unsigned char i;
  942.        
  943.         for(i = 0;i < 8;i++)         //8位数据依次写入,先写最低位
  944.         {
  945.                 SEG_DS = (ucData & 0x80);        //先读入高位   x&0x80;
  946.                 SEG_SHCP = 0;
  947.                 SEG_SHCP = 1;
  948.                 SEG_SHCP = 0;           //SHCP引脚的上升沿移入数据
  949.                 ucData <<=1;           //数据左移
  950.         }

  951. }



  952. /*******************************************************
  953. 函数功能:在指定位置显示一个数据
  954. 参数说明:Data是要显示的数据,Addr是在第几位显示。

  955. Addr取值范围是0~9。
  956. Addr=0~7时,选择的是显示在第几位数码管上;
  957. Addr=8  时,同时选中8位数码管,即打开所有数码管
  958. Addr=9  时,关闭8位数码管

  959. 8位数码管,左数依次为第0位,第1位...第7位。

  960. *******************************************************/


  961. void DisplayOneCharOnAddr(unsigned char Data,unsigned char Addr)
  962. {
  963.                 SEG_Send595OneByte(Seg_Addr[Addr]);  //显示在哪一个数码管上
  964.                 SEG_Send595OneByte( Seg_Data[Data]);  //显示的数据
  965.                 SEG_STCP = 0;
  966.                 SEG_STCP = 1;                 //STCP引脚的上升沿更新数据
  967.                 SEG_STCP = 0;

  968.        
  969. }

  970.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
复制代码

所有资料51hei提供下载:
万年历.rar (71.02 KB, 下载次数: 9)


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

使用道具 举报

沙发
ID:362319 发表于 2018-7-1 15:16 | 只看该作者
好用,真心的不错
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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