原创 DS1302掉电不掉时哦

2008-4-22 15:35 6273 9 13 分类: MCU/ 嵌入式

点击下载     虽然程序大部分是一个网友的(我只改了3个函数),思路也是别人的。可是看在我搞了1天的份上面还是算原创吧,o(∩_∩)o...


注意那个IO口要和电源间接个电阻哦,还有我的外接电源用的手机电池,为这个去买充电电池不划算的


 


# include <AT89x52.h>


/*****************************************


         P0------DB0~DB7        
   P1.0------RS
   P1.1------RW
   P1.2------E


*****************************************/


# define LCD_DB        P0


  sbit         LCD_RS=P1^0;


  sbit         LCD_RW=P1^1;


  sbit         LCD_E=P1^2;


  sbit         DS1302_SCLK = P3^4;


  sbit         DS1302_IO   = P3^3;


  sbit         DS1302_RST  = P3^5;


  //定义待设置的时间:秒、分、时、日、月、星期、年、控制字
  char table[]={0x00,0x58,0x12,0x8,0x3,0x06,0x06,0x00};
  char table1[]={0x11};
  char table2[]={0x22};


  unsigned char bdata time_rx ;
  sbit     time_rx7 = time_rx^7;
/******定义函数****************/


# define uchar unsigned char


# define uint unsigned int



void LCD_init(void);//初始化函数


void LCD_write_command(uchar command);//写指令函数


void LCD_write_data(uchar dat);//写数据函数


void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-16),y(1-2)


void delay_n40us(uint n);//延时函数


  //写一个字节数据函数
void time_write_1(unsigned char time_tx)
{
     int j;                             //设置循环变量
     for(j=0;j<8;j++)                   //连续写8bit
       {
         DS1302_IO    =  0;                         //先设置数据为0
         DS1302_SCLK  =  0;                        //时钟信号拉低
         if(time_tx&0x01)               //判断待发送的数据位是0或1
         {
             DS1302_IO = 1;                     //待发送数据位是1
         }
         time_tx=time_tx>>1;            //待发送的数据右移1位
         DS1302_SCLK = 1;                        //拉高时钟信号
        }
         DS1302_SCLK = 0;                          //写完一个字节,拉低时钟信号
   }
//---------------------------------------------
//读一个字节函数
unsigned char time_read_1()
{
    int j;                             //设置循环变量
 
 
 DS1302_IO = 1;        //设置为输入方式
    for(j=0;j<8;j++)                   //连续读取8bit
    {
         DS1302_SCLK  = 0;                       //拉低时钟信号
         time_rx=time_rx>>1;           //接收寄存器右移1位
         time_rx7=DS1302_IO;          //把接收到的数据放到接收寄存器的最高位
         DS1302_SCLK = 1;                        //拉高时钟信号
       }
    
     DS1302_SCLK = 0;                           //拉低时钟信号
     return(time_rx);                  //返回读取到的数据
 }


 


//DS1302初始化函数
void ds1302_init()
{
    DS1302_SCLK  =   0;                             //拉低时钟信号
    DS1302_RST   =   0;                             //复位DS1302
    DS1302_RST   =   1;                             //使能DS1302
    time_write_1(0x8e);                              //发控制命令
    time_write_1(0);                                  //允许写DS1302
 
    DS1302_RST   =   0;                              //复位
 }


//---------------------------------------------


 //---------------------------------------------
//设置时间函数
void set_time()
{
    int i;                              //定义循环变量
    DS1302_RST = 1;                     //使能DS1302
    time_write_1(0xbe);                 //时钟多字节写命令
    for(i=0;i<8;i++)                    //连续写8个字节数据
    {
        time_write_1(table);         //调用写一个字节函数
    }
    DS1302_RST = 0;                              //复位
}


//---------------------------------------------


 



//---------------------------------------------
//设置是否初始化标志
void set_ytime()
{
  
    DS1302_RST = 1;                              //使能DS1302
    time_write_1(0xc0);                 //时钟多字节写命令
  
    time_write_1(table1[0]);         //调用写一个字节函数
   
    DS1302_RST = 0;                              //复位
}
//读取初始化标志函数
void get_ytime()
{
   
    DS1302_RST = 1;                              //使能DS1302
    time_write_1(0xc1);                 //发送多字节读取命令
   
    table2[0]=time_read_1();       //调用读取1个字节数据的函数
    
    DS1302_RST = 0;                             //复位DS1302
}
//---------------------------------------------


 


 


//读取时间函数
void get_time()
{
    int i;                              //设置循环变量
    DS1302_RST = 1;                              //使能DS1302
    time_write_1(0xbf);                 //发送多字节读取命令
    for(i=0;i<7;i++)                    //连续读取7个字节数据
      {
         table=time_read_1();       //调用读取1个字节数据的函数
      }
    DS1302_RST = 0;                             //复位DS1302
}



//*******初始化函数***************


void LCD_init(void)


{


    delay_n40us(10000);


    LCD_write_command(0x38);//设置8位格式,2行,5x7


    LCD_write_command(0x38);//设置8位格式,2行,5x7


    LCD_write_command(0x38);//设置8位格式,2行,5x7


   
 LCD_write_command(0x02);//整体显示,关光标,不闪烁


 LCD_write_command(0x0C);//清除屏幕显示


    LCD_write_command(0x06);//设定输入方式,增量不移位


}


//********************************


//********写指令函数************


void LCD_write_command(uchar dat)


{
   
    LCD_E = 0;
 
 LCD_RS=0;//指令


    LCD_RW=0;//写入


    LCD_DB=dat;
 
 LCD_E=1;//允许


 delay_n40us(10);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。


    LCD_E = 0;
}


//*******************************


//********写数据函数*************


void LCD_write_data(uchar dat)


{


     LCD_E = 0;    


  LCD_RS=1;//数据


     LCD_RW=0;//写入


     LCD_DB=dat;
 
  LCD_E=1;//允许


     delay_n40us(10);
    
  LCD_E = 0;
}


//********************************


//*******显示一个字符函数*********


void LCD_disp_char(uchar x,uchar y,uchar dat)


{
  uchar address;


     if(y==1)


              address="0x80"+x;


     else


              address="0xc0"+x;


     LCD_write_command(address);


     LCD_write_data(dat);
}


 


void delay_n40us(uint n)


{   
       uint i;


      uchar j;           


        for(i=n;i>0;i--)


           for(j=0;j<15;j++)
            ;          //


}                                         //


//*******************************


void disp_time()
{
    LCD_disp_char(3,1,((table[2]&0xf0)>>4)+0x30);
 
 LCD_disp_char(4,1,(table[2]&0x0f)+0x30);
 
 LCD_disp_char(5,1,':');


 
 LCD_disp_char(6,1,((table[1]&0xf0)>>4)+0x30);
 
 LCD_disp_char(7,1,(table[1]&0x0f)+0x30);
 
 
 LCD_disp_char(8,1,':');


 LCD_disp_char(9,1,((table[0]&0xf0)>>4)+0x30);
 
 LCD_disp_char(10,1,(table[0]&0x0f)+0x30);
 



}


//*********主函数*****************


void main(void)


{      
   
  get_ytime();
      
  if(table2[0]==0x11)
      {
    ;
      }
    else
   {
      ds1302_init();                    //调用DS1302初始化函数
       
         set_time();                       //调用设置时间函数 


      set_ytime();                       //调用设置标志函数
   }
   


  
         DS1302_RST   =   1;                             //使能DS1302


        time_write_1(0x90);                 //充电命令
  
        time_write_1(0xa5);         //打开充电二级管  一个二级管串联一个2K电阻


     DS1302_RST   =   0;                             //复位DS1302
      
 


   
  LCD_init();


        while(1)
  {
     get_time();                  //调用取时间函数
    
     disp_time();
    
   }
       
}

文章评论4条评论)

登录后参与讨论

jizzll_617398179 2008-5-18 23:51

哦,呵呵

用户371580 2008-5-18 17:46

呵呵,收了,研究研究

jizzll_617398179 2008-4-26 19:08

呵呵,要注意我上一篇博客写的东西哦

用户1364249 2008-4-26 18:23

去试验一下
相关推荐阅读
jizzll_617398179 2010-02-08 10:53
正确理解A/D转换器的输入
http://www.freescale.com.cn/tech_ariticles/2005/1102_1.asp 许多嵌入式应用都会用到A/D转换器。然而,如果错误连接了A/D转换器输入端的电路,...
jizzll_617398179 2010-01-12 13:37
好久没来,都长草了
好久没来,都长草了,呵呵。整天忙得很,不过估计再过两个月会轻松点~\(≧▽≦)/~啦啦啦...
jizzll_617398179 2009-03-16 21:57
很奇怪,我收到站内信,但是却找不到发信人呢
发信人是个[],点击就跳到我自己的主页了。只好在这里给那位朋友留言了。 我不知道你说的哪篇文章,还有我也不知道你的EDN的ID。你可以在博客上面留言的。...
jizzll_617398179 2009-03-14 13:08
如何在EXCEL中使用16进制数
最近需要计算串口发送的数据,太多而且比较麻烦。知道EXECL功能强大,所以网上找了找,刚好,不错,很方便。网上找到的http://hi.bccn.net/space-99452-do-blog-id-...
jizzll_617398179 2009-03-05 14:37
〖常识〗不同晶振的最大波特率及其误差
最近犯了个错误,呵呵,晶振和波特率的问题,特查了记在这里,O(∩_∩)O~〖常识〗不同晶振的最大波特率及其误差http://www.aoxue.org/bbs/read.php?tid=65585不同...
jizzll_617398179 2009-02-11 14:30
大端模式和小端模式
转载http://www.cnblogs.com/TsuiLei/archive/2008/10/29/1322504.html大端格式:在这种格式中,字数据的高字节存储在低地址中,而字数据的低字节则...
我要评论
4
9
关闭 站长推荐上一条 /2 下一条