專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

MSP430與DS1302之1602顯示

作者:我行天下   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年03月30日   【字體:

#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();
 
     }
}

關(guān)閉窗口

相關(guān)文章