⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clockand2401rw.c

📁 51单片机上运行的时钟程序,并且可以读写EEPROM,设置几个按钮,可以改变时钟显示和进行读写操作
💻 C
字号:
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Author : ShiZheJun
// Date : 2007.10
// 编译环境 :伟福6000
// 说明:使用8051系列单片机,6M晶振,显示的数字分段从高位到低位输出到74hc164,再移位输出到数码
//       显示管,用两个数码管显示数字.
//       按键K1显示秒数,K2显示分钟,K3写数据到EEPROM 24C01,K4从24C01读出数据并显示
//       数字段码从高位到低位移出到74HC164;在移出过程中数码管必须熄灭,等全部移出后再点亮并
//       延时,24C01读写时指定地址 
//                                                                                    Ver3
//
//////////////////////////////////////////////////////////////////////////////////////////////

#include "stdio.h"
#include "reg51.h"
#include "intrins.h"
#include "absacc.h"

#define Hi       236
#define Lo       120
#define NOP      _nop_();_nop_();_nop_()   /*延时使用,一个_nop_()为一个时钟周期*/
#define Rd2401   0xa1               /*读24C01控制命令*/
#define Wr2401   0xa0               /*写24C01控制命令*/
#define DispLine 0x86
#define Address  0x08               /*读写24C01存储单元的地址*/
unsigned char Seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char Disp;                 /*显示缓冲*/
unsigned char DispTemp;             /*显示临时数据*/
unsigned int  Deda,Sec,Min;
unsigned int  KeyVal;               /*按键值*/
sbit K0=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
sbit K3=P1^3;
sbit SCL=P2^0;                      /*IIC总线方式工作时时钟信号*/
sbit SDA=P2^1;                      /*IIC总线方式工作时串行数据信号*/
sbit Line0=P2^4;
sbit Bout=P3^0;                     /*p3.0输出段数据*/
sbit CLK=P3^1;                      /*p3.2输出脉冲信号,使74hc164产生移位*/
sbit P35=P3^5;                      /*低电平时使个位显示*/
sbit P36=P3^6;                      /*低电平时使十位显示*/

Timer0() interrupt 1
    {
    TMOD=0x01;                      /*工作模式1*/
    TH0=Hi;                         /*设置10ms中断一次*/
    TL0=Lo;
    IE=0x82;                        /*允许计时器0中断*/
    PT0=1;                          /*计时器0中断优先*/
    TR0=1;                          /*启动计时器0*/
    Deda++;
    if (Deda==100) {Sec++;Deda=0;}
    if (Sec==60) {Min++;Sec=0;}
    if (Min==60) Min=0;
    }

void InitTimer0(void)               /*初始化计时器0*/
    {
    TMOD=0x01;
    TH0=Hi;
    TL0=Lo;
    IE=0x82;
    PT0=1;
    TR0=1;
    }

void Delay(unsigned int t)          /*起延迟作用的子函数*/
    {
    while (t--);
    }

void KeyPress(void)                 /*检测按键是否被按下*/
    {
    Line0=0;
    if (K0==0)
        Delay(500);
    if (K0==0) KeyVal=0;
    if (K1==0)
        Delay(500);
    if (K1==0) KeyVal=1;
    if (K2==0)
        Delay(500);
    if (K2==0) KeyVal=2;
    if (K3==0)
        Delay(500);
    if (K3==0) KeyVal=3;
    }

void SendData(void)                 /*向74HC164移位输出显示数据*/
    {
    unsigned char n=8;
    while (n--)
        {
        if (Disp&0x80) Bout=1;
            else Bout=0;
        CLK=0; CLK=1;
        Disp=Disp<<1;
        }
    }

//////////////////////////////////////////////////////////////////////////////////////////////
//
// 以下为IIC总线方式,传输和接收数据,以及启动和停止的各个子函数
//
//////////////////////////////////////////////////////////////////////////////////////////////

void IICStart(void)                 /*IIC启动条件*/
    {
    SDA=1;
    SCL=1;
    NOP;
    SDA=0;
    NOP;
    }

void IICStop(void)                  /*IIC停止条件*/
    {
    SDA=0;
    SCL=1;
    NOP;
    SDA=1;
    NOP;
    }

void IICSend(unsigned char d)       /*IIC发送数据子函数*/
    {
    unsigned int i;
    for (i=0;i<8;i++)
        {
        SCL=0;
        NOP;
        if (d&0x80) SDA=1;
            else SDA=0;
        NOP;
        SCL=1;
        d=d<<1;
        }
    SCL=0;
    }

unsigned char IICReceive(void)      /*IIC接收数据子函数*/
    {
    unsigned int i;
    unsigned char d=0;
    SDA=1;
    NOP;
    SCL=0;
    NOP;
    for (i=0;i<8;i++)
        {
        NOP;
        d=d<<1;
        SCL=1;
        if (SDA) d=d+1;
        SCL=0;
        }
    return d;
    }

void IICAck(void)                   /*IIC发出应答信号*/
    {
    SDA=0;
    NOP;
    SCL=1;
    NOP;
    SCL=0;
    }

void IICNoAck(void)                 /*IIC发出无应答信号*/
    {
    SDA=1;
    NOP;
    SCL=1;
    NOP;
    SCL=0;
    }

void Change(void)                   /*根据按键显示不同的内容*/
    {
    if (KeyVal==0)                  /*显示秒数*/
        {
        Disp=Seg[Sec%10];
        SendData();
        P35=0;
        Delay(407);
        P35=1;
        Disp=Seg[Sec/10];
        SendData();
        P36=0;
        Delay(408);
        P36=1;
        }
    if (KeyVal==1)                  /*显示分钟*/
        {
        Disp=Seg[Min%10];
        SendData();
        P35=0;
        Delay(409);
        P35=1;
        Disp=Seg[Min/10];
        SendData();
        P36=0;
        Delay(410);
        P36=1;
        }
    if (KeyVal==2)                  /*向24C01发送数据*/
        {
        IICStart();
        IICSend(Wr2401);
        SDA=0;
        NOP;
        SCL=1;
        NOP;
        SCL=0;
        IICSend(Address);           /*发送数据地址*/
        SDA=0;
        NOP;
        SCL=1;
        NOP;
        SCL=0;
        IICSend(DispLine);
        IICAck();
        IICStop();
        KeyVal=0;
        }
    if (KeyVal==3)                  /*接收24C01的数据,接收前要先输入写的命令,再重新初始化*/
        {
        IICStart();
        IICSend(Wr2401);
        IICAck();
        IICSend(Address);           /*发送数据地址*/
        IICAck();
        IICStart();
        IICSend(Rd2401);
        IICAck();
        DispTemp=IICReceive();
        IICNoAck();
        IICStop();
        KeyVal=4;
        }
    if (KeyVal==4)                  /*显示从24C01接收到的数据*/
        {
        Disp=DispTemp;
        SendData();
        P35=0;
        Delay(405);
        P35=1;
        Disp=DispTemp;
        SendData();
        P36=0;
        Delay(406);
        P36=1;
        }
    }

void main(void)
    {
    InitTimer0( );		/*初始化计时器0*/
    while ( 1 )
        {
        KeyPress();		/*按键检测*/
        Change();
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -