#include <msp430x14x.h>
typedef unsigned char uchar;
typedef unsigned int uint;
/**************宏定義***************/
#define DataDir P4DIR
#define DataPort P4OUT
#define Busy 0x80
#define CtrlDir P3DIR
#define CLR_RS P3OUT&=~BIT0; //RS = P3.0
#define SET_RS P3OUT|=BIT0;
#define CLR_RW P3OUT&=~BIT1; //RW = P3.1
#define SET_RW P3OUT|=BIT1;
#define CLR_EN P3OUT&=~BIT2; //EN = P3.2
#define SET_EN P3OUT|=BIT2;
/**************宏定義***************/
#define DS_RST BIT7 //DS_RST = P2.7
#define DS_SCL BIT5 //DS_SCL = P2.5
#define DS_SDA BIT6 //DS_SDA = P2.6
#define DS_RST_IN P2DIR &= ~DS_RST
#define DS_RST_OUT P2DIR |= DS_RST
#define DS_RST0 P2OUT &= ~DS_RST
#define DS_RST1 P2OUT |= DS_RST
#define DS_SCL_IN P2DIR &= ~DS_SCL
#define DS_SCL_OUT P2DIR |= DS_SCL
#define DS_SCL0 P2OUT &= ~DS_SCL
#define DS_SCL1 P2OUT |= DS_SCL
#define DS_SDA_IN P2DIR &= ~DS_SDA
#define DS_SDA_OUT P2DIR |= DS_SDA
#define DS_SDA0 P2OUT &= ~DS_SDA
#define DS_SDA1 P2OUT |= DS_SDA
#define DS_SDA_BIT P2IN & DS_SDA
uchar flag;//定義一個(gè)讀標(biāo)志位
uchar second,minute,hour,week,day,month,year;//秒、分、時(shí)、星期、日、月、年
/*******************************************
函數(shù)名稱(chēng):delay
功 能:延時(shí)一段時(shí)間
參 數(shù):time--延時(shí)長(zhǎng)度
********************************************/
void delay(uint time)
{
uint i;
for(i = 0;i < time;i++) _NOP();
}
/*******************************************
函數(shù)名稱(chēng):Delay5ms 功 能:延時(shí)約5ms
********************************************/
void Delay5ms(void)
{
uint i=40000;
while (i != 0)
{
i--;
}
}
/*******************************************
函數(shù)名稱(chēng):WaitForEnable
功 能:等待1602液晶完成內(nèi)部操作
********************************************/
void WaitForEnable(void)
{
P4DIR &= 0x00; //將P4口切換為輸入狀態(tài)
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
while((P4IN & Busy)!=0); //檢測(cè)忙標(biāo)志
CLR_EN;
P4DIR |= 0xFF; //將P4口切換為輸出狀態(tài)
}
/*******************************************
函數(shù)名稱(chēng):write_com
功 能:向液晶模塊寫(xiě)入命令
********************************************/
void write_com(uchar cmd)
{
WaitForEnable(); // 檢測(cè)忙信號(hào)?
CLR_RS;
CLR_RW;
_NOP();
DataPort = cmd; //將命令字寫(xiě)入數(shù)據(jù)端口
_NOP();
SET_EN; //產(chǎn)生使能脈沖信號(hào)
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函數(shù)名稱(chēng):write_data
功 能:向液晶顯示的當(dāng)前地址寫(xiě)入顯示數(shù)據(jù)
參 數(shù):data--顯示字符數(shù)據(jù)
返回值 :無(wú)
********************************************/
void write_data( uchar data )
{
WaitForEnable(); //等待液晶不忙
SET_RS;
CLR_RW;
_NOP();
DataPort = data; //將顯示數(shù)據(jù)寫(xiě)入數(shù)據(jù)端口
_NOP();
SET_EN; //產(chǎn)生使能脈沖信號(hào)
_NOP();
_NOP();
CLR_EN;
}
void Write1602(uchar add,uchar dat)
{
write_com(add);
write_data(dat);
}
void zifuchuan(uchar *ch)
{
while(*ch!=0)
write_data(*ch++);
Delay5ms();
}
/*******************************************
函數(shù)名稱(chēng):LcdReset
功 能:對(duì)1602液晶模塊進(jìn)行復(fù)位操作
********************************************/
void LcdReset(void)
{
CtrlDir |= 0x07; //控制線端口設(shè)為輸出狀態(tài)
DataDir = 0xFF; //數(shù)據(jù)端口設(shè)為輸出狀態(tài)
write_com(0x38);//規(guī)定的復(fù)位操作
Delay5ms();
write_com(0x38);
Delay5ms();
write_com(0x38);
Delay5ms();
write_com(0x38);//顯示模式設(shè)置
write_com(0x06);//寫(xiě)字符時(shí)整體不移動(dòng)
write_com(0x0c);//顯示開(kāi),不開(kāi)游標(biāo),不閃爍
write_com(0x01);//顯示清屏
Write1602(0x80,'2');
Write1602(0x81,'0');
Write1602(0x80+4,'-');
Write1602(0x80+7,'-');
Write1602(0x80+0x40+5,':');
Write1602(0x80+0x40+8,':');
}
/*******************************************
函數(shù)名稱(chēng):Reset_DS1302
功 能:對(duì)DS1302進(jìn)行復(fù)位操作
********************************************/
void Reset_DS1302(void)
{
DS_RST_OUT; //RST對(duì)應(yīng)的IO設(shè)置為輸出狀態(tài)
DS_SCL_OUT; //SCLK對(duì)應(yīng)的IO設(shè)置為輸出狀態(tài)
DS_SCL0; //SCLK=0
DS_RST0; //RST=0
delay(10);
DS_SCL1; //SCLK=1
}
/*******************************************
函數(shù)名稱(chēng):Write1Byte
功 能:對(duì)DS1302寫(xiě)入1個(gè)字節(jié)的數(shù)據(jù)
********************************************/
void Write_Byte(uchar wdata)
{
uchar i;
DS_SDA_OUT; //SDA對(duì)應(yīng)的IO設(shè)置為輸出狀態(tài)
DS_RST1; //REST=1;
for(i = 8; i > 0; i--)
{
if(wdata&0x01)
DS_SDA1;
else
DS_SDA0;
DS_SCL0;
delay(10);
DS_SCL1;
delay(10);
wdata >>= 1;
}
}
/*******************************************
函數(shù)名稱(chēng):Read1Byte
功 能:從DS1302讀出1個(gè)字節(jié)的數(shù)據(jù)
********************************************/
uchar Read_Byte()
{
uchar i;
uchar rdata = 0X00;
DS_SDA_IN; //SDA對(duì)應(yīng)的IO設(shè)置為輸入狀態(tài)
DS_RST1; //REST=1;
for(i = 8; i > 0; i--)
{
DS_SCL1;
delay(10);
DS_SCL0;
delay(10);
rdata >>= 1;
if(DS_SDA_BIT)
rdata |= 0x80;
}
return(rdata);
}
/*******************************************
函數(shù)名稱(chēng):Write_dat
功 能:向某個(gè)寄存器寫(xiě)入一個(gè)字節(jié)數(shù)據(jù)
參 數(shù):add--寄存器地址
dat--寫(xiě)入的數(shù)據(jù)
********************************************/
void Write_dat(uchar add, uchar dat)
{
DS_RST0;
DS_SCL0;
_NOP();
DS_RST1;
Write_Byte(add); //寫(xiě)入地址
Write_Byte(dat); //寫(xiě)入數(shù)據(jù)
DS_SCL1;
DS_RST0;
}
/*******************************************
函數(shù)名稱(chēng):Read_dat
功 能:從某個(gè)寄存器讀出一個(gè)字節(jié)數(shù)據(jù)
參 數(shù):addr--寄存器地址
返回值 :讀出的數(shù)據(jù)
********************************************/
uchar read_1302add(uchar add)
{
uchar rdata;
DS_RST0;
DS_SCL0;
_NOP();
DS_RST1;
Write_Byte(add); //寫(xiě)入地址
rdata = Read_Byte(); //讀出數(shù)據(jù)
DS_SCL1;
DS_RST0;
return(rdata);
}
/***********初始化1302*************/
void init_1302()
{
flag=read_1302add(0x81);//讀秒寄存器最高位,讀出時(shí)鐘狀態(tài)
if(flag&0x80);//判斷時(shí)鐘是否關(guān)閉,若內(nèi)部關(guān)閉,則初始化,否則繼續(xù)走
{
Write_dat(0x8e,0x00);
Write_dat(0x80,((55/10)<<4|(55%10)));//寫(xiě)秒寄存器,并寫(xiě)入初值55
Write_dat(0x82,((59/10)<<4|(59%10)));//寫(xiě)分寄存器,并寫(xiě)入初值59
Write_dat(0x84,((22/10)<<4|(22%10)));//寫(xiě)小時(shí)寄存器,并寫(xiě)入初值23
Write_dat(0x86,((24/10)<<4|(24%10)));//寫(xiě)日寄存器,并寫(xiě)入初值18
Write_dat(0x88,((2/10)<<4|(2%10)));//寫(xiě)月寄存器,并寫(xiě)入初值2
Write_dat(0x8a,((5/10)<<4|(5%10)));//寫(xiě)周寄存器,并寫(xiě)入初值5
Write_dat(0x8c,((12/10)<<4|(12%10)));//寫(xiě)年寄存器,并寫(xiě)入初值12,不能寫(xiě)2012年
Write_dat(0x90,0xa5);//寫(xiě)充電方式
Write_dat(0x8e,0x80);//加上寫(xiě)保護(hù)
}
}
/*****************讀出秒的十進(jìn)制數(shù)***************************/
uchar readsecond()
{
uchar dat;
dat=read_1302add(0x81);
second=((dat&0x70)>>4)*10+(dat&0x0f);
return second;
}
/*****************讀出分的十進(jìn)制數(shù)***************************/
uchar readminute()
{
uchar dat;
dat=read_1302add(0x83);
minute=((dat&0x70)>>4)*10+(dat&0x0f);
return minute;
}
/*****************讀出小時(shí)的十進(jìn)制數(shù)***************************/
uchar readhour()
{
uchar dat;
dat=read_1302add(0x85);
hour=((dat&0x70)>>4)*10+(dat&0x0f);
return hour;
}
/*****************讀出天的十進(jìn)制數(shù)***************************/
uchar readday()
{
uchar dat;
dat=read_1302add(0x87);
day=((dat&0x70)>>4)*10+(dat&0x0f);
return day;
}
/*****************讀出月的十進(jìn)制數(shù)***************************/
uchar readmonth()
{
uchar dat;
dat=read_1302add(0x89);
month=((dat&0x70)>>4)*10+(dat&0x0f);
return month;
}
/*****************讀出周的十進(jìn)制數(shù)***************************/
uchar readweek()
{
uchar dat;
dat=read_1302add(0x8b);
week=((dat&0x70)>>4)*10+(dat&0x0f);
return week;
}
/*****************讀出年的十進(jìn)制數(shù)***************************/
uchar readyear()
{
uchar dat;
dat=read_1302add(0x8d);
year=((dat&0xf0)>>4)*10+(dat&0x0f);
return year;
}
/************************讀出所有時(shí)間**********************/
void readtime()
{
readsecond();
readminute();
readhour();
readday();
readmonth();
readweek();
readyear();
}
/*********************向1602寫(xiě)入時(shí)間****************************/
void write_second()
{
uchar shi,ge;
shi=second/10;
ge=second%10;
Write1602(0x80+0x40+9,0x30+shi);
Write1602(0x80+0x40+10,0x30+ge);
}
void write_minute()
{
uchar shi,ge;
shi=minute/10;
ge=minute%10;
Write1602(0x80+0x40+6,0x30+shi);
Write1602(0x80+0x40+7,0x30+ge);
}
void write_hour()
{
uchar shi,ge;
shi=hour/10;
ge=hour%10;
Write1602(0x80+0x40+3,0x30+shi);
Write1602(0x80+0x40+4,0x30+ge);
}
void write_day()
{
uchar shi,ge;
shi=day/10;
ge=day%10;
Write1602(0x80+8,0x30+shi);
Write1602(0x80+9,0x30+ge);
}
void write_month()
{
uchar shi,ge;
shi=month/10;
ge=month%10;
Write1602(0x80+5,0x30+shi);
Write1602(0x80+6,0x30+ge);
}
void write_year()
{
uchar shi,ge;
shi=year/10;
ge=year%10;
Write1602(0x80+2,0x30+shi);
Write1602(0x80+3,0x30+ge);
}
void write_week()
{
Write1602(0x80+12,0x30+week);
//uchar week;
switch(week)
{
case 1: Write1602(0x80+12,'M');
Write1602(0x80+13,'O');
Write1602(0x80+14,'N');
break;
case 2:Write1602(0x80+12,'T');
Write1602(0x80+13,'U');
Write1602(0x80+14,'E');
break;
case 3:Write1602(0x80+12,'W');
Write1602(0x80+13,'E');
Write1602(0x80+14,'N');
break;
case 4:Write1602(0x80+12,'T');
Write1602(0x80+13,'H');
Write1602(0x80+14,'U');
break;
case 5:Write1602(0x80+12,'F');
Write1602(0x80+13,'R');
Write1602(0x80+14,'I');
break;
case 6:Write1602(0x80+12,'S');
Write1602(0x80+13,'A');
Write1602(0x80+14,'T');
break;
case 7:Write1602(0x80+12,'S');
Write1602(0x80+13,'U');
Write1602(0x80+14,'N');
break;
}
}
/*************************主函數(shù)*************************/
void main( void )
{
/*下面六行程序關(guān)閉所有的IO口*/
P1DIR = 0XFF;P1OUT = 0XFF;
P2DIR = 0XFF;P2OUT = 0XFF;
P3DIR = 0XFF;P3OUT = 0XFF;
P4DIR = 0XFF;P4OUT = 0XFF;
P5DIR = 0XFF;P5OUT = 0XFF;
P6DIR = 0XFF;P6OUT = 0XFF;
WDTCTL = WDTPW + WDTHOLD; //關(guān)狗
LcdReset();
//zifuchuan("The time is:");
//循環(huán)讀數(shù)顯示
init_1302();
while(1)
{
readtime();
write_second();
write_minute();
write_hour();
write_day();
write_month();
write_year();
write_week();
}
}