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

📄 rtc_ds12887.c

📁 本程序是用 ATmega16 控制实时时钟芯片 DS12887 接口驱动的源程序文件。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
********************************************************************************************
源程序文件名:      RTC_DS12887.c
源程序名称:        实时时钟芯片 DS12887 接口驱动的源程序文件
程序版本:        1.0
程序功能:
    本程序是用 ATmega16 控制实时时钟芯片 DS12887 接口驱动的源程序文件。
程序说明:
    
函数入口参数:
函数出口参数:

编译工具软件:      IAR Embedded Workbench for Atmel AVR 版本:3.20 以上
链接子程序文件:

编作者:            
编作者 E-Mail:     PTZSW@163.COM
编制日期:          2005年5月22日
----------------------------------------------------------------------------------------
适用器件芯片类型:   Atmel 公司生产的8位 RISC 单片机
器件芯片时钟频率:
存储器模式:        小存储器模式
外部扩展存储器大小:0 【字节】
数据堆栈大小:      256 【字节】
----------------------------------------------------------------------------------------
源程序版本历史:
2005年5月22日 -------- 版本 1.0 :发行版本
********************************************************************************************
*/


/*==========================================================================================
                     本源程序包括的头部文件
==========================================================================================*/
#include "RTC_DS12887.h"                      // 本程序的头部文件
#include "Delay.h"                            // 包含延时函数的头部文件
#include "LCDM_Day_Time.h"                    // 在液晶屏幕上显示日期和时间信息的头部文件


/*
********************************************************************************************
                                     程序指令代码清单
********************************************************************************************
*/
/*==========================================================================================
函数功能:    本函数用于控制蜂鸣器发出声响告警的操作,设定蜂鸣器频率为 200Hz 。
备注:        蜂鸣器设置为相应的控制引脚高电平时,蜂鸣器发出声响。
==========================================================================================*/
void Buzzer(void)
{
  Buzzer_DDR |= Buzzer_PINNum;                // 设置蜂鸣器控制端口为输出引脚
  Buzzer_PORT |= Buzzer_PINNum;               // 打开蜂鸣器
  delay_ms(2);                                // 延时 3ms
  Buzzer_PORT &= ~Buzzer_PINNum;              // 关闭蜂鸣器
}

#ifdef MCU_No_ExtendedParallelBus             // 无扩展并行总线结构单片机的条件编译
/*==========================================================================================
用于无扩展并行总线结构单片机来扩展虚拟并行总线结构,以访问外围器件而添加的额外函数
==========================================================================================*/
/*--------------------------------------------------------------------------------------
函数功能:    本函数用于虚拟扩展并行总线结构的向外围器件写入数据操作。
函数入口参数:AccessAddress ------ 访问的外围器件地址。
              WriteData ---------- 写入的数据。
备注:        本函数仅可访问外围器件的地址数不超过256个。
--------------------------------------------------------------------------------------*/
void VEPB_WriteData(volatile unsigned char AccessAddress, volatile unsigned char WriteData)
{
  VEPB_AD_DDR = 0xFF;                         // 设置虚拟总线地址/数据总线的数据方向为输出
  VEPB_AD_PORT = AccessAddress;               // 写入访问的外围器件地址到总线上
  VEPB_ALE_PORT |= VEPB_ALE_PINNum;           // 地址锁存到外围器件
  VEPB_ALE_PORT &= ~VEPB_ALE_PINNum;
  VEPB_AD_PORT = WriteData;                   // 写入数据
  VEPB_WR_PORT &= ~VEPB_WR_PINNum;            // 使能写入数据
  VEPB_WR_PORT |= VEPB_WR_PINNum;
}

/*--------------------------------------------------------------------------------------
函数功能:    本函数用于虚拟扩展并行总线结构的从外围器件读取数据操作。
函数入口参数:AccessAddress ------ 访问的外围器件地址。
函数出口参数:读取的数据。
备注:        本函数仅可访问外围器件的地址数不超过256个。
--------------------------------------------------------------------------------------*/
unsigned char VEPB_ReadData(volatile unsigned char AccessAddress)
{
  volatile unsigned char temp;                // 出口参数寄存器变量
  VEPB_AD_DDR = 0xFF;                         // 设置虚拟总线地址/数据总线的数据方向为输出
  VEPB_AD_PORT = AccessAddress;               // 写入访问的外围器件地址到总线上
  VEPB_ALE_PORT |= VEPB_ALE_PINNum;           // 地址锁存到外围器件
  VEPB_ALE_PORT &= ~VEPB_ALE_PINNum;
  VEPB_AD_DDR = 0x00;                         // 设置虚拟总线地址/数据总线的数据方向为输入
  VEPB_AD_PORT = 0xFF;                        // 使能虚拟总线地址/数据总线的上拉电阻
  VEPB_RD_PORT &= ~VEPB_RD_PINNum;            // 使能读取数据
  temp = VEPB_AD_PIN;                         // 读取数据
  temp = VEPB_AD_PIN;                         // 加大读取数据脉冲信号的宽度
  VEPB_RD_PORT |= VEPB_RD_PINNum;
  return (temp);
}
#endif                                        // "MCU_No_ExtendedParallelBus" 条件编译结束

/*==========================================================================================
函数功能:    本函数用于外部中断请求0中断向量的初始化操作。
备注:        ①.本函数仅在主函数中调用一次即可。
              ②.要使能中断还必须在主程序中打开全局中断使能功能,推荐其指令如下:
                  SREG |= BIT7;                       / * 使能全局中断 * /
==========================================================================================*/
void external_INT0_initialization(void)
{
/*--------------------------------------------------------------------------------------
目标器件芯片为 ATmega16、ATmega32、ATmega8535 和 ATmega8 外部中断请求0的初始化操作
--------------------------------------------------------------------------------------*/
#if defined(MCU_TYPE_IS_ATMEGA16) || defined(MCU_TYPE_IS_ATMEGA32) || \
    defined(MCU_TYPE_IS_ATMEGA8535) || defined(MCU_TYPE_IS_ATMEGA8)
  register unsigned char temp;                // 临时寄存器变量
  temp = MCUCR;                               // 设置外部中断请求0的触发方式为:下降沿触发
  temp |= ((0<<ISC00)|(1<<ISC01));
  MCUCR = temp;
  temp = GICR;                                // 使能外部中断请求0
  temp |= (1<<INT0);
  GICR = temp;
  temp = GIFR;                                // 外部中断请求0标志位清零
  temp |= (1<<INTF0);
  GIFR = temp;
#endif
/*--------------------------------------------------------------------------------------
目标器件芯片为 ATmega64、ATmega128、ATmega48、ATmega88 和 ATmega168 外部中断请求0的初始化操作
--------------------------------------------------------------------------------------*/
#if defined(MCU_TYPE_IS_ATMEGA64) || defined(MCU_TYPE_IS_ATMEGA128) || \
    defined(MCU_TYPE_IS_ATMEGA48) || defined(MCU_TYPE_IS_ATMEGA88) || \
    defined(MCU_TYPE_IS_ATMEGA168)
  register unsigned char temp;                // 临时寄存器变量
  temp = EICRA;                               // 设置外部中断请求0的触发方式为:下降沿触发
  temp |= ((0<<ISC00)|(1<<ISC01));
  EICRA = temp;
  temp = EIMSK;                               // 使能外部中断请求0
  temp |= (1<<INT0);
  EIMSK = temp;
  temp = EIFR;                                // 外部中断请求0标志位清零
  temp |= (1<<INTF0);
  EIFR = temp;
#endif
}

/*==========================================================================================
函数功能:    本函数用于 DS12887 闹钟中断请求和更新周期结束中断请求处理的中断服务程序。
备注:        ①.注意:由于本函数为中断函数,故在调用和返回时无法进行明式数值传递,
                  因此将在函数体中隐式修改下面这几个全局静态变量数值。
                  ⑴.时间消息的任务变量(tasks_time),用以通知系统执行相应的处理操作。
                  ⑵.系统时间结构变量(time),从 DS12887 中读取更新的系统时间数值。
              ②.本函数需在设置的 DS12887 中断请求的中断向量函数中调用。在调用之前
                  需对该中断向量进行初始化,以使能该中断。例:如使用外部中断请求0,
                  可使用上面提供的 external_INT0_initialization() 函数进行初始化,
                  而将本本函数放在外部中断请求0服务程序中。
==========================================================================================*/
void DS12887_INT_ISR(void)
{
  register unsigned char temp;                // 临时寄存器变量
  register unsigned char temp2;               // 临时寄存器变量2
  DS12887_CS_PORT &= ~DS12887_CS_PINNum;      // 置 DS12887 片选控制引脚为L
#ifdef MCU_No_ExtendedParallelBus             // 无扩展并行总线结构单片机的条件编译
  temp = VEPB_ReadData(DS12887_REG_C);        // 读取 DS12887 寄存器C的内容
#else
  temp = DS12887_REG_C;
#endif                                        // "MCU_No_ExtendedParallelBus" 条件编译结束
  temp2 = temp;
  if ((temp&BIT5)==BIT5)                      // 检查是否为闹钟中断?
    {
      tasks_time |= BIT1;                     // 闹钟告警消息任务位置位
    }
  if ((temp2&BIT4)==BIT4)                     // 检查是否为更新周期结束中断?
    {                                         // 读取 DS12887 中更新的系统时间数值
#ifdef MCU_No_ExtendedParallelBus             // 无扩展并行总线结构单片机的条件编译
      time.BCD_Second = VEPB_ReadData(DS12887_Second);
      time.BCD_Minute = VEPB_ReadData(DS12887_Minute);
      time.BCD_Hour = VEPB_ReadData(DS12887_Hour);
      time.BCD_Date = VEPB_ReadData(DS12887_Date);
      time.BCD_Month = VEPB_ReadData(DS12887_Month);
      time.BCD_Year = VEPB_ReadData(DS12887_Year);
      time.BCD_Year_H = VEPB_ReadData(DS12887_Year_H);
      time.BCD_Week = VEPB_ReadData(DS12887_Week);
#else
      time.BCD_Second = DS12887_Second;
      time.BCD_Minute = DS12887_Minute;
      time.BCD_Hour = DS12887_Hour;
      time.BCD_Date = DS12887_Date;
      time.BCD_Month = DS12887_Month;
      time.BCD_Year = DS12887_Year;
      time.BCD_Year_H = DS12887_Year_H;
      time.BCD_Week = DS12887_Week;
#endif                                        // "MCU_No_ExtendedParallelBus" 条件编译结束
      tasks_time |= BIT0;                     // 时间更新消息任务位置位
    }
  DS12887_CS_PORT |= DS12887_CS_PINNum;       // 置 DS12887 片选控制引脚为H
}

/*==========================================================================================
函数功能:    本函数用于 DS12887 的各控制输入/输出引脚定义和初始状态设置的初始化操作。
备注:        本函数仅在主函数中调用一次即可。
==========================================================================================*/
void RTC_DS12887_initialization(void)
{
  register unsigned char temp;                // 临时寄存器变量
  DS12887_CS_DDR |= DS12887_CS_PINNum;        // 设置 DS12887 片选控制为输出引脚
  DS12887_CS_PORT |= DS12887_CS_PINNum;       // 置 DS12887 片选控制引脚为H
  DS12887_IRQ_DDR &= ~DS12887_IRQ_PINNum;     // 设置 DS12887 中断请求为输入引脚
  DS12887_IRQ_PORT |= DS12887_IRQ_PINNum;     // 使能 DS12887 中断请求引脚的上拉电阻
#ifdef MCU_No_ExtendedParallelBus             // 无扩展并行总线结构单片机的条件编译
  VEPB_ALE_DDR |= VEPB_ALE_PINNum;            // 设置虚拟总线控制线地址锁存使能为输出引脚
  VEPB_ALE_PORT &= ~VEPB_ALE_PINNum;
  VEPB_WR_DDR |= VEPB_WR_PINNum;              // 设置虚拟总线控制线写使能信号为输出引脚
  VEPB_WR_PORT |= VEPB_WR_PINNum;
  VEPB_RD_DDR |= VEPB_RD_PINNum;              // 设置虚拟总线控制线读锁存信号为输出引脚
  VEPB_RD_PORT |= VEPB_RD_PINNum;
  VEPB_AD_DDR = 0x00;                         // 设置虚拟总线地址/数据总线的数据方向为输入
  VEPB_AD_PORT = 0xFF;                        // 使能虚拟总线地址/数据总线的上拉电阻
#else
  MCUCR |= BIT7;                              // 使能外部存储器接口
#endif                                        // "MCU_No_ExtendedParallelBus" 条件编译结束

  DS12887_CS_PORT &= ~DS12887_CS_PINNum;      // 置 DS12887 片选控制引脚为L
#ifdef MCU_No_ExtendedParallelBus             // 无扩展并行总线结构单片机的条件编译
  temp = VEPB_ReadData(DS12887_REG_C);        // 清零 DS12887 寄存器C所有标志位
  VEPB_WriteData(DS12887_REG_A, 0x20);        // 启动晶体振荡器,关闭周期中断方波输出
  temp = VEPB_ReadData(DS12887_REG_B);        // 芯片处于正常工作状态、允许更新周期结束中断、
  temp &= 0x32;                                 // 闹钟中断保持原设置状态、
  temp |= 0x12;                                 // 关闭周期中断、关闭方波输出、
  VEPB_WriteData(DS12887_REG_B, temp);          // 采用 BCD 码数据格式和 24 小时制模式
  temp = VEPB_ReadData(DS12887_REG_D);        // 检查内置电池能量状态?
  if ((temp&BIT7)==0)
  {
    Buzzer();                                 // 如果电池耗尽,系统将进行告警
  }
  VEPB_WriteData(DS12887_Year_H, 0x20);       // 写入年前两位数据为 20
  temp = VEPB_ReadData(DS12887_REG_C);        // 清零 DS12887 寄存器C所有标志位
#else

⌨️ 快捷键说明

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