#include<pic.h> //包含單片機內部資源預定義
__CONFIG(0x1832);
//芯片配置字,看門狗關,上電延時開,掉電檢測關,低壓編程關,加密,4M晶體HS振蕩
#define i_o RB4 //定義DS1302的數據口
#define sclk RB0 //定義DS1302的時鐘口
#define rst RB5 //定義DS1302的復位口
// unsigned char time_rx;
unsigned char time_rx @ 0x30; //定義接收寄存器
static volatile bit time_rx7 @ (unsigned)&time_rx*8+7; //接收寄存器的最高位
//static volatile bit temp0 @ (unsigned)&temp*8+0;
void port_init(); //申明引腳初始化函數
void ds1302_init(); //申明DS1302初始化函數
void set_time(); //申明設置時間函數
void get_time(); //申明讀取時間函數
void display(); //申明顯示函數
void time_write_1(unsigned char time_tx); //申明寫壹個字節函數
unsigned char time_read_1(); //申明讀壹個字節函數
void delay(); //申明延時函數
//定義待設置的時間: 秒、 分、 時、 日、月、星期、年、控制字
const char table[]={0x00,0x58,0x12,0x8,0x3,0x06,0x06,0x00};
//定義讀取時間和日期存放表格
char table1[7];
//定義0-9的顯示代碼
const char table2[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//----------------------------------------------
//主函數
void main()
{
port_init(); //調用引腳初始化函數
ds1302_init(); //調用DS1302初始化函數
set_time(); //調用設置時間函數
while(1)
{
get_time(); //調用取時間函數
display(); //調用顯示函數
}
}
//---------------------------------------------
//DS1302初始化函數
void ds1302_init()
{
sclk=0; //拉低時鐘信號
rst =0; //復位DS1302
rst=1; //使能DS1302
time_write_1(0x8e); //發控制命令
time_write_1(0); //允許寫DS1302
rst=0; //復位
}
//---------------------------------------------
//設置時間函數
void set_time()
{
int i; //定義循環變量
rst=1; //使能DS1302
time_write_1(0xbe); //時鐘多字節寫命令
for(i=0;i<8;i++) //連續寫8個字節數據
{
time_write_1(table[i]); //調用寫壹個字節函數
}
rst=0; //復位
}
//---------------------------------------------
//讀取時間函數
void get_time()
{
int i; //設置循環變量
rst=1; //使能DS1302
time_write_1(0xbf); //發送多字節讀取命令
for(i=0;i<7;i++) //連續讀取7個字節數據
{
table1[i]=time_read_1(); //調用讀取1個字節數據的函數
}
rst=0; //復位DS1302
}
//--------------------------------------------
//寫壹個字節數據函數
void time_write_1(unsigned char time_tx)
{
int j; //設置循環變量
for(j=0;j<8;j++) //連續寫8bit
{
i_o=0; //先設置數據為0
sclk=0; //時鐘信號拉低
if(time_tx&0x01) //判斷待發送的數據位是0或1
{
i_o=1; //待發送數據位是1
}
time_tx=time_tx>>1; //待發送的數據右移1位
sclk=1; //拉高時鐘信號
}
sclk=0; //寫完壹個字節,拉低時鐘信號
}
//---------------------------------------------
//讀壹個字節函數
unsigned char time_read_1()
{
int j; //設置循環變量
TRISB4=1; //設置數據口方向為輸入
for(j=0;j<8;j++) //連續讀取8bit
{
sclk=0; //拉低時鐘信號
time_rx=time_rx>>1; //接收寄存器右移1位
time_rx7=i_o; //把接收到的數據放到接收寄存器的最高位
sclk=1; //拉高時鐘信號
}
TRISB4=0; //恢復數據口方向為輸出
sclk=0; //拉低時鐘信號
return(time_rx); //返回讀取到的數據
}
//--------------------------------------------
//引腳定義函數
void port_init()
{
TRISA=0x00; //設置A口全輸出
TRISD=0X00; //設置D口全輸出
ADCON1=0X06; //設置A口為普通I/O口
TRISB=0X02; //設置RB1為輸入,其他為輸出
OPTION=0X00; //開啟B口弱上拉
PORTA=0XFF;
PORTD=0XFF; //先熄滅所有顯示
}
//-------------------------------------------
//顯示函數
void display()
{
int i; //定義查表變量
if(RB1==0) //判斷RB1是否按下,如果按下的話顯示日期,不按下顯示時間
{
table1[0]=table1[3];
table1[1]=table1[4];
table1[2]=table1[6];
}
i=table1[0]&0x0f; //求秒的個位
PORTD=table2[i]; //送D口顯示
PORTA=0x1f; //點亮秒的個位
delay(); //延長壹段時間,保證亮度
i=table1[0]&0xf0; //求秒的十位
i=i>>4; //右移4位
PORTD=table2[i]; //送D口顯示
PORTA=0x2f; //點亮秒的十位
delay(); //延長壹段時間,保證亮度
i=table1[1]&0x0f; //求分的個位
PORTD=table2[i]&0x7f; //送D口顯示,並顯示小數點
PORTA=0x37; //點亮分的個位
delay(); //延時壹定時間,保證亮度
i=table1[1]&0xf0; //求分的十位
i=i>>4;
PORTD=table2[i]; //送D口顯示
PORTA=0x3b; //點亮分的十位
delay(); //延長壹段時間,保證亮度
i=table1[2]&0x0f; //求時的個位
PORTD=table2[i]&0x7f; //送D口顯示,並加上小數點
PORTA=0x3d; //點亮時的個位
delay(); //延時壹定時間,保證亮度
i=table1[2]&0xf0; //求時的十位
i=i>>4;
PORTD=table2[i]; //送D口顯示
PORTA=0x3e; //點亮時的十位
delay(); //延長壹段時間,保證亮度
}
//------------------------------------------------------------------
//延時程序
void delay() //延時程序
{
int i; //定義整形變量
for(i=0x64;i--;); //延時
}