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

DS1302的AVR程序(2000年~2099年的星期自动计算功能)

发布时间:2020-06-19 发布时间:
|

虽然是在MEGA128上调的但适用于所有AVR芯片,改下管脚设置就行了。  

程序不是我原创,我只是把我找到的DS1302程序和星期计算程序做了下修改使他们能适应我的系统能一起工作而已,在此向写这些程序的原作者表示敬意。  

struct timechar  
{  
uchar nowyear;  

uchar nowmonth;  
uchar nowday;  
uchar nowhour;  
uchar nowminute;  
uchar nowsecond;  
uchar nowweek;  
};  
struct timechar nowtime;///这里存时间     


#define ds1302_rst   7                     /*!PORTB7 DS1302实时时钟复位线引脚 */  
#define ds1302_io   6                      /*!PORTB6 DS1302实时时钟数据线引脚 */     
#define ds1302_sclk  5                      /*!PORTB5 DS1302实时时钟时钟线引脚 */  

#define set_ds1302_rst_ddr()  DDRB|=1<#define set_ds1302_rst()        PORTB|=1<#define clr_ds1302_rst()        PORTB&=~(1<
#define set_ds1302_io_ddr()   DDRB|=1<#define clr_ds1302_io_ddr()    DDRB&=~(1<#define set_ds1302_io()          PORTB|=1<#define clr_ds1302_io()          PORTB&=~(1<#define in_ds1302_io()          PINB&(1<
#define set_ds1302_sclk_ddr() DDRB|=1<#define set_ds1302_sclk()        PORTB|=1<#define clr_ds1302_sclk()         PORTB&=~(1<
#define ds1302_sec_reg        0x80  
#define ds1302_min_reg        0x82  
#define ds1302_hr_reg           0x84  
#define ds1302_date_reg         0x86  
#define ds1302_month_reg       0x88  
#define ds1302_day_reg        0x8a  
#define ds1302_year_reg        0x8c  
#define ds1302_control_reg      0x8e  
#define ds1302_charger_reg    0x90  
#define ds1302_clkburst_reg   0xbe  

uchar BcdToBin(uchar val)  
  {  
  val = (val >> 4) *10+(val &0x0f); ///将BCD码转换为10进制数  
  return val; ///返回10进制数  
  }  

uchar BinToBcd(uchar val)  
  {  
  return ((val / 10) *16+val % 10);  
  }  

void ds1302_write(uchar reg, uchar data)  
  {  
  uchar i = 0;  
  set_ds1302_io_ddr();  
  nop();  
  nop();  
  clr_ds1302_rst();  
  nop();  
  nop();  
  clr_ds1302_sclk();  
  nop();  
  nop();  
  set_ds1302_rst();  
  nop();  
  nop();  
  for (i = 8; i > 0; i--)  
    {  
    if (reg &0x01)  
    {  
      set_ds1302_io();  
    }  
    else  
    {  
      clr_ds1302_io();  
    }  
    nop();  
    nop();  
    set_ds1302_sclk();  
    nop();  
    nop();  
    clr_ds1302_sclk();  
    nop();  
    nop();  
    reg >>= 1;  
    }  
  for (i = 8; i > 0; i--)  
    {  
    if (data &0x01)  
    {  
      set_ds1302_io();  
    }  
    else  
    {  
      clr_ds1302_io();  
    }  
    nop();  
    nop();  
    set_ds1302_sclk();  
    nop();  
    nop();  
    clr_ds1302_sclk();  
    nop();  
    nop();  
    data >>= 1;  
    }  
  clr_ds1302_rst();  
  nop();  
  nop();  
  clr_ds1302_io_ddr();  
  nop();  
  nop();  
  }  
uchar ds1302_read(uchar reg)  
  {  
  uchar data = 0;  
  uchar i = 0;  
  reg += 1; ///读标志  
  set_ds1302_io_ddr();  
  nop();  
  nop();  
  clr_ds1302_rst();  
  nop();  
  nop();  
  clr_ds1302_sclk();  
  nop();  
  nop();  
  set_ds1302_rst();  
  nop();  
  nop();  
  for (i = 8; i > 0; i--)  
    {  
    if (reg &0x01)  
    {  
      set_ds1302_io();  
    }  
    else  
    {  
      clr_ds1302_io();  
    }  
    nop();  
    nop();  
    set_ds1302_sclk();  
    nop();  
    nop();  
    clr_ds1302_sclk();  
    nop();  
    nop();  
    reg >>= 1;  
    }  
  clr_ds1302_io_ddr();  
  nop();  
  nop();  
  for (i = 8; i > 0; i--)  
    {  
    data >>= 1;  
    if (in_ds1302_io())  
    {  
      data |= 0x80;  
    }  
    nop();  
    nop();  
    set_ds1302_sclk();  
    nop();  
    nop();  
    clr_ds1302_sclk();  
    nop();  
    nop();  
    }  
  clr_ds1302_rst();  
  nop();  
  nop();  
  return (data);  
  }  
uchar check_ds1302(void)  
  {  
  ds1302_write(ds1302_control_reg, 0x80);  
  if (ds1302_read(ds1302_control_reg) == 0x80)  
  {  
    return 1;  
  }  
  return 0;  
  }  
void ds1302_read_time(void)  
  {  
  uchar tmphour;  
  nowtime.nowyear = BcdToBin(ds1302_read(ds1302_year_reg)); ///年  
  nowtime.nowmonth = BcdToBin(ds1302_read(ds1302_month_reg)); ///月  
  nowtime.nowday = BcdToBin(ds1302_read(ds1302_date_reg)); ///日  
  nowtime.nowweek = BcdToBin(ds1302_read(ds1302_day_reg)); ///周  
  tmphour = ds1302_read(ds1302_hr_reg); ///时  
  nowtime.nowhour = (tmphour &0b00100000) / 32 * 20+(tmphour &0x10) / 16 * 10+(tmphour &0x0F);  
  nowtime.nowminute = BcdToBin(ds1302_read(ds1302_min_reg)); ///分  
  nowtime.nowsecond = BcdToBin(ds1302_read(ds1302_sec_reg)); ///秒  
  }  

const unsigned char WeekTab[] = {  
   //闰年月星期表  
  (3 <  (6 <  (0 <  (3 <  (5 <  (1 <  (3 <  (6 <  (1 <  (4 <  (0 <  (2 <};  

/*!------------------------------------------------------------------------------  
                                2000年~2099年星期算法  
-------------------------------------------------------------------------------*/  
unsigned char WeekDay20(unsigned char y, unsigned char m, unsigned char d)  
{  
unsigned char week, day;  
  day = WeekTab[m - 1];///月表  
  week = day >> 5;///月星期数  
  day &= 0x1f;//月天数  
  if ((m       {///平年  
    if (m == 2) day--;///平年月天数  
    week++;///平年月表+1  
  }  
  y = y + (y >> 2);//年+年/4  
  week = (week +  y + d + 2) % 7;///(星期=年+年/4+月表+2日)%7  
  return week;///返回星期  
}  

void ds1302_write_time(void)  
  {  
  uchar bcdyear;  
  uchar bcdmonth;  
  uchar bcdday;  
  uchar bcdhour;  
  uchar bcdminute;  
  uchar bcdsecond;  
  uchar bcdweek;  

  bcdyear = BinToBcd(nowtime.nowyear);  
  bcdmonth = BinToBcd(nowtime.nowmonth);  
  bcdday = BinToBcd(nowtime.nowday);  
  bcdhour = BinToBcd(nowtime.nowhour);  
  bcdminute = BinToBcd(nowtime.nowminute);  
  bcdsecond = BinToBcd(nowtime.nowsecond);  
     
  nowtime.nowweek=WeekDay20(nowtime.nowyear,nowtime.nowmonth,nowtime.nowday);  
  bcdweek = BinToBcd(nowtime.nowweek);  
     
  ds1302_write(ds1302_control_reg, 0x00); ///关闭写保护  
  ds1302_write(ds1302_sec_reg, 0x80); ///暂停  
  ds1302_write(ds1302_day_reg, bcdweek); ///周     
  ds1302_write(ds1302_charger_reg, 0xa9); ///涓流充电  
  ds1302_write(ds1302_year_reg, bcdyear); ///年  
  ds1302_write(ds1302_month_reg, bcdmonth); ///月  
  ds1302_write(ds1302_date_reg, bcdday); ///日  
  ds1302_write(ds1302_hr_reg, bcdhour); ///时  
  ds1302_write(ds1302_min_reg, bcdminute); ///分  
  ds1302_write(ds1302_sec_reg, bcdsecond); ///秒  
  ds1302_write(ds1302_control_reg, 0x80); ///打开写保护  
 } 


关键字:DS1302  AVR程序  自动计算功能 

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

热门文章 更多
单片机制作超级流水灯