基于DS1302的实用时钟程序(iccavr)

发布者:beta12最新更新时间:2016-10-29 来源: eefocus关键字:DS1302  实用时钟  iccavr 手机看文章 扫描二维码
随时随地手机看文章
/*******************************************

*lcd1602_8h.h*
*    LCD1602操作库函数,8位数据联接关系:  *
*  LCD1602:DB0-DB7    M16:PB0-PB7     *
*  LCD1602:RS         M16:PD3      *
*  LCD1602:E         M16:PD6      *
*  LCD1602:R/W  GND       * 
*******************************************/
//LCD相关端口定义
#define RS1602 PD3   //RS接在PORTD.3上
#define E1602 PD6  //E接在PORTD.6上
#define CLR_RS PORTD&=~(1< #define SET_RS PORTD|=1< #define CLR_E PORTD&=~(1< #define SET_E PORTD|=1< //简化宏定义
#define uchar unsigned char
#define uint unsigned int

//延时函数:入口i,需要定时的时长
void delay(uint i)      //在1M时钟下为i ms
    {
 uchar j;
 for(;i;i--)
    {
    for(j=220;j;j--)
       {;}
    }
    }
/*************************************
*         LCD1602操作函数组    *
*************************************/
//写数据到LCD的函数:入口data,需写入的显示数据
void lcd_da(uchar data)
   {
   SET_RS;        //RS置高,写数据
   delay(1);
   SET_E;
   PORTB=data;    //数据送端口
   delay(1);
   CLR_E;     //E下降沿写入数据
   delay(1);    //延时1MS
   }

//写指令到LCD的函数:入口data,需写入的控制指令
void lcd_comm(uchar data)
   {
   CLR_RS;      //RS清0,写指令
   delay(1);    //延时1MS
   SET_E;
   PORTB=data;    //指令送端口
   delay(1);
   CLR_E;     //E下降沿写入指令
   delay(1);    //延时1MS
   }
//将时钟数据转换后在LCD上显示   
void timer_lcd(void)
   {
   lcd_comm(0x80);        //写指令:第1行地址
   lcd_da(0x20);        //留3个空格,使显示数据居中
   lcd_da(0x20); 
   lcd_da(0x20); 
   lcd_da(0x32);        //显示世纪位:2
   lcd_da(0x30);        //0
   
   lcd_da((timer[1]>>4)+0x30);   //显示年
   lcd_da((timer[1]&0x0f)+0x30);
   lcd_da('/');
   lcd_da((timer[2]>>4)+0x30);   //显示月
   lcd_da((timer[2]&0x0f)+0x30);
   lcd_da('/');
   lcd_da((timer[3]>>4)+0x30);   //显示日
   lcd_da((timer[3]&0x0f)+0x30);

   lcd_comm(0xC0);       //写指令:第2行地址
   lcd_da(20);        //留1个空格
   
   lcd_da((timer[4]>>4)+0x30);   //时
   lcd_da((timer[4]&0x0f)+0x30);
   lcd_da(':');
   lcd_da((timer[5]>>4)+0x30);   //分
   lcd_da((timer[5]&0x0f)+0x30);
   lcd_da(':');   
   lcd_da((timer[6]>>4)+0x30);   //秒
   lcd_da((timer[6]&0x0f)+0x30);

   lcd_da(20);       //时间与星期间留1空格
   lcd_da('W');       //星期的前导字
   lcd_da('e');
   lcd_da('e');
   lcd_da('k');
   lcd_da((timer[7]&0x0f)+0x30);  //星期数据
   }
   
//调整显示函数
//入口:m为调整的数据说明,i为调整数据
void set_timer_lcd(uchar m,uchar i)
   {
   lcd_comm(0x80);        //写指令:第1行地址
   lcd_comm(0x01);       //写指令:CLS
   lcd_da(0x20);      //留空格
   lcd_da(0x20);
//   lcd_da(0x20); 
//   lcd_da(0x20);
   lcd_da('S');        //显示SET:
   lcd_da('E');
   lcd_da('T');   
   lcd_da(':');
   lcd_comm(0xC0);       //写指令:第2行地址
   lcd_da(20);        //留1个空格
   switch(m)
     {
  case 1:       //年调整
    {lcd_da('Y');
    lcd_da('E');
    lcd_da('A');
    lcd_da('R');
    lcd_da('=');};break;
  case 2:          //月调整
    {lcd_da('M');
    lcd_da('O');
    lcd_da('N');
    lcd_da('T');
    lcd_da('H');
    lcd_da('=');};break;  
  case 3:        //日调整
    {lcd_da(0x20);
    lcd_da('D');
    lcd_da('A');
    lcd_da('Y');
    lcd_da('=');};break;  
  case 4:        //小时调整
    {lcd_da('H');
    lcd_da('O');
    lcd_da('U');
    lcd_da('R');
    lcd_da('=');};break; 
  case 5:       //分调整
    {lcd_da(0x20);
    lcd_da('M');
    lcd_da('I');
    lcd_da('N');
    lcd_da('=');};break; 
  case 7:          //周调整
    {lcd_da('W');
    lcd_da('E');
    lcd_da('E');
    lcd_da('K');
    lcd_da('=');};break;
  default:;break;
  }
   lcd_da((i>>4)+0x30);      //调整数据
   lcd_da((i&0x0f)+0x30);
   lcd_da(0x20); 
   lcd_da(0x20);
   }
   
//LCD1602初始化函数
void lcd_init(void)
   {   
   lcd_comm(0x38);    //写指令:8位数据、2行显示、5*8点阵
   delay(5);
   lcd_comm(0x06);    //写指令:自左向右显示
   delay(5);
   lcd_comm(0x0C);    //写指令:显示开
   delay(5);
   lcd_comm(0x14);    //写指令:移动
   delay(5);
   lcd_comm(0x80);    //写指令:第1行地址
   delay(5);  
   lcd_comm(0x01);    //写指令:CLS
   }

//ds1302_h.h

//DS1302操作库函数,在用M16学习板时可直接引用
//宏定义:
//联接DS1302的端口定义
#define ds1302_rst PC4         //定义1302的RST接在PC4
#define ds1302_io PC3         //定义1302的IO接在PC3
#define ds1302_sclk PC2        //定义1302的时钟接在PC2
#define set_ds1302_rst_ddr() DDRC|=1< #define set_ds1302_rst() PORTC|=1< #define clr_ds1302_rst() PORTC&=~(1< #define set_ds1302_io_ddr() DDRC|=1< #define set_ds1302_io() PORTC|=1< #define clr_ds1302_io() PORTC&=~(1< #define clr_ds1302_io_ddr() DDRC&=~(1< #define in_ds1302_io() PINC&(1< #define set_ds1302_sclk_ddr() DDRC|=1< #define set_ds1302_sclk() PORTC|=1< #define clr_ds1302_sclk() PORTC &=~(1< #define ds1302_sec_add 0x80        //秒数据地址
#define ds1302_min_add 0x82        //分数据地址
#define ds1302_hr_add 0x84         //时数据地址
#define ds1302_date_add 0x86        //日数据地址
#define ds1302_month_add 0x88        //月数据地址
#define ds1302_day_add 0x8a        //星期数据地址
#define ds1302_year_add 0x8c        //年数据地址
#define ds1302_control_add 0x8e       //控制数据地址
#define ds1302_charger_add 0x90       
#define ds1302_clkburst_add 0xbe

//简化宏定义
#define uchar unsigned char
#define uint unsigned int

/*************************************
*         DS1302操作函数组    *
*************************************/
//写入1302数据函数:
//入口:add为写入地址码,data为写入数据
//返回:无
void ds1302_write(uchar add,uchar data) 
   { 
   uchar i=0; 
   set_ds1302_io_ddr();     //配置IO为输出
   asm("nop"); 
   asm("nop"); 
   clr_ds1302_rst();      //清复位,停止所有操作
   asm("nop"); 
   asm("nop"); 
   clr_ds1302_sclk();      //清时钟,准备操作
   asm("nop"); 
   asm("nop"); 
   set_ds1302_rst();      //置复位,开始操作
   asm("nop"); 
   asm("nop"); 
   for(i=8;i>0;i--)      //此循环写入控制码
     { 
  if(add&0x01)
     set_ds1302_io();     //当前位为1,置数据位
  else
     clr_ds1302_io();     //当前位为0,清数据位
  asm("nop"); 
  asm("nop"); 
  set_ds1302_sclk();     //产生时钟脉冲,写入数据
  asm("nop"); 
  asm("nop"); 
  clr_ds1302_sclk(); 
  asm("nop"); 
  asm("nop"); 
  add>>=1;         //移位,准备写入下1位
  } 
   for(i=8;i>0;i--)      //此循环写入数据码 
     { 
     if(data&0x01)
     set_ds1302_io(); 
     else
     clr_ds1302_io(); 
     asm("nop"); 
     asm("nop"); 
     set_ds1302_sclk(); 
     asm("nop"); 
     asm("nop"); 
     clr_ds1302_sclk(); 
     asm("nop"); 
     asm("nop"); 
     data>>=1; 
     } 
   clr_ds1302_rst(); 
   asm("nop"); 
   asm("nop"); 
   clr_ds1302_io_ddr();      //清输出状态
   asm("nop"); 
   asm("nop"); 
   }
//从1302中读出数据:
//入口:add为读数据所在地址
//返回:读出的数据data
uchar ds1302_read(uchar add) 
   { 
   uchar data=0; 
   uchar i=0; 
   add+=1;            //读标志 
   set_ds1302_io_ddr();     //端口输出 
   asm("nop"); 
   asm("nop"); 
   clr_ds1302_rst();     //清复位 
   asm("nop"); 
   asm("nop"); 
   clr_ds1302_sclk();      //清时钟
   asm("nop"); 
   asm("nop"); 
   set_ds1302_rst();      //置复位
   asm("nop"); 
   asm("nop"); 
   for(i=8;i>0;i--)      //此循环写入地址码
     { 
  if(add&0x01)
     {set_ds1302_io();} 
  else
     {clr_ds1302_io();}
  
  asm("nop"); 
  asm("nop"); 
  set_ds1302_sclk(); 
  asm("nop"); 
  asm("nop"); 
  clr_ds1302_sclk(); 
  asm("nop"); 
  asm("nop"); 
  add>>=1; 
  } 
   clr_ds1302_io_ddr();      //端口输入
   asm("nop"); 
   asm("nop"); 
   for(i=8;i>0;i--)      //此循环读出1302的数据
     { 
  data>>=1; 
  if(in_ds1302_io())
     {data|=0x80;}
  asm("nop"); 
  asm("nop"); 
  set_ds1302_sclk(); 
  asm("nop"); 
  asm("nop"); 
  clr_ds1302_sclk(); 
  asm("nop"); 
  asm("nop"); 
  } 
   clr_ds1302_rst(); 
   asm("nop"); 
   asm("nop"); 
   return(data); 
   } 
//检查1302状态
uchar check_ds1302(void) 
   { 
   ds1302_write(ds1302_control_add,0x80); 
   if(ds1302_read(ds1302_control_add)==0x80) return 1; 
   return 0; 
   } 
//向1302中写入时钟数据
void ds1302_write_time(void) 
   { 
   ds1302_write(ds1302_control_add,0x00);   //关闭写保护 
   ds1302_write(ds1302_sec_add,0x80);    //暂停 
   ds1302_write(ds1302_charger_add,0xa9);   //涓流充电 
   ds1302_write(ds1302_year_add,timer[1]);   //年 
   ds1302_write(ds1302_month_add,timer[2]);  //月 
   ds1302_write(ds1302_date_add,timer[3]);   //日 
   ds1302_write(ds1302_day_add,timer[7]);   //周 
   ds1302_write(ds1302_hr_add,timer[4]);   //时 
   ds1302_write(ds1302_min_add,timer[5]);   //分 
   ds1302_write(ds1302_control_add,0x80);   //打开写保护 
   }

//秒清0,并启动时钟
void start_ds1302(void)
   {   
   ds1302_write(ds1302_control_add,0x00);   //关闭写保护
   ds1302_write(ds1302_sec_add,0x00);    //开启计时,秒清0
   ds1302_write(ds1302_control_add,0x80);   //打开写保护
   }

 

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

/*ds1302_lcd_h.c */
/*DS1302 实用时钟程序LCD1602版  */
/* 实验环境:阿发的M16学习板      */
/* 时钟频率:内部 1.0000Mhz      */
/* 编译系统:ICCAVR6.31A      */
/* 功    能:通过按键S0-S7对时钟数据   */
/*           进行调整,在LCD1602上显示 */
/* 说    明:S0调整/正常,S1调整数据转换*/
/*           S2调整减,   S3调整加  */
/*           S7确认调整并写入暂停走时 */
/*    S8启动时钟正常走时   */
/****************************************/
#include
#include
#include
#include

//简化宏定义
#define uchar unsigned char
#define uint unsigned int
//全局变量定义
uchar timer[8];    //时钟数据
//定义按键数据
uchar key,k1;
uchar k2=0;
uchar set_flag=0;       //定义按键调整标志

//延时函数:入口i,需要定时的时长
void delay_ms(uint i)      //在1M时钟下为i ms
    {
 uchar j;
 for(;i;i--)
    {
    for(j=220;j;j--)
       {;}
    }
    }
   
//向1302中写入时钟数据
void ds1302_write_time(void) 
   { 
   ds1302_write(ds1302_control_add,0x00);   //关闭写保护 
   ds1302_write(ds1302_sec_add,0x80);    //暂停 
   ds1302_write(ds1302_charger_add,0xa9);   //涓流充电 
   ds1302_write(ds1302_year_add,timer[1]);   //年 
   ds1302_write(ds1302_month_add,timer[2]);  //月 
   ds1302_write(ds1302_date_add,timer[3]);   //日 
   ds1302_write(ds1302_day_add,timer[7]);   //周 
   ds1302_write(ds1302_hr_add,timer[4]);   //时 
   ds1302_write(ds1302_min_add,timer[5]);   //分
   ds1302_write(ds1302_control_add,0x80);   //打开写保护 
   }
//从1302中读出当前时钟
void ds1302_read_time(void) 
   { 
   timer[1]=ds1302_read(ds1302_year_add);   //年 
   timer[2]=ds1302_read(ds1302_month_add);  //月 
   timer[3]=ds1302_read(ds1302_date_add);   //日 
   timer[7]=ds1302_read(ds1302_day_add);   //周 
   timer[4]=ds1302_read(ds1302_hr_add);   //时 
   timer[5]=ds1302_read(ds1302_min_add);   //分 
   timer[6]=(ds1302_read(ds1302_sec_add))&0x7F;   //秒 
   }
   
//将时钟数据转换后在LCD上显示   
void timer_lcd(void)
   {
   lcd_comm(0x80);        //写指令:第1行地址
   lcd_da(0x20);        //留3个空格,使显示数据居中
   lcd_da(0x20); 
   lcd_da(0x20); 
   lcd_da(0x32);        //显示世纪位:2
   lcd_da(0x30);        //0
   
   lcd_da((timer[1]>>4)+0x30);   //显示年
   lcd_da((timer[1]&0x0f)+0x30);
   lcd_da('/');
   lcd_da((timer[2]>>4)+0x30);   //显示月
   lcd_da((timer[2]&0x0f)+0x30);
   lcd_da('/');
   lcd_da((timer[3]>>4)+0x30);   //显示日
   lcd_da((timer[3]&0x0f)+0x30);

   lcd_comm(0xC0);       //写指令:第2行地址
   lcd_da(20);        //留1个空格
   
   lcd_da((timer[4]>>4)+0x30);   //时
   lcd_da((timer[4]&0x0f)+0x30);
   lcd_da(':');
   lcd_da((timer[5]>>4)+0x30);   //分
   lcd_da((timer[5]&0x0f)+0x30);
   lcd_da(':');   
   lcd_da((timer[6]>>4)+0x30);   //秒
   lcd_da((timer[6]&0x0f)+0x30);

   lcd_da(20);       //时间与星期间留1空格
   lcd_da('W');       //星期的前导字
   lcd_da('e');
   lcd_da('e');
   lcd_da('k');
   lcd_da((timer[7]&0x0f)+0x30);  //星期数据
   }
   
//时钟调整加函数:入口b需要调整的时钟数据位置
void add_timer(uchar b)
   {
   switch(b)
     {
  case 1:        //年数据加1调整,范围00-99
    {
    timer[1]+=0x01;
    if((timer[1]& 0x0f)==0x0A)
      {
   timer[1]=((timer[1]&0xF0)+0x10);
   if(timer[1]>0x99)timer[1]=0x00;
   }
    };break;
  case 2:        //月数据加1调整,范围1-12
    {
    timer[2]+=0x01;
    if(timer[2]==0x13)timer[2]=0x01;
    if((timer[2]&0x0f)==0x0A)
      {
   timer[2]=((timer[2]&0xF0)+0x10);
   }
    };break;
  case 3:        //日数据加1调整,范围1-30,暂未考虑31日
    {
    timer[3]+=0x01;
    if(timer[3]>0x30)timer[3]=0x01;
    if((timer[3]&0x0f)==0x0A)
      {
   timer[3]=((timer[3]&0xF0)+0x10);
   }
    };break;
  case 4:        //时数据加1调整,范围0-24
    {
    timer[4]+=0x01;
    if(timer[4]==0x24)timer[4]=0x00;
    if((timer[4]&0x0f)==0x0A)
      {
   timer[4]=((timer[4]&0xF0)+0x10);
   }
    };break;
  case 5:        //分数据加1调整,范围0-59
    {
    timer[5]+=0x01;
    if((timer[5]&0x0f)==0x0A)
      {
   timer[5]=((timer[5]&0xF0)+0x10);
   if(timer[5]>0x59)timer[5]=0x00;
   }
    };break;
  case 7:        //星期数据加1调整,范围1-7
    {
    timer[7]+=0x01;
    if(timer[7]>0x07)timer[7]=0x01;
    };break;
  default:;break;
  }
   }
//时钟调整减函数:入口b需要调整的时钟数据位置
void dec_timer(uchar b)
   {
   switch(b)
     {
  case 1:        //年数据减1调整,范围00-99
    {
    timer[1]-=0x01;
    if((timer[1]&0x0f)==0x0F)
      {
   timer[1]=(timer[1]&0xF9);
   if(timer[1]>0x99)timer[1]=0x99;
   }
    };break;
  case 2:        //月数据减1调整,范围1-12
    {
    timer[2]-=0x01;
    if(timer[2]==0x00)timer[2]=0x12;
    if((timer[2]&0x0f)==0x0F)
      {
   timer[2]=(timer[2]&0xF9);
   }
    };break;
  case 3:        //日数据减1调整,范围1-30,暂未考虑31日
    {
    timer[3]-=0x01;
    if(timer[3]==0x00)timer[3]=0x30;
    if((timer[3]&0x0f)==0x0F)
      {
   timer[3]=(timer[3]&0xF9);
   }
    };break;
  case 4:        //时数据减1调整,范围0-24
    {
    timer[4]-=0x01;
    if(timer[4]>0x24)timer[4]=0x23;
    if((timer[4]&0x0f)==0x0f)
      {
   timer[4]=(timer[4]&0xF9);
   }
    };break;
  case 5:        //分数据减1调整,范围0-59
    {
    timer[5]-=0x01;
    if((timer[5]&0x0f)==0x0F)
      {
   timer[5]=(timer[5]&0xF9);
   if(timer[5]>0x59)timer[5]=0x59;
   }
    };break;
  case 7:        //星期数据减1调整,范围1-7
    {
    timer[7]-=0x01;
    if(timer[7]<0x01)timer[7]=0x07;
    };break;
  default:;break;
  }
   }
/***************************************
*           按键读取判断函数     *
* 函数功能:判断按键是否按下     *
* 入口参数:无         *
* 返 回 值:无键按下0,有键按下为1-8   *
* 说    明:需要在初始化函数中将接口置 *
*           为输入        *
***************************************/
uchar rd_key(void)
   {
   uchar a,b;
   a=PINA;
   if(a==0xFF)
      return(0);
   else
      {
   a=~a;
   switch(a)
     {
  case 0x01:b=1;break;
  case 0x02:b=2;break;
  case 0x04:b=3;break;
  case 0x08:b=4;break;
  case 0x10:b=5;break;
  case 0x20:b=6;break;
  case 0x40:b=7;break;
  case 0x80:b=8;break;
  default:b=0;break;
  }
      return(b);        //返回的1-8分别对应按键S0-S7
   }
   }
   
//定时器1:每秒从DS1302中读取4次数据,更新显示
void timer1_init(void)        //定时器1初始化:250毫秒定时,预分频256
   {
   TCCR1B = 0x00;          //停止定时器
   TCNT1H = 0xFC;      //初值高字节
   TCNT1L = 0x2F;      //定时初值低字节
   TCCR1A = 0x00;
   TCCR1B = 0x04;           //启动定时器
   }
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)     //定时器1中断入口:250MS中断一次
   {
   TCNT1H = 0xFC;      //重装初值
   TCNT1L = 0x2F;   
   ds1302_read_time();     //读出当前时钟
   timer_lcd();       //显示数据转换
   }

/* 定时器0中断配置函数
预分频数: 256
定时时间: 50mSec
功    能:在进入调整状态20秒内没操作自动回到时钟状态*/
void timer0_init(void)
{
 TCCR0 = 0x00;          //先关定器0
 TCNT0 = 0x3C;        //装初值
 OCR0  = 0x13;        //set compare
 TCCR0 = 0x04;        //开定时器
}
/* 定时器0中断入口函数 */
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
  TCNT0 = 0x3C;        //重装初值
 if(k2==0)
   {
   set_flag=0;     //清调整标志
   TCCR1B = 0x04;    //启动定时器1
   }
 else
   k2--;   
}
   
/*************************************
*              主函数     *
*************************************/
void main(void)
   {
   uchar a=1,b=0;
   DDRA=0x00;                //设置按键A口为带上拉输入:接按键
   PORTA=0xFF;
   DDRC=255;      //定义C口为输出:接LCD背光
   DDRB=255;       //定义B口为输出:接LCD数据
   PORTB=255;
   DDRD=0xFB;      //定义D口为输出:接LCD控制,PD2为输入,中断按钮
   PORTD=0x04;     //PD2上拉

   delay_ms(500);    //延时500ms,准备LCD初始化
   lcd_init();     //初始化LCD
   delay_ms(50);   
   
   CLI();      //先关闭所有中断
   timer0_init();     //设定定时器0
   timer1_init();    //设定定时器1
   MCUCR = 0x00;
   GICR  = 0x00;
   TIMSK = 0x05;    //允许定时器0、定时器1中断
   SEI();        //开总中断
 
   while(1)
      {
   if(rd_key()!=0)
     {
  k1=rd_key();     //
  delay_ms(20);    //
  if(rd_key()==k1)
    {
    key=rd_key();
    switch(key)
      {
   case 1:       //调整和结束调整处理
     {
     if(set_flag==0)
       {
    set_flag=1;
    a=1;
    k2=250;
    TCCR1B = 0x00;  //停止定时器1
    set_timer_lcd(1,timer[1]);   //年数据调整显示
    }
     else
       {
    set_flag=0;
    TCCR1B = 0x04;           //启动定时器
    }
     };break;
   case 2:          //调整数据切换
     {
     if(set_flag==1)
       {
      a++;
      if(a==6)a=7;
      if(a>=8)a=1;
      set_timer_lcd(a,timer[a]);
      k2=250;
    }
     };break;
   case 3:           //数据减1调整
     {
     if(set_flag==1)
       {
      dec_timer(a);
      set_timer_lcd(a,timer[a]);
      k2=250;
    }
     };break;
   case 4:              //数据加1调整
     {
     if(set_flag==1)
       {
      add_timer(a);
      set_timer_lcd(a,timer[a]);
      k2=250;
    }
     };break;
   case 5:;break;
   case 6:;break;
   case 7:           //写入调整后的时钟并暂停
     {
     if(set_flag==1)
       {
    ds1302_write_time();     //写入调整后的时钟并暂停
    set_flag=0;
    TCCR1B = 0x04;           //启动定时器
    b=1;
    }
     };break;
   case 8:           //启动时钟
     {
     if(b==1)
       {
    start_ds1302();
    b=0;
    }
     };break;
   default:;break;
   }
    while(rd_key()!=0)
      {
   delay_ms(20);
   }
    }
  }
   }
   }

关键字:DS1302  实用时钟  iccavr 引用地址:基于DS1302的实用时钟程序(iccavr)

上一篇:IIC的PCF8563实用时钟程序(iccavr)
下一篇:两个数码管从0显示到99(ICC-AVR)

推荐阅读最新更新时间:2024-03-16 15:18

单片机实时时钟电路(LCD1602、DS1302
一、简介 此电路主要有51单片机、LCD1602模块、DS1302芯片组成,通过LCD1062显示当前时间。 二、运行效果 三、源文件 main.c /*想要更多项目私wo!!!*/ #include reg52.h #include intrins.h #include string.h #define uint unsigned int #define uchar unsigned char sbit IO = P1^0; sbit SCLK = P1^1; sbit RST = P1^2; sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; uchar *
[单片机]
单片机实时<font color='red'>时钟</font>电路(LCD1602、<font color='red'>DS1302</font>)
DS1302的AVR单片机C程序
下面是DS1302的AVR 单片机 的C程序,这个程序结构很不错。但是没有调试这个AVR单片机的程序。 #define ds1302_rst PC0 #define ds1302_io PC1 #define ds1302_sclk PC2 #define set_ds1302_rst_ddr() DDRC|=1 ds1302_rst #define set_ds1302_rst() PORTC|=1 ds1302_rst #define clr_ds1302_rst() PORTC&=~(1 ds1302_rst) #define set_ds1302_io_ddr() DDRC|=1 ds1302_io #def
[单片机]
实时时钟芯片DS1302
DS1302是一种三线制的串行时钟芯片,即CE(片选),SCLK(时钟),I/O(双向数据)。从严格意义上来说,它不是SPI总线类型的,因为SPI的数据线的输入输出是分开的,但是我们操作的时候可以用带SPI的硬件接口的MCU,比如PIC16F877的MSSP模块。 命令字节的基本格式 存储器结构 需要注意的地方: 1.在上电时,RST 必须为逻辑0直至Vcc 2.0V。同时SCLK 在RST 驱动至逻辑1 状态时必须为逻辑0。 2.数据输入是在SCLK的上升沿,数据输出是在SCLK的下降沿。 3.传输方式:低位先传输。 4.时钟运行:秒寄存器的最高位(BIT7)是作为时钟控制位,当为逻辑1时
[单片机]
MSP430之变态版3线SPI总线实现(DS1302时钟芯片用)
如题, 这个是网上所谓的变态版的3线SPI总线:一根时钟线,一根使能线,一根双向IO线. 一个模块,两个文件: //spi3.c #include typedef.h #include spi3.h /*********************************************************************** 名称:init_spi3 描述:SPI3初始化函数 参数:(无) 返回:(无) 说明: ***********************************************************************/ void init_spi3(void) {
[单片机]
ds1302制作一个精密的电子时钟
题目:用ds1302制作一个精密的电子时钟 感想:我看视频的时候讲的是DS12CR887这块芯片,两块毕竟是不一样的,所以,我只是看了他讲怎样看时序,之后的就没再看了。我就拿着自己下载打印的DS1302数据手册,研习,研习,再研习。还查了书上的,网上的,源程序。但是,你别指望着谁会把所有的东西都给你写上去。只能作为参考。后来,我终于写出了一个程序,可是一编译,就漏洞百出。最主要的有两点:for循环和BCD码。不过还好,都得到了很好的解决。 解决方案: #include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned in
[单片机]
基于DS1302的简易数码管电子钟
#include reg51.h #include intrins.h #include DS1302.h #include KEY.h #include IIC.H #define uchar unsigned char #define uint unsigned int #define LEDIO P0 #define LEDCHIP P2 sbit BEEP=P3^7; /*************************数码管定义**************************************/ //段码 0 1 2 3 4 5 6 7 8 9 A B - P d uchar
[单片机]
IIC的PCF8563实用时钟程序(iccavr)
/************************************* * PCF8563时钟程序 * * 文 件 名:1602_8563.c * * 版 本:V22.02 * * 主控芯片:Mega16L * * 工作频率:7.3728MHz * *************************************/ #include iom16v.h #include macros.h #include stdio.h #include D:\PCF8563\1602_time\timer_io.h #include D:\PCF8563\1602_time\delay.h #incl
[单片机]
ds1302实时时钟
现在流行的串行时钟电路很多,如DS1302、DS1307、PCF8485等。这些电路的接口简单、价格低廉、使用方便,被广泛地采用。本文介绍的实时时钟电路DS1302是DALLAS公司的一种具有涓细电流充电能力的电路,主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。采用普通32.768kHz晶振。 2 DS1302的结构及工作原理   DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或R
[电源管理]
<font color='red'>ds1302</font>实时<font color='red'>时钟</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved