Thông báo

Collapse
No announcement yet.

Không ghi được 2 byte liên tiếp trên EEPROM

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Không ghi được 2 byte liên tiếp trên EEPROM

    Chào các bác ạ, em đang muốn ghi dữ liệu vào 2 byte liên tiếp của EEPROM. Code có lấy ở trên mạng và chỉnh sửa, nhưng khổ nỗi có lỗi là khi ghi 2 byte hoặc nhiều hơn liên tiếp chỉ ghi được byte đầu tiên thôi, byte sau thì không ghi được. Đổi vị trí 2 lệnh ghi thì chỉ lệnh ghi với địa chỉ đầu là như thế nào thì vẫn ghi được, trong khi địa chỉ sau thì không thể ghi được. Các bác xem giúp em code với ạ. EM xin chân thành cảm ơn
    Code:
    #include <REGX51.H>
    #include "string.h"
    sfr lcddata=0xA0;
    sbit bf=0xA7;
    sbit rs=P3^0;
    sbit rw=P3^1;
    sbit en=P3^2;
    unsigned int x=0,dat,h,l,a,b;
    
    #define EEPROMS_ID 0xA0	/* Microchip 24xx512 */
    #define SDA P1_0		/* Set P1.0 = SDA */
    #define SCL P1_1		/* Set P1.1 = SCL */
    #define I2C_DELAY 0x0F	/* For delay i2c bus */
    
    void I2C_delay(void)
    {
    	unsigned char i;
    
    	for(i=0; i<I2C_DELAY; i++);
    }
    
    void I2C_clock(void)
    {
    	I2C_delay();
    
    	SCL = 1;		/* Start clock */
    
    	I2C_delay();    
    
    	SCL = 0;		/* Clear SCL */
    }
    
    void I2C_start(void)
    {
    	if(SCL)
    	SCL = 0;		/* Clear SCL */
    
    	SDA = 1;        /* Set SDA */
    	SCL = 1;		/* Set SCL */
    
    	I2C_delay(); 
    
    	SDA = 0;        /* Clear SDA */
    
    	I2C_delay(); 
    
    	SCL = 0;        /* Clear SCL */
    }
    
    void I2C_stop(void)
    {
    	if(SCL)	
    	SCL = 0;			/* Clear SCL */
    
    	SDA = 0;			/* Clear SDA */
    	I2C_delay();
    
    	SCL = 1;			/* Set SCL */
    
    	I2C_delay();
    
    	SDA = 1;			/* Set SDA */
    }
    
    bit I2C_write(unsigned char dat)
    {
    	bit data_bit;		
    	unsigned char i;	
    
    	for(i=0;i<8;i++)				/* For loop 8 time(send data 1 byte) */
    	{
    		data_bit = dat & 0x80;		/* Filter MSB bit keep to data_bit */
    		SDA = data_bit;				/* Send data_bit to SDA */
    
    		I2C_clock();      			/* Call for send data to i2c bus */
    
    		dat = dat<<1;  
    	}
    
    	SDA = 1;			/* Set SDA */
    
    	I2C_delay();	
    	
    	SCL = 1;			/* Set SCL */
    
    	I2C_delay();	
    
    	data_bit = SDA;   	/* Check acknowledge */
    	SCL = 0;			/* Clear SCL */
    
    	I2C_delay();
    
    	return data_bit;	/* If send_bit = 0 i2c is valid */		 	
    }
    
    unsigned char I2C_read(void)
    {
    	bit rd_bit;	
    	unsigned char i, dat;
    
    	dat = 0x00;	
    
    	for(i=0;i<8;i++)		/* For loop read data 1 byte */
    	{
    		I2C_delay();
    
    		SCL = 1;			/* Set SCL */
    
    		I2C_delay(); 
    
    		rd_bit = SDA;		/* Keep for check acknowledge	*/
    		dat = dat<<1;		
    		dat = dat | rd_bit;	/* Keep bit data in dat */
    
    		SCL = 0;			/* Clear SCL */
    	}
    
    	return dat;
    }
    
    //void I2C_ack()
    //{
    //	SDA = 0;		/* Clear SDA */
    
    //	I2C_delay();    
    
    //	I2C_clock();	/* Call for send data to i2c bus */
    
    //	SDA = 1;		/* Set SDA */
    //}
     
    void I2C_noack()
    {
    	SDA = 1;		/* Set SDA */
    
    	I2C_delay();
    
    	I2C_clock();	/* Call for send data to i2c bus */
    
    	SCL = 1;		/* Set SCL */
    }
    unsigned char EEPROM_get(unsigned int addr)
    {
    	unsigned char dat;	
    
    	I2C_start();            /* Start i2c bus */
    
    	I2C_write(EEPROMS_ID);   /* Connect to EEPROM */
    	I2C_write(addr>>8);	 /* Request RAM address (Hight byte) */	 
    	I2C_write(addr&0x00FF);	 /* Request RAM address (Low byte) */
    	
    	I2C_start();			/* Start i2c bus */
    
    	I2C_write(EEPROMS_ID+1);/* Connect to EEPROM for Read */
    	dat = I2C_read();		/* Receive data */
    
    	I2C_noack();
    	
    	I2C_stop();				/* Stop i2c bus */
    
       return dat;			
    }
    
    void EEPROM_set(unsigned int addr, unsigned char val)
    {
    	I2C_start(); 
    
    	I2C_write(EEPROMS_ID);   /* Connect to EEPROM */
    	I2C_write(addr>>8);		 /* Request RAM address (Hight byte) */
    	I2C_write(addr&0x00FF);		 /* Request RAM address (Low byte) */
    
    	I2C_write(val);			/* Write sec on RAM specified address */
    
    	I2C_stop();           	/* Stop i2c bus */
    }
    void wait(void)
    {
    	//long n=0;
    	
    	en=1;
    	rs=0;
    	rw=1;
    	lcddata=0xff;
    	while(bf)
    	{
    		//n++;
    		//if(n>100)break;
    	}
    	en=0;
    	rw=0;	
    
    }
    void lcdcontrol(unsigned char x)
    {
    	rs=0;
    	rw=0;
    	lcddata=x;
    	en=1;
    	en=0;
    	wait();
    }
    void lcdinit(void)
    {
    	lcdcontrol(0x30); //Phai co cai nay thi moi chay 2 dong duoc
    	
    	lcdcontrol(0x38);
    	//lcdcontrol(0x0C);
    	lcdcontrol(0x0e);
    	lcdcontrol(0x01);
    }
    void lcdwrite(unsigned char c)
    {
    	rs=1;
    	rw=0;
    	lcddata=c;
    	en=1;
    	en=0;
    	wait();
    }
    void lcdwrites(unsigned char *s)
    {
    	unsigned char data lens, count;
    	lens=strlen(s);
    	for(count=0;count<lens;count++)
    	{
    		lcdwrite(*(s+count));
    	}
    }
    void delay(long time)
    {
    	while(time--);
    }
    void number(unsigned int i)
    {
    	unsigned char a,b,c,d,e;
    	e=i%10;
    	i=i/10;
    	d=i%10;
    	i=i/10;
    	c=i%10;
    	i=i/10;
    	b=i%10;
    	a=i/10;
    	lcdwrite(a+48);
    	lcdwrite(b+48);
    	lcdwrite(c+48);
    	lcdwrite(d+48);
    	lcdwrite(e+48);
    }
    
    void main(void)			
    {
     
    	
    	EEPROM_set(0xffff+1,123);
    	EEPROM_set(0xffff,456);
    	
      IT0=1;// ngat suon âm*/
      lcdinit();
      lcdcontrol(0x80);
    	lcdwrites("Counts");
    	
    	lcdcontrol(0xc0);
    	lcdwrites("Read");
      while(1)
    {
    
    	
    a = EEPROM_get(0xffff);
    
    b = EEPROM_get(0xffff+1);	
    lcdcontrol(0xc0);
    number(b);
    lcdcontrol(0x87);
    number(a);
    	
    
    	
    }  
    } /* End main */
    Last edited by qwerty68; 15-11-2012, 23:06.

  • #2
    Bạn viết lại phần ghi EEProm và đọc EEProm đi. Con 24C512 có 65536 ô nhớ, trong khi đó bạn cần lưu ở tận ô địa chỉ 0xffff+1 = (65536 + 1) thì lấy đâu ra mà lưu .
    void main(void)
    {


    EEPROM_set(1,123); // ghi vào ô nhớ thứ nhất giá trị 123
    EEPROM_set(2,45); // (trong chương trình của bạn 1 ô nhớ chỉ lưu max = 255 thôi, bạn lưu giá trị 456 thì lưu
    // bằng răng ah)

    IT0=1;// ngat suon âm*/
    lcdinit();
    lcdcontrol(0x80);
    lcdwrites("Counts");

    lcdcontrol(0xc0);
    lcdwrites("Read");
    while(1)
    {


    a = EEPROM_get(1); // dọc ô nhớ thứ 1

    b = EEPROM_get(2); // đọc ô nhớ thứ 2
    lcdcontrol(0xc0);
    number(b);
    lcdcontrol(0x87);
    number(a);
    }
    } /* End main */
    Last edited by traixommoi; 16-11-2012, 01:50.

    Comment


    • #3
      Nguyên văn bởi traixommoi Xem bài viết
      Bạn viết lại phần ghi EEProm và đọc EEProm đi. Con 24C512 có 65536 ô nhớ, trong khi đó bạn cần lưu ở tận ô địa chỉ 0xffff+1 = (65536 + 1) thì lấy đâu ra mà lưu .
      Cảm ơn bạn, mình đã sửa lại thành địa chỉ 0x0000 và 0x0000+1 nhưng vẫn đều không được. Chả hiểu do đâu nữa.

      Comment


      • #4
        đã từng gặp lỗi này, ban đầu nghĩ sai đủ thứ nhưng hóa ra ko phải.
        theo như kinh nghiệm đã làm thì họ 24Cxxx giao tiếp I2C, cùng với kiểu của như DS1307 chẳng hạn nhưng DS1307 có tốc độ giao tiếp lớn hơn. còn vs dòng EEprom kia có tốc độ giao tiếp khá chậm. giữa các quá trình ghi đọc time cần tăng delay để nó kịp đáp ứng
        bạn có thể viết thêm 1 chương trình con giao tiếp riêng cho eeprom và tăng delay cho nó lên test thử xem. mình đã từng làm trên mạch thật và tất nhiên ghép chung chân SDA và SCL
        Website chính thức đổi địa chỉ website thành
        Mời các bạn ghé thăm !!!

        Comment


        • #5
          Nguyên văn bởi mast090 Xem bài viết
          đã từng gặp lỗi này, ban đầu nghĩ sai đủ thứ nhưng hóa ra ko phải.
          theo như kinh nghiệm đã làm thì họ 24Cxxx giao tiếp I2C, cùng với kiểu của như DS1307 chẳng hạn nhưng DS1307 có tốc độ giao tiếp lớn hơn. còn vs dòng EEprom kia có tốc độ giao tiếp khá chậm. giữa các quá trình ghi đọc time cần tăng delay để nó kịp đáp ứng
          bạn có thể viết thêm 1 chương trình con giao tiếp riêng cho eeprom và tăng delay cho nó lên test thử xem. mình đã từng làm trên mạch thật và tất nhiên ghép chung chân SDA và SCL
          Cảm ơn bạn, để mình test thử xem sao.

          Comment

          Về tác giả

          Collapse

          qwerty68 Trịnh Ngọc Duy Tìm hiểu thêm về qwerty68

          Bài viết mới nhất

          Collapse

          Đang tải...
          X