專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

AT89s51-AT24c02記憶秒表計時實驗

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2011年07月06日   【字體:

 夜深了,我要的就是這種困意。白天睡覺,晚上學習。突然茫然了一下,彭宗敏說他最后會下定決心準備高考是為了計算機。

        我當初為了什么,也許是有答案的,不經(jīng)意的發(fā)現(xiàn),早在高二時候,我就確定我以后讀電子信息類的。路既然沒錯,就不要有任何后悔的走下去!
 


 

/**********************************************
 《郭天祥新概念51單片機》P188,有改動。
    利用定時器產(chǎn)生0-99計時秒表,每過1秒,將計數(shù)的
的數(shù)值寫入AT24c02,關閉電源再打開,單片機將原來
寫入的值讀出來,接著此數(shù)繼續(xù)按秒變化,并顯示在
數(shù)碼管上
**********************************************/
/**********************************************
數(shù)碼管顯示:
  數(shù)據(jù)P0 段選P2^6  位選 P2^7 
AT24C02:
  地址設置為1010111x  x為0表示寫  x為1表示讀
  SDA==P2^0  SCL==P2^1  WP接GND(表示允許讀/寫)
**********************************************/

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
bit  write=0;    //寫24C02的標志;
sbit sda=P2^0;                         
sbit scl=P2^1;
sbit dula=P2^6;
sbit wela=P2^7;
uchar sec,tcnt; 
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/*******************************************
                延時函數(shù)
*******************************************/
void delay()
{ ;; }

void delay1ms(uint z)
{
   uint x,y;
   for(x=z;x>0;x--)
    for(y=120;y>0;y--);
}

/*******************************************
                開始信號
*******************************************/
void start()  
{ 
 sda=1;
 delay();
 scl=1;
 delay();
 sda=0;
 delay();
}

/*******************************************
                停止信號
*******************************************/
void stop()   
{
 sda=0;
 delay();
 scl=1;
 delay();
 sda=1;
 delay();
}

/*******************************************
                應答信號
*******************************************/
void respons()  
{
 uchar i;
 scl=1;
 delay();
 while((sda==1)&&(i<250)) i++;
 scl=0;
 delay();
}
/*******************************************
              總線初始化
*******************************************/
void init()
{
 sda=1;
 delay();
 scl=1;
 delay();
}

/*******************************************
                寫入一個字節(jié)
*******************************************/
void write_byte(uchar date)
{
 uchar i,temp;
 temp=date;
 for(i=0;i<8;i++)
 {
  temp=temp<<1;
  scl=0;
     delay();
  sda=CY;
  delay();
  scl=1;
  delay();
 }
 scl=0;
 delay();
 sda=1;
 delay();
}

/*******************************************
               讀出一個字節(jié)
*******************************************/
uchar read_byte()
{
 uchar i,k;
 scl=0;
 delay();
 sda=1;
 delay();
 for(i=0;i<8;i++)
 {
  scl=1;
  delay(); 
  k=(k<<1)|sda;
  scl=0;
  delay(); 
 }
 return k;
}

/*******************************************
             指定地址寫入數(shù)據(jù)
*******************************************/
void write_add(uchar address,uchar date)
{
 start();
 write_byte(0xae);
 respons();
 write_byte(address);
 respons();
 write_byte(date);
 respons();
 stop();
}

/*******************************************
             指定地址讀出數(shù)據(jù)
*******************************************/
uchar read_add(uchar address)
{
 uchar date;
 start();
 write_byte(0xae);
 respons();
 write_byte(address);
 respons();
 start();
 write_byte(0xaf);
 respons();
 date=read_byte();
 stop();
 return date;
}

/*******************************************
                顯示程序
*******************************************/
void display(uchar bai_c,uchar sh_c) 
{
   dula=0;
   P0=table[bai_c];  //顯示第一位
   dula=1;
   dula=0;

   wela=0;
   P0=0xfe;
   wela=1;
   wela=0;

   delay1ms(5);


   dula=0;
   P0=table[sh_c];  //顯示第二位
   dula=1;
   dula=0;

   wela=0;
   P0=0xfd;
   wela=1;
   wela=0;

   delay1ms(5);
}

/*******************************************
                 MAIN
*******************************************/
void main()
{
 init();
 sec=read_add(2);    //讀出保存的數(shù)據(jù)賦于sec
 if(sec>100)        //防止首次讀取出錯誤數(shù)據(jù)
  sec=0;
 TMOD=0x01;     //定時器工作在方式1
 ET0=1; 
 EA=1;
 TH0=(65536-50000)/256; //對TH0 TL0賦值
 TL0=(65536-50000)%256; //使定時器0.05秒中斷一次
 TR0=1;                 //開始計時
 while(1)
 {
  display(sec/10,sec%10);
  if(write==1)         //判斷計時器是否計時一秒
  {
   write=0;              //清零
   write_add(2,sec);     //在24c02的地址2中寫入數(shù)據(jù)sec
  }
 } 
}

/*******************************************
        Interrupt service routine
*******************************************/
void t0() interrupt 1 //定時中斷服務函數(shù)
{
 TH0=(65536-50000)/256; //對TH0 TL0賦值
 TL0=(65536-50000)%256; //重裝計數(shù)初值
 tcnt++;             //每過50ms tcnt加一
 if(tcnt==20)        //計滿20次(1秒)時
 {
     tcnt=0;         //重新再計
     sec++;
     write=1;        //1秒寫一次24C02
     if(sec==100)//定時100秒,再從零開始計時
      sec=0;
 }
}

關閉窗口

相關文章