51模拟IIC-页读写操作

51代码页读写IIC--模拟IIC

#include <reg52.h>
#include <intrins.h>

sbit SDA = P0^0;
sbit SCL = P0^1;
sbit LED = P2^0;

unsigned char code table[] = {0x1c,0X3B,0X2C,0X2D,0X5A,0X5C,0XC5,0X5b};
void delayms(unsigned int t)
{
    unsigned int i,j;
    for(i = t; i > 0; i --)
    for(j = 110; j > 0; j --);
}
void delay()
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        
}
void start()
{
        SCL = 1;
        SDA = 1;
        delay();
        SDA = 0;
        delay();
        SCL = 0;
                
}

void stop()
{
        
        SDA = 0;
        delay();
        SCL = 1;
        delay();
        SDA = 1;
        delay();

}

void ack()
{
        
        SCL = 0;

        delay();
        while(SDA);
        SCL = 1;
        delay();
        
        SCL = 0;
}

void noack()
{
        SCL = 0;
        
        SDA = 1;
        SCL = 1;
        delay();
        SCL = 0;

}

void writebyte(unsigned char byte)
{
        //MSB first
        unsigned char i = 0;
        SCL = 0;
        for(i = 0; i < 8; i ++)
        {
                byte <<= 1;
                SDA = CY;
                delay();
                SCL = 1;
                delay();
                SCL = 0;
        }
        
//        SDA = 1;//waiting for ack
//        delay();
        
        

        

}

unsigned char readbyte()
{
        unsigned char i = 0,val = 0;
        SCL = 0;
        for(i = 0; i < 8 ; i ++)
        {
                val <<= 1;
                delay();
                SCL = 1;
                delay();
                if(SDA)
                {
                        val |= 0x01;
                }        
                else
                {
                        val |= 0x00;
                }
                SCL = 0;
                
        }

        SCL = 0;//release IIC bus

        return val;

            
    

}


void write_data(unsigned char add, unsigned char byte)
{
         start();
         writebyte(0xae);
         ack();
         writebyte(add);
         ack();
         writebyte(byte);
         ack();

         stop();
}

unsigned char read_data(unsigned char add)
{
        unsigned char val = 0;
        start();
        writebyte(0xae);
        ack();
        writebyte(add);
        ack();
        start();
        writebyte(0xaf);
        ack();
        val = readbyte();
        noack();
        stop();

        return val;
}

void pagewrite(unsigned char add)
{
    unsigned char i;
    start();
    writebyte(0xae);
    ack();
    writebyte(add);
    ack();
    for(i = 0; i < 8; i ++)
    {
        writebyte(table[i]);
        ack();
    }
    stop();
}

unsigned char *pageread(unsigned char add)
{
    unsigned char value[8],i;
    start();
    writebyte(0xae);
    ack();
    writebyte(add);
    ack();

    start();
    writebyte(0xaf);
    ack();
    for(i = 0; i < 8; i ++)
    {
        value[i] = readbyte();
        if(i == 7)
        {
            noack();
        }
        else
        {
            SCL = 0;  //主机来应答
    
            delay();
            SDA = 0;
            delay();
            SCL = 1;
            delay();
            
            SCL = 0;
            delay();
            SDA = 1;
            delay();
            
        }
        delay();
    }
    stop();

    return value;
    

}
void main()
{
        unsigned char *TMP_VAL, Tmp = 0;
/**     write_data(0x01,0xAC); //TEST 1    
        delayms(500);     

        Tmp = read_data(0x01);
        delayms(5);
        if(Tmp == 0xac)
        {
            P2 = Tmp;
        } 
 **/
/**        pagewrite(0X00);  //TEST2

        delayms(500);     

        Tmp = read_data(0x07);
        delayms(5);
        if(Tmp == table[7])
        {
            P2 = Tmp;
        }         **/
        pagewrite(0X00);
        delayms(600);
        TMP_VAL = pageread(0x00);
        delayms(500);
        if(*(TMP_VAL+1) == table[1])
        {
            P2 = *(TMP_VAL+1);
        }
        while(1);
}

注意以下要点

过程中出现只能写入偶数情况,是Stop()函数的问题,在SCL上升沿时发生了SDA改变导致的,调整一下先后顺序即可;

页读操作注意ack是主机拉低SDA发出的应答,和单字节读写不同;

如何接收函数返回的数组,以及如何写这个返回数组的函数。

调试过程中有EE不拉低SDA应答的情况,后来排查是EE芯片坏了。

写完数据不能立刻读,要有稍长的延时才行。

posted @ 2024-05-16 22:21  了解2号  阅读(21)  评论(0编辑  收藏  举报