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

📄 ds1302_8bit.lst

📁 多功能时钟
💻 LST
字号:
C51 COMPILER V7.50   DS1302_8BIT                                                           09/29/2008 13:41:16 PAGE 1   


C51 COMPILER V7.50, COMPILATION OF MODULE DS1302_8BIT
OBJECT MODULE PLACED IN ds1302_8bit.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE ds1302_8bit.c BROWSE DEBUG OBJECTEXTEND

line level    source

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

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

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

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

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

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


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 + -