| IIC读写EEPROM的源码,经过编译和烧录,成功在开发板上实现。一个00~99的计数器,每秒计数一次,具有断电记忆功能(开机后,从关机前的最新数值继续计数),软件模拟IIC协议。 源码以及开发板上的与本源码相关的电路部分如下
 
   数码管
 
   EEPROM模块以及受影响的DS1302模块
 
   单片机源程序如下:
 
 复制代码#include<reg52.h>
#include<intrins.h>
bit x=0;                //将计时值写入EEPROM的标志位
sbit SCL=P2^1;
sbit SDA=P2^0;
sbit X=P2^4;                //引脚P2^4为开发板上DS1302模块的复位引脚
sbit DU=P2^6;                //数码管模块段选位
sbit WE=P2^7;                //数码管模块位选位
unsigned char num=0;
unsigned char i=0;
unsigned char LEDS[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};                //共阴数码管的段码
void LEDS_IO()                //数码管锁存
{
        WE=1;
        P0=1;
        WE=0;
        DU=1;
        P0=0;
        DU=0;
}
void Delay5ms()
{
        unsigned char i,j;
        i=9;
        j=244;
        do
        {
                while(--j);
        }
        while(--i);
}
void IIC_Delay()
{
        _nop_();
        _nop_();
}
void IIC_INIT()                //IIC初始化
{
        X=0;                //DS1302模块的复位电平为低电平,令DS1302模块一直处于复位状态,使其I/O端口(P2^0)不输出,避免干扰EEPROM模块的SDA端口(P2^0)
        SDA=1;
        IIC_Delay();
        SCL=1;
        IIC_Delay();
}
void IIC_Start()                //IIC起始信号
{
        SDA=1;
        IIC_Delay();
        SCL=1;
        IIC_Delay();
        SDA=0;
        IIC_Delay();
}
void IIC_Stop()                //IIC停止信号
{
        SDA=0;
        IIC_Delay();
        SCL=1;
        IIC_Delay();
        SDA=1;
        IIC_Delay();
}
void IIC_ACK()                //等待应答信号;“应答”信号:SDA=0;“非应答”信号:SDA=1
{
        unsigned char i;
        SCL=1;
        IIC_Delay();
        while((SDA==1)&&(i<256))                //若超时,则视为“非应答”
        {
                i++;
        }
        SCL=0;
        IIC_Delay();
}
void IIC_Write(unsigned char DATA)                //IIC发送数据
{
        unsigned char i;
        unsigned char temp;
        temp=DATA;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                SCL=0;
                IIC_Delay();
                SDA=CY;                //IIC数据的发送从高位开始,需要使用左移指令,而C语言的左移和右移指令,CY参与其中(CY并不是只有在进位和借位中用到),左移出来的一位赋给CY
                IIC_Delay();
                SCL=1;
                IIC_Delay();
        }
        SCL=0;                //将SCL置低电平,准备接收应答信号
        IIC_Delay();
        SDA=1;                //释放SDA,准备接收从器件反馈的应答信号
        IIC_Delay();
}
unsigned char IIC_Read()                //IIC接收数据
{
        unsigned char i;
        unsigned char DATA;
        SCL=0;
        IIC_Delay();
        SDA=1;
        IIC_Delay();
        for(i=0;i<8;i++)
        {
                SCL=1;
                IIC_Delay();
                DATA=(DATA<<1)|SDA;
                SCL=0;
                IIC_Delay();
        }
        return DATA;
}
void EEPROM_Write(unsigned char ADDRESS,unsigned char DATA)                //写入EEPROM
{
        IIC_Start();
        IIC_Write(0xa0);                //发送IIC从器件(EEPROM)地址,并选择“写”操作
        IIC_ACK();
        IIC_Write(ADDRESS);                //发送将要写入的EEPROM的存储地址
        IIC_ACK();
        IIC_Write(DATA);                //发送写入EEPROM的数据
        IIC_ACK();
        IIC_Stop();
}
unsigned char EEPROM_Read(unsigned char ADDRESS)                //读取EEPROM
{
        unsigned char DATA;
        IIC_Start();
        IIC_Write(0xa0);
        IIC_ACK();
        IIC_Write(ADDRESS);
        IIC_ACK();
        IIC_Start();
        IIC_Write(0xa1);                //发送IIC从器件(EEPROM)地址,并选择“读”操作
        IIC_ACK();
        DATA=IIC_Read();
        IIC_Stop();
        return DATA;
}
void LEDS_OUTPUT(unsigned char m,unsigned char n)                //数码管显示
{
        DU=0;
        P0=LEDS[m];
        DU=1;
        DU=0;
        WE=0;
        P0=0x3e;
        WE=1;
        WE=0;
        Delay5ms();
        DU=0;
        P0=LEDS[n];
        DU=1;
        DU=0;
        WE=0;
        P0=0x3d;
        WE=1;
        WE=0;
        Delay5ms();
}
void main()
{
        IIC_INIT();
        LEDS_IO();
        num=EEPROM_Read(0x00);
        TMOD=0x01;
        TH0=0x4c00;
        TL0=0x4c00;
        TR0=1;
        ET0=1;
        EA=1;
        while(1)
        {
                LEDS_OUTPUT(num/10,num%10);
                if(x==1)
                {
                        x=0;
                        EEPROM_Write(0x00,num);
                }
        }
}
void T() interrupt 1                //每0.05秒中断一次
{
        TH0=0x4c00;
        TL0=0x4c00;
        i++;
        if(i==20)                //中断20次,即1秒
        {
                i=0;
                num++;
                x=1;
                if(num==100)
                {
                        num=0;
                }
        }
}
 
    【必读】版权免责声明
        1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
     |