专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AT89s51-AT24c02记忆秒表计时实验

作者:佚名   来源:本站原创   点击数:  更新时间:2011年07月06日   【字体:

 夜深了,我要的就是这种困意。白天睡觉,晚上学习。突然茫然了一下,彭宗敏说他最后会下定决心准备高考是为了计算机。

        我当初为了什么,也许是有答案的,不经意的发现,早在高二时候,我就确定我以后读电子信息类的。路既然没错,就不要有任何后悔的走下去!
 


 

/**********************************************
 《郭天祥新概念51单片机》P188,有改动。
    利用定时器产生0-99计时秒表,每过1秒,将计数的
的数值写入AT24c02,关闭电源再打开,单片机将原来
写入的值读出来,接着此数继续按秒变化,并显示在
数码管上
**********************************************/
/**********************************************
数码管显示:
  数据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};
/*******************************************
                延时函数
*******************************************/
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();
}

/*******************************************
                写入一个字节
*******************************************/
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();
}

/*******************************************
               读出一个字节
*******************************************/
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;
}

/*******************************************
             指定地址写入数据
*******************************************/
void write_add(uchar address,uchar date)
{
 start();
 write_byte(0xae);
 respons();
 write_byte(address);
 respons();
 write_byte(date);
 respons();
 stop();
}

/*******************************************
             指定地址读出数据
*******************************************/
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);    //读出保存的数据赋于sec
 if(sec>100)        //防止首次读取出错误数据
  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中写入数据sec
  }
 } 
}

/*******************************************
        Interrupt service routine
*******************************************/
void t0() interrupt 1 //定时中断服务函数
{
 TH0=(65536-50000)/256; //对TH0 TL0赋值
 TL0=(65536-50000)%256; //重装计数初值
 tcnt++;             //每过50ms tcnt加一
 if(tcnt==20)        //计满20次(1秒)时
 {
     tcnt=0;         //重新再计
     sec++;
     write=1;        //1秒写一次24C02
     if(sec==100)//定时100秒,再从零开始计时
      sec=0;
 }
}

关闭窗口

相关文章