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

📄 51

📁 51单片机大量源码
💻
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V8.18   EX98                                                                  01/04/2010 16:37:15 PAGE 1   


C51 COMPILER V8.18, COMPILATION OF MODULE EX98
OBJECT MODULE PLACED IN ex98.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE ex98.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          //实例98:基于DS1302的日历时钟
   2          #include<reg51.h>     //包含单片机寄存器的头文件
   3          #include<intrins.h>   //包含_nop_()函数定义的头文件
   4          /***********************************************************************
   5          以下是DS1302芯片的操作程序
   6          ************************************************************************/
   7          unsigned char code digit[10]={"0123456789"};   //定义字符数组显示数字
   8          sbit DATA=P1^1;   //位定义1302芯片的接口,数据输出端定义在P1.1引脚
   9          sbit RST=P1^2;    //位定义1302芯片的接口,复位端口定义在P1.1引脚
  10          sbit SCLK=P1^0;   //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚
  11          /*****************************************************
  12          函数功能:延时若干微秒
  13          入口参数:n
  14          ***************************************************/ 
  15          void delaynus(unsigned char n)
  16          {
  17   1       unsigned char i;
  18   1       for(i=0;i<n;i++)
  19   1            ;
  20   1      }
  21          /*****************************************************
  22          函数功能:向1302写一个字节数据
  23          入口参数:x
  24          ***************************************************/ 
  25          void Write1302(unsigned char dat)
  26          {
  27   1        unsigned char i; 
  28   1        SCLK=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备
  29   1        delaynus(2);       //稍微等待,使硬件做好准备
  30   1        for(i=0;i<8;i++)      //连续写8个二进制位数据
  31   1          {
  32   2                  DATA=dat&0x01;    //取出dat的第0位数据写入1302
  33   2                      delaynus(2);       //稍微等待,使硬件做好准备
  34   2                       SCLK=1;           //上升沿写入数据
  35   2                       delaynus(2);      //稍微等待,使硬件做好准备
  36   2                       SCLK=0;           //重新拉低SCLK,形成脉冲
  37   2                       dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位
  38   2                }
  39   1              
  40   1       }
  41          /*****************************************************
  42          函数功能:根据命令字,向1302写一个字节数据
  43          入口参数:Cmd,储存命令字;dat,储存待写的数据
  44          ***************************************************/ 
  45          void WriteSet1302(unsigned char Cmd,unsigned char dat)
  46           {
  47   1         RST=0;           //禁止数据传递
  48   1         SCLK=0;          //确保写数居前SCLK被拉低
  49   1              RST=1;           //启动数据传输
  50   1              delaynus(2);     //稍微等待,使硬件做好准备
  51   1              Write1302(Cmd);  //写入命令字
  52   1              Write1302(dat);  //写数据
  53   1              SCLK=1;          //将时钟电平置于已知状态
  54   1              RST=0;           //禁止数据传递
  55   1       }
C51 COMPILER V8.18   EX98                                                                  01/04/2010 16:37:15 PAGE 2   

  56          /*****************************************************
  57          函数功能:从1302读一个字节数据
  58          入口参数:x
  59          ***************************************************/ 
  60           unsigned char Read1302(void)
  61           {
  62   1         unsigned char i,dat;
  63   1              delaynus(2);       //稍微等待,使硬件做好准备
  64   1              for(i=0;i<8;i++)   //连续读8个二进制位数据
  65   1               {
  66   2                 dat>>=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位
  67   2                      if(DATA==1)    //如果读出的数据是1
  68   2                       dat|=0x80;    //将1取出,写在dat的最高位
  69   2                       SCLK=1;       //将SCLK置于高电平,为下降沿读出
  70   2                       delaynus(2);  //稍微等待
  71   2                       SCLK=0;       //拉低SCLK,形成脉冲下降沿
  72   2                       delaynus(2);  //稍微等待
  73   2                }      
  74   1        return dat;        //将读出的数据返回
  75   1      }  
  76          /*****************************************************
  77          函数功能:根据命令字,从1302读取一个字节数据
  78          入口参数:Cmd
  79          ***************************************************/ 
  80          unsigned char  ReadSet1302(unsigned char Cmd)
  81           {
  82   1        unsigned char dat;
  83   1        RST=0;                 //拉低RST
  84   1        SCLK=0;                //确保写数居前SCLK被拉低
  85   1        RST=1;                 //启动数据传输
  86   1        Write1302(Cmd);       //写入命令字
  87   1        dat=Read1302();       //读出数据
  88   1        SCLK=1;              //将时钟电平置于已知状态
  89   1        RST=0;               //禁止数据传递
  90   1        return dat;          //将读出的数据返回
  91   1      }
  92          /*****************************************************
  93          函数功能: 1302进行初始化设置
  94          ***************************************************/ 
  95          void Init_DS1302(void)
  96          {       
  97   1         WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 
  98   1         WriteSet1302(0x80,((0/10)<<4|(0%10)));   //根据写秒寄存器命令字,写入秒的初始值
  99   1              WriteSet1302(0x82,((0/10)<<4|(0%10)));   //根据写分寄存器命令字,写入分的初始值
 100   1              WriteSet1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值
 101   1              WriteSet1302(0x86,((16/10)<<4|(16%10))); //根据写日寄存器命令字,写入日的初始值
 102   1              WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值
 103   1              WriteSet1302(0x8c,((8/10)<<4|(8%10)));   //根据写小时寄存器命令字,写入小时的初始值
 104   1      }
 105          /*******************************************************************************
 106          以下是对液晶模块的操作程序
 107          *******************************************************************************/
 108          sbit RS=P2^0;           //寄存器选择位,将RS位定义为P2.0引脚
 109          sbit RW=P2^1;           //读写选择位,将RW位定义为P2.1引脚
 110          sbit E=P2^2;            //使能信号位,将E位定义为P2.2引脚
 111          sbit BF=P0^7;           //忙碌标志位,,将BF位定义为P0.7引脚
 112          /*****************************************************
 113          函数功能:延时1ms
 114          (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
 115          ***************************************************/
 116          void delay1ms()
 117          {
C51 COMPILER V8.18   EX98                                                                  01/04/2010 16:37:15 PAGE 3   

 118   1         unsigned char i,j;   
 119   1               for(i=0;i<10;i++)
 120   1                for(j=0;j<33;j++)
 121   1                 ;             
 122   1       }
 123          /*****************************************************
 124          函数功能:延时若干毫秒
 125          入口参数:n
 126          ***************************************************/
 127           void delaynms(unsigned char n)
 128           {
 129   1         unsigned char i;
 130   1              for(i=0;i<n;i++)
 131   1                 delay1ms();
 132   1       }
 133          /*****************************************************
 134          函数功能:判断液晶模块的忙碌状态
 135          返回值:result。result=1,忙碌;result=0,不忙
 136          ***************************************************/
 137          bit BusyTest(void)
 138            {
 139   1          bit result;
 140   1              RS=0;       //根据规定,RS为低电平,RW为高电平时,可以读状态
 141   1          RW=1;
 142   1          E=1;        //E=1,才允许读写
 143   1          _nop_();   //空操作
 144   1          _nop_();
 145   1          _nop_(); 
 146   1          _nop_();   //空操作四个机器周期,给硬件反应时间     
 147   1          result=BF;  //将忙碌标志电平赋给result
 148   1         E=0;         //将E恢复低电平
 149   1         return result;
 150   1        }
 151          /*****************************************************
 152          函数功能:将模式设置指令或显示地址写入液晶模块
 153          入口参数:dictate
 154          ***************************************************/
 155          void WriteInstruction (unsigned char dictate)
 156          {   
 157   1          while(BusyTest()==1);   //如果忙就等待
 158   1               RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
 159   1               RW=0;   
 160   1               E=0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
 161   1                                 // 就是让E从0到1发生正跳变,所以应先置"0"
 162   1               _nop_();
 163   1               _nop_();               //空操作两个机器周期,给硬件反应时间
 164   1               P0=dictate;            //将数据送入P0口,即写入指令或地址
 165   1               _nop_();
 166   1               _nop_();
 167   1               _nop_();
 168   1               _nop_();               //空操作四个机器周期,给硬件反应时间
 169   1               E=1;                   //E置高电平
 170   1               _nop_();
 171   1               _nop_();
 172   1               _nop_();
 173   1               _nop_();               //空操作四个机器周期,给硬件反应时间
 174   1                E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
 175   1       }
 176          /*****************************************************
 177          函数功能:指定字符显示的实际地址
 178          入口参数:x
 179          ***************************************************/
C51 COMPILER V8.18   EX98                                                                  01/04/2010 16:37:15 PAGE 4   

 180           void WriteAddress(unsigned char x)
 181           {
 182   1           WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
 183   1       }
 184          /*****************************************************

⌨️ 快捷键说明

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