|
單片機(jī)C語言實(shí)例-199-時(shí)鐘DS1302(LCD)
/********************************************************************
* 文件名 : 時(shí)鐘DS1302LCD.c
* 描述 : 該文件實(shí)現(xiàn)用DS1302來實(shí)現(xiàn)日歷和時(shí)鐘功能,液晶1602上顯示出來。
* 創(chuàng)建人 : 東流,2009年4月10日
* 版本號(hào) : 2.0
***********************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit T_CLK = P1^6; /*實(shí)時(shí)時(shí)鐘時(shí)鐘線引腳 */
sbit T_IO = P3^5; /*實(shí)時(shí)時(shí)鐘數(shù)據(jù)線引腳 */
sbit T_RST = P1^7; /*實(shí)時(shí)時(shí)鐘復(fù)位線引腳 */
//這三個(gè)引腳參考資料
sbit E=P2^7; //1602使能引腳
sbit RW=P2^6; //1602讀寫引腳
sbit RS=P2^5; //1602數(shù)據(jù)/命令選擇引腳
/********************************************************************
* 名稱 : delay()
* 功能 : 延時(shí),延時(shí)時(shí)間大概為140US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++)
;
}
/********************************************************************
* 名稱 : enable(uchar del)
* 功能 : 1602命令函數(shù)
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
void enable(uchar del)
{
P0 = del;
RS = 0;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/********************************************************************
* 名稱 : write(uchar del)
* 功能 : 1602寫數(shù)據(jù)函數(shù)
* 輸入 : 需要寫入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void write(uchar del)
{
P0 = del;
RS = 1;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/********************************************************************
* 名稱 : L1602_init()
* 功能 : 1602初始化,請(qǐng)參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}
/********************************************************************
* 名稱 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符顯示"b" ,調(diào)用該函數(shù)如下
L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
/********************************************************************
* 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
/********************************************************************
* 名稱 : v_RTInputByte()
* 功能 : 往DS1302寫入1Byte數(shù)據(jù)
* 輸入 : ucDa 寫入的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
T_RST = 1;
for(i=8; i>0; i--)
{
T_IO = ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
* 名稱 : uc_RTOutputByte()
* 功能 : 從DS1302讀取1Byte數(shù)據(jù)
* 輸入 : 無
* 返回值: ACC
***********************************************************************/
uchar uc_RTOutputByte(void)
{
uchar i;
T_RST = 1;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
T_IO=1;
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
* 名稱 : v_W1302(uchar ucAddr, uchar ucDa)
* 功能 : 往DS1302寫入數(shù)據(jù)
* 輸入 : ucAddr: DS1302地址, ucDa: 要寫的數(shù)據(jù)
* 返回值 : 無
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); // 寫地址
_nop_();
_nop_();
v_RTInputByte(ucDa); // 寫1Byte數(shù)據(jù)
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
* 名稱 : uc_R1302(uchar ucAddr)
* 功能 : 讀取DS1302某地址的數(shù)據(jù)
* 輸入 : ucAddr: DS1302地址
* 返回值 : ucDa :讀取的數(shù)據(jù)
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); //寫地址,命令
_nop_();
_nop_();
ucDa = uc_RTOutputByte(); //讀1Byte數(shù)據(jù)
T_CLK = 1;
T_RST = 0;
return(ucDa);
}
/********************************************************************
* 名稱 : v_BurstW1302T
* 功能 : 往DS1302寫入時(shí)鐘數(shù)據(jù)(多字節(jié)方式)
* 輸入 : pSecDa: 時(shí)鐘數(shù)據(jù)地址 格式為: 秒 分 時(shí) 日 月 星期 年 控制
* 8Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B 1B
* 返回值 : 無
***********************************************************************/
void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e, 0x00); //控制命令,WP=0,寫操作
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbe); //0xbe:時(shí)鐘多字節(jié)寫命令
for(i=8; i>0; i--) //8Byte = 7Byte 時(shí)鐘數(shù)據(jù) + 1Byte 控制
{
v_RTInputByte(*pSecDa); //寫1Byte數(shù)據(jù)
pSecDa++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
* 名稱 : v_BurstR1302T(uchar *pSecDa)
* 功能 : 讀取DS1302時(shí)鐘數(shù)據(jù)
* 輸入 : pSecDa: 時(shí)鐘數(shù)據(jù)地址 格式為: 秒 分 時(shí) 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值 : ucDa :讀取的數(shù)據(jù)
***********************************************************************/
void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf); //0xbf:時(shí)鐘多字節(jié)讀命令
for(i=8; i>0; i--)
{
*pSecDa = uc_RTOutputByte(); //讀1Byte數(shù)據(jù)
pSecDa++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
* 名稱 : v_BurstW1302R(uchar *pReDa)
* 功能 : 往DS1302寄存器數(shù)寫入數(shù)據(jù)(多字節(jié)方式)
* 輸入 : pReDa: 寄存器數(shù)據(jù)地址
* 返回值 : 無
***********************************************************************/
void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e,0x00); //控制命令,WP=0,寫操作
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe); //0xbe:時(shí)鐘多字節(jié)寫命令
for(i=31; i>0; i--) //31Byte 寄存器數(shù)據(jù)
{
v_RTInputByte(*pReDa); //寫1Byte數(shù)據(jù)
pReDa++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
* 名稱 : v_BurstR1302R(uchar *pReDa)
* 功能 : 讀取DS1302寄存器數(shù)據(jù)
* 輸入 : pReDa: 寄存器數(shù)據(jù)地址
* 返回值 : 無
***********************************************************************/
void v_BurstR1302R(uchar *pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xff); //0xbf:時(shí)鐘多字節(jié)讀命令
for(i=31; i>0; i--) //31Byte 寄存器數(shù)據(jù)
{
*pReDa = uc_RTOutputByte(); //讀1Byte數(shù)據(jù)
pReDa++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
* 名稱 : v_Set1302(uchar *pSecDa)
* 功能 : 設(shè)置初始時(shí)間
* 輸入 : pSecDa: 初始時(shí)間地址。初始時(shí)間格式為: 秒 分 時(shí) 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 無
***********************************************************************/
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e, 0x00); //控制命令,WP=0,寫操作
for(i=7; i>0; i--)
{
v_W1302(ucAddr, *pSecDa); // 秒 分 時(shí) 日 月 星期 年
pSecDa++;
ucAddr += 2;
}
v_W1302(0x8e, 0x80); //控制命令,WP=1,寫保護(hù)
}
/********************************************************************
* 名稱 : v_Get1302(uchar ucCurtime[])
* 功能 : 讀取DS1302當(dāng)前時(shí)間
* 輸入 : ucCurtime: 保存當(dāng)前時(shí)間地址。當(dāng)前時(shí)間格式為: 秒 分 時(shí) 日 月 星期 年
* 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
* 返回值 : 無
***********************************************************************/
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for(i=0; i<7; i++)
{
ucCurtime = uc_R1302(ucAddr); //格式為: 秒 分 時(shí) 日 月 星期 年
ucAddr += 2;
}
}
/********************************************************************
* 名稱 : dectobcd(uchar dec)
* 功能 : DEC碼轉(zhuǎn)換為BCD碼
* 輸入 : dec碼
* 輸出 : bcd碼
***********************************************************************/
uchar dectobcd(uchar dec)
{
uchar bcd;
bcd = 0;
while(dec >= 10)
{
dec -= 10;
bcd++;
}
bcd <<= 4;
bcd |= dec;
return bcd;
}
/********************************************************************
* 名稱 : bcdtodec(uchar bcd)
* 功能 : BCD碼轉(zhuǎn)換為DEC碼
* 輸入 : bcd碼
* 輸出 : dec碼
***********************************************************************/
uchar bcdtodec(uchar bcd)
{
uchar data1;
data1 = bcd & 0x0f; //取BCD低4位
bcd = bcd & 0x70; //剔除BCD的最高位和低4位。
data1 += bcd >> 1;
data1 += bcd >> 3; //用位移代替乘法運(yùn)算
return data1;
}
/********************************************************************
* 名稱 : Write_DS1302Init()
* 功能 : 往DS1302中寫入數(shù)據(jù)。最開始顯示的數(shù)據(jù)就是在這里設(shè)置的。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Write_DS1302Init(void)
{
v_W1302(0x8e,0);
v_W1302(0x80,0x50); //寫入秒
v_W1302(0x8e,0);
v_W1302(0x82,0x59); //寫入分
v_W1302(0x8e,0);
v_W1302(0x84,0x07); //寫入小時(shí)
v_W1302(0x8e,0);
v_W1302(0x86,0x08); //寫入日
v_W1302(0x8e,0);
v_W1302(0x88,0x08); //寫入月
v_W1302(0x8e,0);
v_W1302(0x8a,0x05); //寫入星期
v_W1302(0x8e,0);
v_W1302(0x8c,0x08); //寫入年
}
/********************************************************************
* 名稱 : Run_DS1302(void)
* 功能 : 讀出DS1302中的數(shù)據(jù),并在液晶1602上進(jìn)行顯示
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Run_DS1302(void)
{
uchar sec, min, hour, day, month, year;
while(1)
{
v_W1302(0x8f, 0);
sec = bcdtodec(uc_R1302(0x81)); //讀出DS1302中的秒
v_W1302(0x8f, 0);
min = bcdtodec(uc_R1302(0x83)); //讀出DS1302中的分
v_W1302(0x8f, 0);
hour = bcdtodec(uc_R1302(0x85)); //讀出DS1302中的小時(shí)
v_W1302(0x8f, 0);
day = bcdtodec(uc_R1302(0x87)); //讀出DS1302中的日
v_W1302(0x8f, 0);
month = bcdtodec(uc_R1302(0x89)); //讀出DS1302中的月
v_W1302(0x8f, 0);
year = bcdtodec(uc_R1302(0x8d)); //讀出DS1302中的年
L1602_char(2, 6, hour / 10 % 10 + 48);
L1602_char(2, 7, hour % 10 + 48);
L1602_char(2, 8, '-');
L1602_char(2, 9, min / 10 % 10 + 48);
L1602_char(2, 10, min % 10 + 48);
L1602_char(2, 11, '-');
L1602_char(2, 12, sec / 10 % 10 + 48);
L1602_char(2, 13, sec % 10 + 48);
L1602_char(1, 8, year / 10 % 10 + 48);
L1602_char(1, 9, year % 10 + 48);
L1602_char(1, 10, '-');
L1602_char(1, 11, month / 10 % 10 + 48);
L1602_char(1, 12, month % 10 + 48);
L1602_char(1, 13, '-');
L1602_char(1, 14, day / 10 % 10 + 48);
L1602_char(1, 15, day % 10 + 48);
}
}
/********************************************************************
* 名稱 : Main(void)
* 功能 : 主函數(shù)
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Main(void)
{
L1602_init();
L1602_string(1,1,"DAYS 20");
L1602_string(2,1,"TIME");
Write_DS1302Init();
Run_DS1302();
}
更多詳情參考附件文檔
+08:00C127聯(lián)盟網(wǎng)9869.png (43.08 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
2022-2-18 10:04 上傳
游客,如果您要查看本帖隱藏內(nèi)容請(qǐng) 回復(fù)
|
|