×
单片机 > 单片机程序设计 > 详情

ds1302 ICC程序

发布时间:2020-06-19 发布时间:
|
//串行数码管显示  年-月-日   时-分-秒

//芯片 ATMEGA16L 
//时钟 4MHz 内部
// DS1302 上升沿读写数据
// DS1302 读数据时 IO口上拉无效  
//短延时 2us  wait();    长延时 n ms   delay_nms();
#include 

//164数据线置1
#define hc164_data_SET     PORTD |= 0x01  
//164数据线清0 
#define hc164_data_CLR     PORTD &= ~0x01 
//164时钟线置1 
#define hc164_clk_SET      PORTD |= 0x02  
//164时钟线清0 
#define hc164_clk_CLR      PORTD &= ~0x02 

void hc164_send_byte (unsigned char byte); //164发送数据子程序
void delay_nms(unsigned int);  //延时 n ms
void wait(void);               //短延时 2us   

/*--------------------------DS1302程序开始----------------------------------*/
#define SCLK1302  4  // 时钟
#define DATA1302  5  // 数据
#define RST1302   6  // 复位
//时钟线置1
#define SET_SCLK1302     PORTD |=  (1< //时钟线清0
#define CLR_SCLK1302     PORTD &= ~(1< //数据线置1
#define SET_DATA1302     PORTD |=  (1<TA1302)
//数据线清0
#define CLR_DATA1302     PORTD &= ~(1<TA1302)
//复位线置1
#define SET_RST1302      PORTD |=  (1< //复位线清0
#define CLR_RST1302      PORTD &= ~(1< //DS1302的数据线DATA置为输出
#define DATA1302_OUT   DDRD |= (1<TA1302)
//DS1302的数据线DATA置为输入
#define DATA1302_IN   DDRD &= ~(1<TA1302)

void wr1302(unsigned char dat);   //向1302写1个字节
unsigned char rd1302(void);       //从1302读1个字节
void v_wr1302(unsigned char add,unsigned char dat);  //先写地址,后写1字节数据
unsigned char v_rd1302(unsigned char add);           //先写地址,后读1字节数据
void v_set1302(unsigned char *p2);                   //设置初始时间
void v_get1302(void);                                //读取DS1302当前时间
/* --------------------DS1302程序结束--------------------------------------  */
char ledxs[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
      // 年-月-日 或 时-分-秒  LED显示  
char time[7];  //当前时间,格式: 秒 分 时 日 月 星期 年
char settime[7]={0x00,0x39,0x21,0x28,0x01,0x04,0x10};
               //时间初始值: 秒   分    时   日  月  星期  年
const char tab[]={0xb7,0x12,0x67,0x76,0xd2,0xf4,0xf5,0x16,0xf7,0xf6,0xd7,0xf1,0xa5,0x73,0xe5,0xc5,0,0xff,0x40};
                          //共阴极代码 0-F,  全灭,全亮,‘-’
void main(void)
{
   unsigned char i,k; 
   wait(); 
   wait(); 
   delay_nms(200); 
   DDRD = 0xff;  
   v_set1302(settime); // 设置初始时间
   while(1)
   {   
     k=30;
     while(k>0)   //年-月-日  显示3秒   (例 09-06-04 )
     {
       v_get1302();    //取得当前时间     
       ledxs[0]=time[6]>>4;
       ledxs[1]=time[6]&0x0f;  // 年
       ledxs[2]=18;        // -
       ledxs[3]=time[4]>>4;
       ledxs[4]=time[4]&0x0f;  // 月
       ledxs[5]=18;       // -
       ledxs[6]=time[3]>>4;
       ledxs[7]=time[3]&0x0f;  // 日
       for(i=0;i<8;i++) //串行显示
       {
         hc164_send_byte ( tab[ledxs[i]] );
         wait(); 
       }
       k--;
       delay_nms(100);
     }
     k=100;
     while(k>0)    //时-分-秒   显示10秒    (例 16-30-00 )
     {
       v_get1302();    //取得当前时间    
       ledxs[0]=time[2]>>4;
       ledxs[1]=time[2]&0x0f;  // 时
       ledxs[2]=18;        // -
       ledxs[3]=time[1]>>4;
       ledxs[4]=time[1]&0x0f;  // 分
       ledxs[5]=18;       // -
       ledxs[6]=time[0]>>4;
       ledxs[7]=time[0]&0x0f;  // 秒
       for(i=0;i<8;i++)  //串行显示
       {
         hc164_send_byte ( tab[ledxs[i]] );
         wait();
       }
       k--;
       delay_nms(100);
     }
   }

void wait(void)    //短延时 2us  
{  
  asm("nop"); 
  asm("nop");     
}  
void delay_nms(unsigned int k)  //延时 n ms
{
  while(k)   //4M晶振,一个循环1ms
  {
  int i;
  i=700;
  while(i--);
  k=k-1;
  }
}
void hc164_send_byte (unsigned char byte)  //164发送数据子程序
{
  unsigned char i;
   for(i=0;i<8;i++)
   {
      if( byte & ( 1 << i )) 
     hc164_data_SET;
   else 
     hc164_data_CLR;
      hc164_clk_SET;
      hc164_clk_CLR;   
   }  

void wr1302(unsigned char dat0)    //向1302写1个字节
{
  unsigned char i;
  for(i=0;i<8;i++)  //从最低位开始发送
  {
    if(dat0&0x01) 
       SET_DATA1302;
    else
       CLR_DATA1302;     //位传送至数据总线
    wait(); 
    SET_SCLK1302;  //时钟上升沿,发送数据有效
    wait(); 
    CLR_SCLK1302; //清时钟总线
    wait(); 
    dat0 >>= 1;
  }
}
unsigned char rd1302(void) //从1302读1个字节
{
  unsigned char i,dat=0;   
  for(i=0;i<8;i++)  //从最低位开始接收
  {
    dat >>= 1;
    if((PIND&(1<TA1302))==(1<TA1302)) dat |= 0x80;    //接收1位数据   
    SET_SCLK1302;;//时钟置高电平 ,时钟上降沿,接收数据有效
    wait(); 
    CLR_SCLK1302;//清时钟总线
    wait();
  }
  return dat;
}
void v_wr1302(unsigned char add,unsigned char dat)//先写地址,后写1字节数据
{            //      地址或命令             数据
 
  DATA1302_OUT; //DATA1302置为输出  
  CLR_RST1302;//复位引脚低电平,所有数据传送终止
  wait();  
  CLR_SCLK1302;//清时钟总线
  wait();   
  SET_RST1302;//复位引脚高电平,控制逻辑有效
  wait(); 
  wr1302(add);   //写地址或命令
  wait();
  wr1302(dat);   //写1个数据
  wait(); 
  CLR_RST1302;  //复位引脚低电平,所有数据传送终止
  wait();
  DATA1302_IN; // DATA1302置为输入   
}
unsigned char v_rd1302(unsigned char add) //先写地址,后读1字节数据
{                     //         地址
  unsigned char i; 
  DATA1302_OUT; //DATA1302置为输出  
  CLR_RST1302;//复位引脚低电平,所有数据传送终止
  wait();  
  CLR_SCLK1302;//清时钟总线
  wait();
  SET_RST1302;//复位引脚高电平,控制逻辑有效
  wait();   
  wr1302(add);   //写地址或命令
  wait(); 
  PORTD &= ~(1 << DATA1302); //上拉无效
  DATA1302_IN;  // DATA1302置为输入    
  wait();
  i=rd1302();   //读取数据
  wait();
  CLR_RST1302;  //复位引脚低电平,所有数据传送终止
  wait();
  return i;  //返回读取的数据
}

/********************************************************************
* 名称: v_set1302
* 功能: 设置初始时间
* 调用: v_wr1302()
* 输入: *p2: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 
***********************************************************************/
 void v_set1302(unsigned char *p2)
{
  unsigned char i;
  unsigned char addr=0x80;
  v_wr1302(0x8e,0x00); //控制命令,WP=0,允许写
  for(i=0;i<7;i++)
  {
    v_wr1302(addr,*p2); // 秒 分 时 日 月 星期 年 
    p2++;
    addr=addr+2;
  }
  v_wr1302(0x8e,0x80); // 控制命令,WP=1,写保护

/********************************************************************
* 名称: v_get1302
* 功能: 读取DS1302当前时间
* 调用: v_rd1302()
* 输入: time: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 
***********************************************************************/
void v_get1302(void)
{
  unsigned char i;
  unsigned char addr=0x81;
  for(i=0;i<7;i++)
  {
     time[i]=v_rd1302(addr);  //格式为: 秒 分 时 日 月 星期 年
     addr=addr+2;
  }
}

关键字:ds1302  ICC程序 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何升级STM32单片机的代码