有關EEPROM M24C16 |
答題得分者是:DavidLo
|
scott123
中階會員 發表:19 回覆:66 積分:52 註冊:2011-08-11 發送簡訊給我 |
|
DavidLo
高階會員 發表:17 回覆:225 積分:168 註冊:2004-07-21 發送簡訊給我 |
Please see page 5/20
Table 3. Device Select Code 1 Note: 1. The most significant bit, b7, is sent first. 2. E0, E1 and E2 are compared against the respective external pins on the memory device. 3. A10, A9 and A8 represent high significant bits of the address. A10 A9 A8 RW |
scott123
中階會員 發表:19 回覆:66 積分:52 註冊:2011-08-11 發送簡訊給我 |
剛剛突然開竅,對喔,device不就有包括位址的三條線
所以剛好是2k,謝謝 另外請問ack和nack是在SCL什麼情況下接收和答覆的 我的ack 是在SCL 0-->1之後去檢查SDA是不是為0的 我的nack是在SCL 0-->1之前先把SDA設為0的 可是我收到的資料都是0 m24c16_start(); m24c16_write(Write); //device m24c16_ack(); m24c16_write(0x00); //address m24c16_ack(); m24c16_write(0x50); //data m24c16_nack(); m24c16_stop(); _NOP(); _NOP(); m24c16_start(); m24c16_write(Write); //device m24c16_ack(); m24c16_write(0x00); //address m24c16_ack(); m24c16_start(); m24c16_write(Read); //device m24c16_ack(); m24c16_read(); m24c16_nack(); m24c16_stop(); _NOP();
編輯記錄
scott123 重新編輯於 2011-10-24 02:59:59, 註解 無‧
|
DavidLo
高階會員 發表:17 回覆:225 積分:168 註冊:2004-07-21 發送簡訊給我 |
|
scott123
中階會員 發表:19 回覆:66 積分:52 註冊:2011-08-11 發送簡訊給我 |
|
DavidLo
高階會員 發表:17 回覆:225 積分:168 註冊:2004-07-21 發送簡訊給我 |
提供參考,希望對你有幫助,在說明一下,我用的是有內建I2C功能,程式Read/Write byte範例如下(from Microchip I2C example)
I2C basic functions call are from Microchip library,如果你不是使用跟我一樣的CPUvoid i2c_WriteByte(int pos,char databyte) { unsigned char SlaveAddress; char i2cData[128]; int DataSz; char buff[80]; SlaveAddress = 0x50; //0b1010000 Serial EEPROM address // Send Data to eeprom to program one location i2cData[0] = (SlaveAddress << 1) | 0; //EEPROM Device Address and WR Command i2cData[1] = (pos>>8); //eeprom location to program (high address byte) i2cData[2] = (pos&0xFF); //eeprom location to program (low address byte) i2cData[3] = databyte; DataSz = 4; StartI2C1(); //Send the Start Bit IdleI2C1(); //Wait to complete int Index = 0; while( DataSz ) { MasterWriteI2C1( i2cData[Index ] ); IdleI2C1(); //Wait to complete DataSz--; //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data. if( I2C1STATbits.ACKSTAT ) break; } StopI2C1(); //Send the Stop condition IdleI2C1(); //Wait to complete // wait for eeprom to complete write process. poll the ack status while(1) { i2c_wait(10); StartI2C1(); //Send the Start Bit IdleI2C1(); //Wait to complete MasterWriteI2C1( i2cData[0] ); IdleI2C1(); //Wait to complete if( I2C1STATbits.ACKSTAT == 0 ) //eeprom has acknowledged { StopI2C1(); //Send the Stop condition IdleI2C1(); //Wait to complete break; } StopI2C1(); //Send the Stop condition IdleI2C1(); //Wait to complete } } char i2c_ReadByte(int pos) { unsigned char SlaveAddress; char i2cData[128]; int DataSz,i; char buff[80]; SlaveAddress = 0x50; //0b1010000 Serial EEPROM address i2cData[0] = (SlaveAddress << 1) | 0; //EEPROM Device Address and WR Command (to write the address) i2cData[1] = (pos>>8); //eeprom location to read (high address byte) i2cData[2] = (pos&0xFF); //eeprom location to read (low address byte) DataSz = 3; StartI2C1(); //Send the Start Bit IdleI2C1(); //Wait to complete //send the address to read from the serial eeprom int Index = 0; while( DataSz ) { MasterWriteI2C1( i2cData[Index ] ); IdleI2C1(); //Wait to complete DataSz--; //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not acknowledge the data. if( I2C1STATbits.ACKSTAT ) break; } //now send a start sequence again RestartI2C1(); //Send the Restart condition //wait for this bit to go back to zero IdleI2C1(); //Wait to complete MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit read command IdleI2C1(); //Wait to complete unsigned char retByte; retByte = MasterReadI2C1(); StopI2C1(); //Send the Stop condition IdleI2C1(); //Wait to complete return(retByte); } |
scott123
中階會員 發表:19 回覆:66 積分:52 註冊:2011-08-11 發送簡訊給我 |
|
DavidLo
高階會員 發表:17 回覆:225 積分:168 註冊:2004-07-21 發送簡訊給我 |
找到了51控制的I2C方法,請參考,EEPROM is 24C02
bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) { unsigned char i; Start_I2c(); /*啟動總線*/ SendByte(sla); /*發送器件地址*/ if(ack==0)return(0); SendByte(suba); /*發送器件子地址*/ if(ack==0)return(0); Start_I2c(); /*重新啟動總線*/ SendByte(sla 1); if(ack==0)return(0); for(i=0;i *s=RcvByte(); /*發送數據*/ Ack_I2c(0); /*發送就答位*/ s ; } *s=RcvByte(); Ack_I2c(1); /*發送非應位*/ Stop_I2c(); /*結束總線*/ return(1); } void Start_I2c() { SDA=1; /*發送起始條件的數據信號*/ _Nop(); SCL=1; _Nop(); /*起始條件建立時間大於4.7us,延時*/ _Nop(); _Nop(); _Nop(); _Nop(); SDA=0; /*發送起始信號*/ _Nop(); /* 起始條件鎖定時間大於4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0; /*鉗住I2C總線,準備發送或接收數據 */ _Nop(); _Nop(); } void SendByte(unsigned char c) { unsigned char BitCnt; for(BitCnt=0;BitCnt<8;BitCnt ) /*要傳送的數據長度為8位*/ { if((c< _Nop(); SCL=1; /*置時鐘線為高,通知被控器開始接收數據位*/ _Nop(); _Nop(); /*保證時鐘高電平週期大於4μs*/ _Nop(); _Nop(); _Nop(); SCL=0; } _Nop(); _Nop(); SDA=1; /*8位發送完後釋放數據線,準備接收應答位*/ _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; else ack=1; /*判斷是否接收到應答信號*/ SCL=0; _Nop(); _Nop(); } void Ack_I2c(bit a) { if(a==0)SDA=0; /*在此發出應答或非應答信號 */ else SDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); /*時鐘低電平週期大於4μs*/ _Nop(); _Nop(); _Nop(); SCL=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/ _Nop(); _Nop(); } |
scott123
中階會員 發表:19 回覆:66 積分:52 註冊:2011-08-11 發送簡訊給我 |
找到問題了在哪了
接資料應該是以下格式 I2C_Start(); Send_Comm(Write); Receive_ACK(); Send_Comm(0x00); Receive_ACK(); I2C_Start(); ///////////這裡 Send_Comm(Read); Receive_ACK(); data[1] = read_Comm(); Send_ACK(1); I2C_Stop(); 結果是在restart的地方出問題 start是在scl為1的時後,sda由1變0 在restart的時後,sda之前被拉成0了,拉成1之後,再拉成0 I2C誤認為stop,就這樣,改一下順序就好 scl先拉還是sda先拉,也是很重要的 這樣簡單的動作,害我找了兩個禮拜 不過不知道為什麼, 可以連續寫page write,但是只能一筆一筆讀, 連續讀只有第一筆正確,第二筆之後都是0x00,why |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |