⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302.lst

📁 51单片机示例程序
💻 LST
字号:
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 1   


C51 COMPILER V7.20, COMPILATION OF MODULE DS1302
OBJECT MODULE PLACED IN DS1302.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE DS1302.C BROWSE DEBUG OBJECTEXTEND

line level    source

   1          /***************************************************************
   2          
   3                           DS1302实时时钟实验
   4                    网址:http://www.kaifaban.com
   5          
   6                            功能:在数码管上显示从DS1302读取的时间日期星期数据
   7                                 时间格式:时-分-秒
   8                                     日期格式:年月日-星期
   9                                     S1:选择显示时间还是日期
  10                                     S2:循环选择所要编辑的位
  11                                     S3:编辑的位的数值加1
  12                                     S4:编辑的位的数值减1
  13          
  14          
  15          ****************************************************************/
  16          #include <reg52.h>
  17          #include <intrins.h>
  18          #define uchar unsigned char
  19          uchar Code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //共阳数码管编码表
  20          sbit DsySelect=P3^6; //控制数码管的74HC244所在IO口
  21          uchar BitCode=0x80; //数码管位码初值
  22          uchar DS1302[8]={0,0,0,0,0,0,0,0}; //秒,分,时,日,月,星期,年
  23          uchar DateBit[8]={0,0,0,0,0,0,10,0}; //日期各位显示的数值
  24          uchar TimeBit[8]={0,0,10,0,0,10,0,0}; //时间各位显示的数值
  25          sbit DATA=P1^1; //数据传送总线
  26          sbit SCLK=P1^0; //时钟控制总线
  27          sbit RST=P1^2; //复位总线
  28          sbit S1=P3^4; //S1输入口
  29          sbit S2=P3^5; //S2输入口
  30          sbit S3=P3^2; //S3输入口
  31          sbit S4=P3^3; //S4输入口
  32          uchar TimeFlag=0; //显示日期时间标志
  33          uchar EditFlag=0; //闪烁显示标志
  34          uchar S2Num=0; //S2按的次数
  35          uchar num=0;
  36          //向DS1302写一字节数据,address为命令字节
  37          void WriteByte(uchar Command,uchar WriteData){
  38   1      uchar j,k=1;
  39   1      RST=0;
  40   1      SCLK=0;
  41   1      RST=1;
  42   1      for(j=0;j<=7;j++){
  43   2      if(Command&k) DATA=1;
  44   2      else DATA=0;
  45   2      SCLK=1;
  46   2      k<<=1;
  47   2      SCLK=0;
  48   2      }
  49   1      k=1;
  50   1      for(j=0;j<=7;j++){
  51   2      if(WriteData&k) DATA=1;
  52   2      else DATA=0;
  53   2      SCLK=1;
  54   2      k<<=1;
  55   2      SCLK=0;
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 2   

  56   2      }
  57   1      RST=0;
  58   1      }
  59          //读取DS1302一字节数据,address为命令字节
  60          uchar ReadByte(uchar Command){
  61   1      uchar i,k=1;
  62   1      RST=0;
  63   1      SCLK=0;
  64   1      RST=1;
  65   1      for(i=0;i<8;i++){
  66   2      if(Command&k) DATA=1;
  67   2      else DATA=0;
  68   2      SCLK=1;
  69   2      k<<=1;
  70   2      if(i!=7) SCLK=0;
  71   2      }
  72   1      k=0;
  73   1      for(i=0;i<8;i++){
  74   2      k>>=1;
  75   2      SCLK=0;
  76   2      if(DATA) k|=0x80;
  77   2      SCLK=1;
  78   2      }
  79   1      RST=0;
  80   1      return(k);
  81   1      }
  82          //延时程序
  83          void delay(uchar ms){
  84   1      uchar i;
  85   1      while(ms--){
  86   2      for(i=0;i<125;i++);
  87   2      }
  88   1      }
  89          //扫描显示程序
  90          void Display(){
  91   1      uchar i;
  92   1      for(i=0;i<8;i++){
  93   2      if(EditFlag&&S2Num>0){ //判断是否闪烁
  94   3      if(TimeFlag){ //判断日期还是时间闪烁
  95   4      switch(S2Num){ //根据S2按的次数判断日期那一位闪烁
  96   5      case 1:P2=BitCode&0x3F;break;
  97   5      case 2:P2=BitCode&0xCF;break;
  98   5      case 3:P2=BitCode&0xF3;break;
  99   5      case 4:P2=BitCode&0xFE;break;
 100   5      }
 101   4      }else{
 102   4      switch(S2Num){ //根据S2按的次数判断时间那一位闪烁
 103   5      case 1:P2=BitCode&0x3F;break;
 104   5      case 2:P2=BitCode&0xE7;break;
 105   5      case 3:P2=BitCode&0xFC;break;
 106   5      }
 107   4      }
 108   3      }else{
 109   3      P2=BitCode; //输出位码
 110   3      }
 111   2      if(TimeFlag) P0=Code[DateBit[i]]; //判断显示时间还是日期
 112   2      else
 113   2      P0=Code[TimeBit[i]];
 114   2      BitCode=_cror_(BitCode,1); //位码循环右移一位
 115   2      delay(1); //延时1ms
 116   2      P0=0xFF;
 117   2      }
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 3   

 118   1      }
 119          //时间编辑程序
 120          void TimeEdit(uchar flag){
 121   1      uchar Data,NowData;
 122   1      if(flag){ //判断加1还是减1
 123   2      switch(S2Num){ //判断编辑时间的哪一位
 124   3      case 1:{
 125   4      Data=ReadByte(0x85); //读取小时数据
 126   4      NowData=Data+1;
 127   4      if((NowData&0x0F)>9) NowData=NowData+6;
 128   4      if(NowData>=0x24) NowData=0;
 129   4      WriteByte(0x84,NowData); //写入小时数据
 130   4      break;
 131   4      }
 132   3      case 2:{
 133   4      Data=ReadByte(0x83); //读取分数据
 134   4      NowData=Data+1;
 135   4      if((NowData&0x0F)>9) NowData=NowData+6;
 136   4      if(NowData>=0x60) NowData=0;
 137   4      WriteByte(0x82,NowData); //写入分数据
 138   4      break;
 139   4      }
 140   3      case 3:{
 141   4      Data=ReadByte(0x81); //读取秒数据
 142   4      NowData=Data+1;
 143   4      if((NowData&0x0F)>9) NowData=NowData+6;
 144   4      if((NowData&0x7F)>=0x60) NowData=0;
 145   4      WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据
 146   4      break;
 147   4      }
 148   3      }
 149   2      }else{
 150   2      switch(S2Num){ //判断编辑时间的哪一位
 151   3      case 1:{
 152   4      Data=ReadByte(0x85); //读取小时数据
 153   4      if(Data==0){
 154   5      NowData=0x23;
 155   5      }else{
 156   5      NowData=Data-1;
 157   5      if((NowData&0x0F)>9) NowData=NowData-6;
 158   5      }
 159   4      WriteByte(0x84,NowData); //写入小时数据
 160   4      break;
 161   4      }
 162   3      case 2:{
 163   4      Data=ReadByte(0x83); //读取分数据
 164   4      if(Data==0){
 165   5      NowData=0x59;
 166   5      }else{
 167   5      NowData=Data-1;
 168   5      if((NowData&0x0F)>9) NowData=NowData-6;
 169   5      }
 170   4      WriteByte(0x82,NowData); //写入分数据
 171   4      break;
 172   4      }
 173   3      case 3:{
 174   4      Data=ReadByte(0x81); //读取秒数据
 175   4      if(Data==0){
 176   5      NowData=0x59;
 177   5      }else{
 178   5      NowData=Data-1;
 179   5      if((NowData&0x0F)>9) NowData=NowData-6;
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 4   

 180   5      }
 181   4      WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据
 182   4      break;
 183   4      }
 184   3      }
 185   2      }
 186   1      }
 187          //日期编辑程序
 188          void DateEdit(uchar flag){
 189   1      uchar Data,NowData;
 190   1      if(flag){ //判断加1还是减1
 191   2      switch(S2Num){ //判断编辑日期的哪一位
 192   3      case 1:{ //年加1
 193   4      Data=ReadByte(0x8d); //读取年数据
 194   4      NowData=Data+1; //年加1
 195   4      if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
 196   4      if(NowData>=0xA0) NowData=0; //年>=100时,年=0
 197   4      WriteByte(0x8c,NowData); //年写入DS1302
 198   4      break;
 199   4      }
 200   3      case 2:{
 201   4      Data=ReadByte(0x89); //读取月数据
 202   4      NowData=Data+1; //月加1
 203   4      if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
 204   4      if(NowData>=0x13) NowData=1; //月>=13,月=1
 205   4      WriteByte(0x88,NowData); //月写入DS1302
 206   4      break;
 207   4      }
 208   3      case 3:{
 209   4      Data=ReadByte(0x87); //读取日数据
 210   4      NowData=Data+1; //日加1
 211   4      if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
 212   4      if(NowData>=0x32) NowData=1; //日>=32,日=1
 213   4      WriteByte(0x86,NowData); //日写入DS1302
 214   4      break;
 215   4      }
 216   3      case 4:{
 217   4      Data=ReadByte(0x8B); //读取星期数据
 218   4      NowData=Data+1; //星期加1
 219   4      if(NowData>=8) NowData=1; //星期>=8,星期=1
 220   4      WriteByte(0x8A,NowData); //星期写入DS1302
 221   4      break;
 222   4      }
 223   3      }
 224   2      }else{
 225   2      switch(S2Num){
 226   3      case 1:{ //年减1
 227   4      Data=ReadByte(0x8d); //读取年数据
 228   4      if(Data==0){
 229   5      NowData=0x99; //如果年=0,减1则为99
 230   5      }else{
 231   5      NowData=Data-1; //年减1
 232   5      if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
 233   5      }
 234   4      WriteByte(0x8c,NowData); //年写入DS1302
 235   4      break;
 236   4      }
 237   3      case 2:{
 238   4      Data=ReadByte(0x89); //读取月数据
 239   4      NowData=Data-1; //月减1
 240   4      if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
 241   4      if(NowData==0) NowData=0x12; //月=0,月=12
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 5   

 242   4      WriteByte(0x88,NowData); //月写入DS1302
 243   4      break;
 244   4      }
 245   3      case 3:{
 246   4      Data=ReadByte(0x87); //读取日数据
 247   4      NowData=Data-1; //日减1
 248   4      if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
 249   4      if(NowData==0) NowData=0x31; //日=0,日=31
 250   4      WriteByte(0x86,NowData); //日写入DS1302
 251   4      break;
 252   4      }
 253   3      case 4:{
 254   4      Data=ReadByte(0x8B); //读取星期数据
 255   4      NowData=Data-1; //星期减1
 256   4      if(NowData==0) NowData=7; //星期=0,星期=7
 257   4      WriteByte(0x8A,NowData); //星期写入DS1302
 258   4      break;
 259   4      }
 260   3      }
 261   2      }
 262   1      }
 263          //按钮功能函数
 264          void KeyFun(uchar key){
 265   1      ET0=0;
 266   1      switch(key){
 267   2      case 0x0E:{ //S1按下,切换显示日期还是时间
 268   3      TimeFlag=~TimeFlag;
 269   3      S2Num=0;
 270   3      break;
 271   3      }
 272   2      case 0x0D:{ //S2按下,S2Num加1
 273   3      S2Num++;
 274   3      if((TimeFlag>0)&&(S2Num>=5)) S2Num=0; //如果当前编辑的是日期并且S2Num>=5,则编辑完毕,返回正常状态
 275   3      if((TimeFlag==0)&&(S2Num>=4)) S2Num=0; //如果当前编辑的是时间并且S2Num>=4,则编辑完毕,返回正常状态
 276   3      break;
 277   3      }
 278   2      case 0x0B:{ //S3按下,所选位加1
 279   3      if(TimeFlag==0) TimeEdit(1); //判断编辑日期还是时间
 280   3      else DateEdit(1);
 281   3      break;
 282   3      }
 283   2      case 0x07:{ //S4按下,所选位减1
 284   3      if(TimeFlag==0) TimeEdit(0); //判断编辑日期还是时间
 285   3      else DateEdit(0);
 286   3      break;
 287   3      }
 288   2      }
 289   1      ET0=1;
 290   1      }
 291          //键盘扫描程序
 292          uchar KeyScan(){
 293   1      uchar key=0x00;
 294   1      key|=S4;
 295   1      key<<=1;
 296   1      key|=S3;
 297   1      key<<=1;
 298   1      key|=S2;
 299   1      key<<=1;
 300   1      key|=S1;
 301   1      return key;
 302   1      }
 303          //读取DS1302的秒,分,时,日,月,星期,年
C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 6   

 304          void ReadDS1302(){
 305   1      uchar i;
 306   1      for(i=0;i<=6;i++) DS1302[i]=ReadByte(0x80+2*i+1);
 307   1      //计算时间日期的各位要显示的数据
 308   1      TimeBit[7]=DS1302[0]&0x0F;
 309   1      TimeBit[6]=DS1302[0]&0x70;
 310   1      TimeBit[6]>>=4;
 311   1      TimeBit[4]=DS1302[1]&0x0F;
 312   1      TimeBit[3]=DS1302[1]&0x70;
 313   1      TimeBit[3]>>=4;
 314   1      TimeBit[1]=DS1302[2]&0x0F;
 315   1      TimeBit[0]=DS1302[2]&0x30;
 316   1      TimeBit[0]>>=4;
 317   1      DateBit[5]=DS1302[3]&0x0F;
 318   1      DateBit[4]=DS1302[3]&0x30;
 319   1      DateBit[4]>>=4;
 320   1      DateBit[3]=DS1302[4]&0x0F;
 321   1      DateBit[2]=DS1302[4]&0x10;
 322   1      DateBit[2]>>=4;
 323   1      DateBit[7]=DS1302[5]&0x07;
 324   1      DateBit[1]=DS1302[6]&0x0F;
 325   1      DateBit[0]=DS1302[6]&0xF0;
 326   1      DateBit[0]>>=4;
 327   1      }
 328          //T0中断程序,读取和显示时间日期,更新闪烁标志
 329          void T0Int(void) interrupt 1{
 330   1      TL0=0x00;
 331   1      TH0=0xb8;
 332   1      num++;
 333   1      if(num==15){
 334   2      EditFlag=~EditFlag; //更新闪烁标志
 335   2      num=0;
 336   2      }
 337   1      ReadDS1302();
 338   1      Display();
 339   1      }
 340          //主函数
 341          main(){
 342   1      uchar key=0;
 343   1      DsySelect=0; //打开数码管
 344   1      P0=0xFF; //复位P0口
 345   1      P2=0xFF; //复位P2口
 346   1      TMOD=0x01; //T0初始化
 347   1      EA=1;
 348   1      ET0=1;
 349   1      TL0=0x00;
 350   1      TH0=0xb8;
 351   1      TR0=1;
 352   1      WriteByte(0x80,ReadByte(0x81)&0x7F); //启动DS1302
 353   1      while(1){
 354   2      key=KeyScan();
 355   2      if(key!=0x0F){
 356   3      delay(10); //隔10ms再次检测,可以消抖动
 357   3      key=KeyScan();
 358   3      if(key!=0x0F){
 359   4      KeyFun(key);
 360   4      delay(150); //此延时可以调节键盘的灵敏度
 361   4      }
 362   3      }
 363   2      }
 364   1      }

C51 COMPILER V7.20   DS1302                                                                01/17/2007 01:01:13 PAGE 7   


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   1183    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     41    ----
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -