Troubles about Programming AT24C02

Discuss all aspects of programming here.

Moderator: The Mod Squad

Troubles about Programming AT24C02

Postby migrant » Fri Jun 09, 2017 10:36 pm

Good day~
I would like to save the data which is belongs to float type
Into AT24C02 and then read and show them in the serial port.But why it always show a wrong number in the serial port? Are there any problems in my program?This is the datasheet of AT24C02: http://www.kynix.com/uploadfiles/pdf/AT24C02-10PI-2.7.pdf
My program is given below:
Code:
Code: Select all
#include<reg51.h>
#include <stdio.h>

#define write_c02 0xa0
#define read_c02 0xa1

typedef unsigned char uchar;
typedef unsigned int uint;

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

/*********delay**************/
void delay()           /about 5us
{
    ;;
}

void delayms(uint xms)  // delay X millisecond
{
    uchar x,y;
        for(x=xms;x>0;x--)
            for(y=110;y>0;y--);       
}

/**********I2Csub program***************/
void i2c_init()          //I2C initialization
{
    sda=1;
        delay();
        scl=1;
        delay();
}

void start()      //start I2C
{
    sda=1;
        scl=1;
        delay();    //If scl is in high level,one downing edge of sda is starting signal一        sda=0;     
        delay();
}

void stop()        //stop I2C
{
    sda=0;
        scl=1;
        delay();
        sda=1;          //If scl is in high level,one rising edge of sda is stoping signal
        delay();
}

void ack()       //response signal 0
{
    uchar i=0;   //waiting viable
        scl=1;       //waiting response when scl in the high level
        delay();
        while((sda=1)&&i<250)//quit if answering 0;
        i++;
        scl=0;       //downing scl after answering
        delay();
}

void nack()      //non-answer
{
    scl=1;       //If scl is in high level,mainframe send 1 to slave;no answer signal        delay();
        sda=1;
        scl=0;       //downing scl after answering
        delay();
}

void send_byte(uchar date)  // write a byte
{
    uchar i , temp;
        temp=date;     //saving the writing data
        for(i=0;i<8;i++)
        {
            temp<<=1;
                scl=0;     // The data in sda could change just in the condition that scl is low level
                delay();
                sda=CY;    // send the data in CY to sda
                delay();
                scl=1;     //The data in sda can’t change if  scl is in high level,keep the data stable
                delay();
                scl=0;     //allow the data in sda to change and wait the another data to transfer
                delay();
        }//waiting for response of slave after sending a byte
        scl=0;//allow sda to change
        delay();
        sda=1;//sda draw high to wait answering, if sda=0,the slave has answered
        delay();
}                       

uchar read_byte()        //read a byte data
{
    uchar i,j,k;
        scl=0;         //allow sda to change
        delay();       //waiting data
        for(i=0;i<8;i++)
        {
            scl=1;     // ban sda to change
                delay();
                j=sda;     //read the data in sda
                k=(k<<1)|j;// saving the data into K after passing1calculate            delay();
                scl=0;     //allow the data in sda to change and wait the another data to transfer
                delay();
        }
        delay();
        return k;      //return the reading data
}

/*****************saving data from AT24C02***********************/
void write_at24c02(uchar address,uchar date)//write date into the address of at24c02、
{
    start();         //start I2C
        send_byte(write_c02); //
        ack();        //slave answer :0
        send_byte(address);//
        ack();
        send_byte(date);/
        ack();
        stop();         /stop I2C
}

uchar read_at24c02(uchar address)//reading the writing date from the address of at24c02、{
    uchar dat;   //
        start();     /start I2C
        send_byte(write_c02);//
        ack();
        send_byte(address);  //
        ack();
        start();          //start I2C again
        send_byte(read_c02);//
        ack();
        dat=read_byte();//
        nack();//
        stop();//stop I2C
        return dat;
}

/**********************saving float type data from AT24C02****************************/
void write_f_rom(uchar address,float date)//saving coefficient into AT24C02
{
    unsigned long d;
        unsigned char d0,d1,d2,d3;
        d=(unsigned long)(date);
        d0=(unsigned char)(d>>24);
        d1=(unsigned char)((d&0x00ff0000)>>16);
        d2=(unsigned char)((d&0x0000ff00)>>8);
        d3=(unsigned char)(d%256);
        delayms(10);
        write_at24c02(address,d0);
        delayms(10);
        write_at24c02(address+0x01,d1);
        delayms(10);
        write_at24c02(address+0x02,d2);
        delayms(10);
        write_at24c02(address+0x03,d3);
        delayms(10);
}

float read_f_rom(unsigned char address)        //read data from AT24C02
{
    unsigned char i;
        float date;
        unsigned char c[4];
        unsigned long d[4];

        for(i=0;i<4;i++)
        {
            read_at24c02(address+i);
                c[i]=read_at24c02(address+i);       
        }
    for(i=0;i<4;i++)
        {
            d[i]=(unsigned long)c[i];
        }
        date=((float)((long)((d[0]<<24)+(d[1]<<16)+(d[2]<<8)+d[3])));
        return date;
}

/******************serial port initialization**********************/

void uart_init(void) //serial port initialization
{
    TMOD=0x20;//0010 0000,timer 1,working way2
    TH1=0xfd;//set baud rate to be 9600
    TL1=0xfd;
    TR1=1;//start timer 1       
    SCON=0x50; //0101 0000.serial port working way 1,allow series to control
    PCON=0x00;//setSMOD=0
    IE=0x90; //CPU allow to interrupt,series is allowed to interrupt   
    TI=1;//use printf directly need to add this sentence
        ES=1;//series interrupt
        EA=1;//
}

void main()
{
//    uchar i;
        float shuju=1.1;
        float shuju1;
        i2c_init();
        uart_init();
        start();
        while(1)
        {
                write_f_rom(0x00,shuju);
                delayms(100);
                shuju1=read_f_rom(0x00);
                delayms(100);
                printf("%.1f\n",shuju1);
                delayms(200);
        }
}

Thanks.
migrant
Pilgrim
Pilgrim
 
Posts: 1
Joined: Fri Jun 09, 2017 6:12 pm

Return to Programming

Who is online

Users browsing this forum: No registered users and 0 guests