?? timer.c
字號:
// Copyright (c)2005 - 2006 by Laser Electronics, All Rights Reserved.
/*----------------------------------------------------------------------------+
| File Name: Timer.c, v1.0.1 |
| Author: |
| Date: |
+-----------------------------------------------------------------------------+
| Description: 聯(lián)網(wǎng)型智能樓宇對講系統(tǒng) -- 管理中心機(jī)實(shí)時(shí)時(shí)鐘驅(qū)動程序 |
| 器件選擇 -- STC89C58RD+, PQFP-44 |
| 時(shí)鐘頻率 -- 24.000 MHz |
+-----------------------------------------------------------------------------+
/*----------------------------------------------------------------------------+
| Include files |
+----------------------------------------------------------------------------*/
#include "Main.h"
#include "Timer.h"
#include "LCD.h"
/*----------------------------------------------------------------------------+
| Type Definition & Macro |
+----------------------------------------------------------------------------*/
// 與DS1302通信的管腳
#define SCLK P3_7
#define IO P3_6
#define nRST P3_5
/*----------------------------------------------------------------------------+
| Global Variables |
+----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------+
| Internal Variables |
+----------------------------------------------------------------------------*/
BYTE cSecond; // 0.01秒,初始為0,每次系統(tǒng)滴答一下則加1,加到60以后則向秒進(jìn)位
idata t_Time Time; // 保存當(dāng)前的時(shí)間
idata t_Time TempTime; // 臨時(shí)保存時(shí)間的變量
idata BYTE Hour2Minute; // 小時(shí)和分鐘之間的那個(gè)冒號, 有時(shí)為冒號, 有時(shí)不顯示, 具體在TickCountAdd()中改變
// 定義各個(gè)月份的一個(gè)月的天數(shù),按照BCD碼來排列
code BYTE MonthTable[] = {0x00, 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x30, 0x31};
/*----------------------------------------------------------------------------+
| System Foundation Routines |
+----------------------------------------------------------------------------*/
//
// 復(fù)位DS1302
void DS1302_Reset(void)
{
SCLK = 0; // SCLK must be at a logic 0 when nRST is driven to a logic 1 state
nRST = 0;
nRST = 1;
}
//
// 向DS1302發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
// nData: 需要寫入的數(shù)據(jù)
void DS1302_WriteByte(BYTE nData)
{
BYTE i;
// 最低位在前, 上升沿寫入數(shù)據(jù)
for (i=0; i<8; i++)
{
IO = nData & 0x01;
nData >>= 1;
SCLK = 0;
SCLK = 1;
}
IO = 1;
}
//
// 從DS1302讀取一個(gè)字節(jié)的數(shù)據(jù)
// 返回: 讀到的數(shù)據(jù)
BYTE DS1302_ReadByte(void)
{
BYTE i;
BYTE temp;
temp = 0x00;
// 最低位在前, 下降沿輸出數(shù)據(jù)
for (i=0; i<8; i++)
{
temp >>= 1;
SCLK = 1;
SCLK = 0;
if (IO)
temp |= 0x80;
}
return temp;
}
/*
//
// 向DS1302發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
// Addr: 需要讀取的寄存器的地址, 只有最低5位有效
// nData: 需要寫入的數(shù)據(jù)
BYTE DS1302_ReadData(BYTE Addr)
{
BYTE temp;
Addr <<= 1;
Addr &= 0x3E; // 保留bit1~bit5, 寄存器地址數(shù)據(jù)
Addr |= 0x81; // nCK, nWR
SCLK = 0; // SCLK must be at a logic 0 when nRST is driven to a logic 1 state
nRST = 0;
nRST = 1;
// 地址
DS1302_WriteByte(Addr);
// 數(shù)據(jù)
temp = DS1302_ReadByte();
SCLK = 0;
nRST = 0;
nRST = 1;
SCLK = 1;
IO = 0;
SCLK = 0;
nRST = 0;
return temp;
}
*/
//
// 向DS1302發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
// Addr: 需要寫入的寄存器的地址, 只有最低5位有效
// nData: 需要寫入的數(shù)據(jù)
void DS1302_WriteData(BYTE Addr, BYTE nData)
{
Addr <<= 1;
Addr &= 0x3E; // 保留bit1~bit5, 寄存器地址數(shù)據(jù)
Addr |= 0x80; // nCK, nWR
SCLK = 0; // SCLK must be at a logic 0 when nRST is driven to a logic 1 state
nRST = 0;
nRST = 1;
// 地址
DS1302_WriteByte(Addr);
// 數(shù)據(jù)
DS1302_WriteByte(nData);
SCLK = 0;
nRST = 0;
nRST = 1;
SCLK = 1;
IO = 0;
SCLK = 0;
nRST = 0;
}
/*----------------------------------------------------------------------------+
| System Initialization Routines |
+----------------------------------------------------------------------------*/
//
// 初始化實(shí)時(shí)時(shí)鐘
void InitRealTimer(void)
{
nRST = 0; // 平常nRST保持低電平
Hour2Minute = ':';
cSecond = 0x00;
DS1302_WriteData(0x07, 0x00); // 清除寫保護(hù)位
DS1302_WriteData(0x08, 0xAB); // 選擇電池充電模式, 高4位始終為1010, 選擇2個(gè)二極管串聯(lián), 8KOhm限流電阻
DS1302_ReadTime();
}
/*----------------------------------------------------------------------------+
| General Subroutines |
+----------------------------------------------------------------------------*/
//
// 系統(tǒng)每10ms產(chǎn)生一次中斷,每次中斷之后都調(diào)用這個(gè)函數(shù)使時(shí)間數(shù)據(jù)增加0.01秒
void TickCountAdd(void)
{
cSecond ++;
if (cSecond == 50) // 0.5秒, 更新時(shí)間顯示的冒號
{
Hour2Minute = ' '; // 半秒時(shí)候顯示空字符
// 正常情況下每0.5秒更新一次顯示的時(shí)間
SendMessage(MSG_TIME_DISPLAY);
}
else if (cSecond == 100) // 定時(shí)時(shí)間到了1秒,從DS1302時(shí)鐘芯片中讀取時(shí)間并顯示
{
cSecond = 0;
Hour2Minute = ':';
DS1302_ReadTime();
SendMessage(MSG_TIME_DISPLAY);
}
}
//
// 從時(shí)鐘芯片DS1302中讀取當(dāng)前時(shí)間
void DS1302_ReadTime(void)
{
// Burst Mode Read
DS1302_Reset();
DS1302_WriteByte(0xBF); // clock burst read (eight registers)
Time.Second = DS1302_ReadByte(); // Second
Time.Minute = DS1302_ReadByte();
Time.Hour = DS1302_ReadByte();
Time.Date = DS1302_ReadByte(); //date
Time.Month = DS1302_ReadByte();
DS1302_ReadByte(); // day of week
Time.Year = DS1302_ReadByte();
DS1302_ReadByte(); // must read control register in burst mode
SCLK = 0;
nRST = 0;
nRST = 1;
SCLK = 1;
IO = 0;
SCLK = 0;
nRST = 0;
/*
Time.Second = DS1302_ReadData(0x00);
Time.Minute = DS1302_ReadData(0x01);
Time.Hour = DS1302_ReadData(0x02);
Time.Date = DS1302_ReadData(0x03);
Time.Month = DS1302_ReadData(0x04);
Time.Year = DS1302_ReadData(0x06);
*/
}
//
// 將時(shí)間寫入到DS1302時(shí)鐘芯片中
void DS1302_WriteTime(void)
{
DS1302_WriteData(0x00, 0); // Second
DS1302_WriteData(0x01, Time.Minute);
DS1302_WriteData(0x02, Time.Hour);
DS1302_WriteData(0x03, Time.Date);
DS1302_WriteData(0x04, Time.Month);
DS1302_WriteData(0x06, Time.Year);
}
//
// 更新時(shí)間顯示緩沖, 保存在一個(gè)16位的字符數(shù)組當(dāng)中
void UpdateTimeBuffer(BYTE *Dest)
{
// 格式: "20xx-yy-zz AA:BB"
// 年份, 4位數(shù)
Dest[0] = 0x02+0x30;
Dest[1] = 0x00+0x30;
Dest[2] = (Time.Year >> 4) | 0x30;
Dest[3] = (Time.Year&0x0F) | 0x30;
Dest[4] = '-';
// 月份, 2位數(shù)
Dest[5] = (Time.Month >> 4) | 0x30;
Dest[6] = (Time.Month&0x0F) | 0x30;
Dest[7] = '-';
// 日期, 2位數(shù)
Dest[8] = (Time.Date >> 4) | 0x30;
Dest[9] = (Time.Date&0x0F) | 0x30;
Dest[10] = 0x20; // 空格
// 小時(shí), 2位數(shù)
Dest[11] = (Time.Hour >> 4) | 0x30;
Dest[12] = (Time.Hour&0x0F) | 0x30;
Dest[13] = Hour2Minute;
// 分鐘, 2位數(shù)
Dest[14] = (Time.Minute >> 4) | 0x30;
Dest[15] = (Time.Minute&0x0F) | 0x30;
}
/*----------------------------------------------------------------------------+
| 有關(guān)日歷的函數(shù)
+----------------------------------------------------------------------------*/
//
// 修改時(shí)間并且將新的時(shí)間寫入到時(shí)鐘芯片DS1302中
// pDate: 一個(gè)指向保存有時(shí)間信息的字符串的指針,依次為年、月、日、小時(shí)、分、秒
BOOL ModifyTime(BYTE *pDate)
{
// 先判斷輸入是否正確
if (CheckBufferTime(pDate))
{
// 將得到的時(shí)間寫入到DS1302中
Time.Year = TempTime.Year;
Time.Month = TempTime.Month;
Time.Date = TempTime.Date;
Time.Hour = TempTime.Hour;
Time.Minute = TempTime.Minute;
Time.Second = 0x00;
DS1302_WriteTime();
return TRUE;
}
return FALSE;
}
//
// 判斷緩沖區(qū)中輸入的時(shí)間是否正確
BOOL CheckBufferTime(BYTE *pDate)
{
BYTE temp;
// 年
temp = pDate[0] << 4;
temp += pDate[1];
if (temp > 0x99)
{
return FALSE;
}
TempTime.Year = temp;
// 月
temp = pDate[2] << 4;
temp += pDate[3];
if ((temp > 0x12) || (temp == 0x00))
{
return FALSE;
}
TempTime.Month = temp;
// 日
temp = pDate[4] << 4;
temp += pDate[5];
if ((temp > MonthTable[TempTime.Month]) || (temp == 0x00))
{
if (TempTime.Month == 0x02) // 如果是閏年的二月, 則又多出一天
{
if (IsLeapYear(TempTime.Year))
{
if (temp > 0x29) // 閏年二月, 超過了29天
{
return FALSE;
}
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
TempTime.Date = temp;
// 小時(shí)
temp = pDate[6] << 4;
temp += pDate[7];
if (temp > 0x24)
{
return FALSE;
}
TempTime.Hour = temp;
// 分
temp = pDate[8] << 4;
temp += pDate[9];
if (temp > 0x59)
{
return FALSE;
}
TempTime.Minute = temp;
return TRUE;
}
//
// 判斷是否是閏年, 閏年2月為29天, 這一年為366天
// year: BCD碼表示的年份的低2位, 如0x15表示2015年
BOOL IsLeapYear(BYTE year)
{
UINT temp;
temp = year & 0xF0; // 年份的十位數(shù)
temp *= 10;
temp += (year & 0x0F);
temp += 2000;
if ((!(temp % 4) && (temp % 100)) || !(temp % 400))
{
return TRUE;
}
return FALSE;
}
/*----------------------------------------------------------------------------+
| End of source file |
+----------------------------------------------------------------------------*/
/*------------------------ Nothing Below This Line --------------------------*/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -