找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3171|回复: 3
打印 上一主题 下一主题
收起左侧

数码管显示写入AT24C02的一个字节数据。

[复制链接]
跳转到指定楼层
楼主
采用STC89C52芯片,12MHZ晶振。
欢迎大家交流,并提出意见。
程序:
#include<reg52.h>
#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit we=P2^7;  //数码管位选
sbit du=P2^6;  //数码管段选

sbit scl=P2^1;        //scl
sbit sda=P2^0;        //sda   

uchar n;   //定义读取AT24C02里面的数据

/*共阴极数码管段选信号和位选信号*/
uchar code table[ ]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数字0-9段选码
uchar code smgwe[ ]={0xfe,0xfd,0xfb};        //位选码

/*毫秒级延时函数*/
void delay(uint z)
{
        uint x,y;
        for(x=100;x>0;x--)       
                for(y=z;y>0;y--);
}
/*数码管显示*/
void display(uchar n)
{
while(1)
{
                        P0 = 0xff; // 清除断码
                we = 1;//打开位选
                        P0 =smgwe[0] ;//1111 1110 只选通第一位数码管
                        we = 0;        //关闭位选

                        du = 1;        //打开段选
                        P0 = table[n/100];        //显示百位
                        du = 0;        //关闭段选
                        delay(5);//延时5毫秒

                        P0 = 0xff; // 清除断码
                        we = 1;        //打开位选
                        P0 =smgwe[1] ;//1111 1101  只选通第二位数码管
                        we = 0;        //关闭位选
                       
                        du = 1;//打开段选
                        P0 = table[(n/10)%10]; //显示十位
                        du = 0;        //关闭段选
                        delay(5);//延时5毫秒       

                        P0 = 0xff; // 清除断码
                        we = 1;        //打开位选
                        P0 = smgwe[2];//1111 1011  只选通第二位数码管
                        we = 0;        //关闭位选
                       
                        du = 1;//打开段选
                        P0 = table[n%10];   //显示个位
                        du = 0;        //关闭段选
                        delay(5);//延时5毫秒
                        }       
}
/*5微秒延时函数*/
void delay5us()
{
        _nop_();
}
/*IIC开始信号*/
void I2cstart()
{
        scl=1;
        _nop_(); //延时一个机器周期稳定一下
        sda=1;
        delay5us();
        sda=0;
        delay5us();       
}
/*IIC停止信号*/
void I2cstop()
{
        sda=0;
        _nop_();
        scl=1;
        delay5us();
        sda=1;
        delay5us();
}
/*检测从机应答*/
bit readback()
{
        //scl=0;
        scl=1;
        delay5us();
        if(sda)//非应答
        {       
            scl=0;//拉低时钟总线
                _nop_();
                //sda=0;
                return(0);        //非应答,返回0
        }
    else //应答
        {
                scl=0;//拉低时钟总线,以便后面数据传输,SCl为低,允许SDA数据变化
                _nop_();
                return(1);//应答,返回1
        }
}
/*主机发送应答和非应答*/
void sendback(bit i)
{
        scl=0;        //拉低时钟总线允许SDA数据总线上的数据变化
        _nop_();// 让总线稳定
        if(i)
                sda=0;
        else
                sda=1;
        _nop_(); //让sda稳定一下
        scl=1; //拉高时钟总线,让从机从SDA上读取数据
        delay5us();
        scl=0;        //拉低时钟总线, 占用总线继续通信,因为scl为低,sda才可以变化,才可以发送数据
        //如果scl为高,sda就不能变化,一变化就成了开始和停止信号了
        _nop_(); //稳定延时一下
        sda=1;        //释放sda数据总线
        _nop_(); //稳定延时一下

}
/*发送一个字节*/
void I2csendbite(uchar m)
{
        uchar i;

        for(i=0;i<8;i++)
        {
                scl=0;
                _nop_();
                if(m&0x80)//如果最高为为1
                   {
                        sda=1;          //sda置1,即发送数据1
                        _nop_();
                        }
                else
                {
                        sda=0; //sda为0,发送数据0
                        _nop_();
                }
                scl=1;//scl置1,从机可以读取总线sda上的数据
                _nop_();
                m=m<<1;        //左移一位,于是传输一字节数据中的下一位数据
        }       
        scl=0;         //拉低时钟总线, 使总线继续通信
        _nop_();
        sda=1;         //释放SDA数据总线。
        _nop_();
}
/*I2C 读一字节*/
uchar I2creadbite()
{
        uchar i,DAT;
//        bit a;
        scl = 0;
        _nop_();
        sda= 1;
        _nop_();
        for(i=0;i<8;i++)
        {
                scl = 1;
                _nop_();
                if (sda)                            
                {
                         DAT |= 0x01; //
                }
                else
                {
                        DAT &=  0xfe;        //1111 1110
                }
                _nop_();
                scl = 0 ;
                _nop_();
                if(i < 7)
                {
                        DAT = DAT << 1;       
                }       
        }
        return(DAT);
}

bit I2c24c02write(uchar ADDR, DAT)
{
        I2cstart();
        I2csendbite(0xa0+0); //器件地址+0,表示写
        if( !readback(  ))
           {
           return(0);
           }
        I2csendbite(ADDR);         //从哪个地址写入数据
         if( !readback(  ))
           {
           return(0);
           }
        I2csendbite(DAT);
         if( !readback(  ))
           {
           return(0);
           }
        I2cstop();
        return(1);       
}

uchar I2c24c02read(uchar ADDR)
{
        uchar DAT;
        I2cstart();
        I2csendbite(0xa0+0);//I2c发送一个字节
        if( !readback(  ))
           {
           return(0);
           }
        I2csendbite(ADDR); //从哪个存储单元读取数据,例如AT24C02的话,有256个字节存储单元(256*8=2048位。)ADDR可以是0-255之间的数。
        //如果是PCF8591的话,ADDR就是控制字,控制字假如为0000 0010.则读取通道2上的模拟量转化为的数字量。

        sendback(0);

        I2cstart();
        I2csendbite(0xa0+1);
        if( !readback(  ))
           {
           return(0);
           }
        DAT=I2creadbite();

        sendback(0);//发送一个非应答
        I2cstop();

        return(DAT);
}

void main()
{       
        I2cstart();
        I2c24c02write(3, 122);
        delay(100);//等从机处理好
        n=I2c24c02read(3);

    display(n);
       
}



屏幕截图(9).png (274.79 KB, 下载次数: 40)

Proteus仿真图

Proteus仿真图

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-7-3 19:51 | 只看该作者
好资料,51黑有你更精彩!!!支持原创
回复

使用道具 举报

板凳
ID:732342 发表于 2020-5-9 10:57 | 只看该作者
很棒对于初学者来着给了很多帮助,谢谢
回复

使用道具 举报

地板
ID:1097263 发表于 2023-11-16 17:10 | 只看该作者
好资料,如果能提供下载链接就更好了……
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表