📄 rtc_ds12887.c
字号:
/*
********************************************************************************************
源程序文件名: 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 + -