|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產業(yè) | CAN-bus/DeviceNe |
求助I2C 24LC02讀寫 |
| 作者:mikezhong 欄目:單片機 |
我現(xiàn)在調試一個I2C的程序,在SCL,SDA線根本都不能出現(xiàn)波形,請問大俠,這是怎回事啊? 我的硬件連接是24LC02 SCL,SDA分別接到RC3,RC4,WP接地,采取軟件方式,頁寫入一數(shù)組CODE到24LC02,起始地址為0X00,然后通過PORTD口的8個LED,自由方式讀出單個數(shù)據(jù),由8個LED檢查讀出的數(shù)據(jù)是否正確。 軟件如下: /******************************************************************* 程序說明: 1,24LC02器件地址是1010000R/W. 2,數(shù)組寫入24LC02采取頁寫方式. 3,數(shù)組從24LC02讀出時采取自由讀方式. 4,采用4。00M晶體。 *******************************************************************/ #include "pic.h" #define uCHAR unsigned CHAR #define nop() asm("nop" #define SCL RC3 #define SDA RC4 void start_i2c(); void stop_i2c(); void send_byte(uCHAR c); uCHAR receive_byte(); bit I_send_str(uCHAR sla,uCHAR suba,uCHAR *s,uCHAR no); void delay_250ms(); uCHAR code[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; uCHAR no,ack,c; void main(void) { TRISC=0X7F; //C口設為輸入 RC3為SCL線,RC4為SDA線。 PORTC=0X80; TRISD=0X00; //D口為輸出,顯示IC24LC01中的內容 PORTD=0X00; //初始顯示全亮 RC7=0; //頁寫入指示 I_send_str(0xa0,0x00,code,9); //頁寫入code數(shù)組到24LC02,器件地址為0Xa0,子地址為0X00,共9個數(shù)。 delay_250ms(); delay_250ms(); RC7=1; //頁寫完畢,開始讀,RC7指示燈滅。 ///////////開始讀出到D口進行顯示,根據(jù)Rondan read時序圖。 while (1) { start_i2c(); send_byte(0xa0); //發(fā)送器件地址,即DEVICE ADDRESS。 if (ack==0) RC7=0; send_byte(0x01); //發(fā)送字地址,即WORD ADDRESS。D口顯示0b00000001. if (ack==0) RC7=0; start_i2c(); //重新啟動總線。 send_byte(0xa1); //發(fā)送讀命令和器件地址DEVICE ADDRESS。 if (ack==0) RC7=0; PORTD=receive_byte(); stop_i2c(); } } /******************************************************************* 起動總線函數(shù) 函數(shù)原型: void start_i2c(); Function: start on the I2C bus *******************************************************************/ void start_i2c() { SDA=1; //發(fā)送啟始條件的數(shù)據(jù)信號 nop(); SCL=1; nop();nop();nop();nop();nop(); //24LC02要求建立時間大于4,7S SDA=0; //發(fā)送起始信號 nop();nop();nop();nop();nop(); SCL=0; //鉗住I2C總線,準備發(fā)送數(shù)據(jù)或接收數(shù)據(jù) nop();nop(); } /******************************************************************* 停止總線函數(shù) 函數(shù)原型: void stop_i2c(); Function: stop the I2C bus *******************************************************************/ void stop_i2c() { SDA=0; //發(fā)送結束條件的數(shù)據(jù)信號 nop(); SCL=1; nop();nop();nop();nop();nop(); SDA=1; nop();nop();nop();nop(); } /*================================================================= 字節(jié)數(shù)據(jù)傳送函數(shù) 函數(shù)原型: void send_byte(uCHAR c); Function: 將數(shù)據(jù)C發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待回應,并對此狀態(tài) 位進行操作(不應答或非應答都使ack=0 ),發(fā)送數(shù)據(jù)正常,ack=1;ack=0 表示被控器無應答或損壞。 ==================================================================*/ void send_byte(uCHAR c) { uCHAR bit_count; for (bit_count=0;bit_count<8;bit_count++) { if ((c<<bit_count)&0x80) SDA=1; else SDA=0; nop(); SCL=1; nop();nop();nop();nop();nop(); SCL=0; } nop();nop(); SDA=1; nop();nop(); SCL=1; nop();nop();nop(); if (SDA==1) ack=0; else ack=1; SCL=0; nop();nop(); } /*================================================================== 字節(jié)數(shù)據(jù)接收函數(shù) 函數(shù)原型:uCHAR receive_byte(); FUNCTION: 用來接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應答信號), 發(fā)完后請用應答函數(shù)。 ===================================================================*/ uCHAR receive_byte() { uCHAR retc,bit_count; retc=0; SDA=1; for (bit_count=0;bit_count<8;bit_count++) { nop(); SCL=0; nop();nop();nop();nop();nop(); SCL=1; nop();nop(); retc=retc<<1; if (SDA==1) retc=retc+1; nop();nop(); } SCL=0; nop();nop(); return (retc); } /*================================================================ 向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù) 函數(shù)原型: bit I_send_str(uCHAR sla,uCHAR suba,uCHAR *s,uCHAR no); Function: 從啟動總線到發(fā)送地址,數(shù)據(jù),結束總線的全過程,從器件地址sla。如果 返回1表示操作成功,否則操作有誤。 =================================================================*/ bit I_send_str(uCHAR sla,uCHAR suba,uCHAR *s,uCHAR no) { uCHAR i; start_i2c(); send_byte(sla); if (ack==0) return(0); send_byte(suba); if (ack==0) return(0); for (i=0;i<no;i++) { send_byte(*s); if (ack==0) return(0); s++; } stop_i2c(); return(1); } /***************************************************************** 延時函數(shù) 函數(shù)原型: void delay_250ms(); FUNCTION: 延明250ms *****************************************************************/ void delay_250ms() { unsigned int d=24999; while (--d); } /**********END**************/ |
| 2樓: | >>參與討論 |
| 作者: xieyuanbin 于 2005/1/9 13:57:00 發(fā)布:
軟件模擬I2C條件: 1.數(shù)據(jù)及時鐘線均接上拉電阻,不得有電容接入. 2.輸出高電平時端口設置成輸入(高阻) 3.輸出低電平時先向端口寫0,然后設置成輸出即可 4.嚴格按照I2C協(xié)議改變端口狀態(tài). 5.建議使用匯編. * - 本貼最后修改時間:2005-1-9 13:59:18 修改者:xieyuanbin |
|
| 3樓: | >>參與討論 |
| 作者: cyw701 于 2005/1/9 14:22:00 發(fā)布:
24C02讀寫程序 http://www.pe.gxnu.edu.cn/cx/ 朋友,不妨到這個網站看一下,里面有24C02讀寫程序! |
|
| 4樓: | >>參與討論 |
| 作者: mikezhong 于 2005/1/9 15:17:00 發(fā)布:
難道是AT24LC02壞了? 謝謝兩位大俠!數(shù)據(jù)線和時鐘線均接了10K上拉電阻,沒有接電容,端口設為輸入方式,就是不見總線上有波形,總線根本就沒有開始?cyw701大俠推薦的網站,我看了,和我的程序一致,我寫的24C02地址是0XA0,存儲地址是0X00開始,難道是AT24LC02壞了? 謝大俠第3點: 3.“輸出低電平時先向端口寫0,然后設置成輸出即可” 如果我要使SDA線=0,是否先向SDA(RC3)寫入0,然后再使TRISC=0X00,從而在總線上得到低電平? |
|
| 5樓: | >>參與討論 |
| 作者: xieyuanbin 于 2005/1/10 8:15:00 發(fā)布:
不錯 "如果我要使SDA線=0,是否先向SDA(RC3)寫入0,然后再使TRISC=0X00,從而在總線上得到低電平?" 就是這樣 |
|
| 6樓: | >>參與討論 |
| 作者: mikezhong 于 2005/1/11 10:11:00 發(fā)布:
能否這樣對相應的端口設置TRISC.3=1;TRISC.4=1;? 各位大俠,既然按照上面的操作,我可以首先使SDA(RC3),SCL(RC4)初始化為“0”,然后,程序中要使SDA為1時,我只要將TRISC設為輸入,輸出0時,TRISC設為輸出,但這樣一定會影響PORTC的其它端口設置,請問各位大俠,此端口設置能否像端口PORT一樣進行位操作?能否這樣對相應的端口設置TRISC.3=1;TRISC.4=1;? |
|
| 7樓: | >>參與討論 |
| 作者: xieyuanbin 于 2005/1/11 11:12:00 發(fā)布:
可以的. PIC的所有寄存器都支持位操作. |
|
| 8樓: | >>參與討論 |
| 作者: mikezhong 于 2005/1/11 16:47:00 發(fā)布:
為什么我總是不能接收到24LC24的應答信號 大俠能否幫我看一下程序?為什么我總是不能接收到24LC24的應答信號,程序進入總線錯誤子程序!很苦惱!總線開始和結束都正常。 /******************************************************************* 程序說明: 1,24LC02器件地址是1010000R/W. 2,數(shù)組寫入24LC02采取頁寫方式. 3,采用4。00M晶體。 *******************************************************************/ #include "pic1687x.h" #define uCHAR unsigned CHAR #define nop() asm("nop" #define SCL TRISC3 #define SDA TRISC4 void start_i2c(); void stop_i2c(); void send_byte(uCHAR c); void I_send_str(uCHAR sla,uCHAR suba,uCHAR s); void delay_250ms(); void i2c_error (); uCHAR ack,c; void main(void) { TRISC=0Xff; //C口設為輸入 RC3為SCL線,RC4為SDA線。 PORTC=0X00; TRISD=0X00; //D口為輸出,顯示IC24LC02中的內容 PORTD=0X00; //初始顯示全亮 while(1) { I_send_str(0xa0,0x01,0x0f);//頁寫入0x0f到24LC02,器件地址為0Xa0,子地址為0X01 } } /******************************************************************* 起動總線函數(shù) 函數(shù)原型: void start_i2c(); Function: start on the I2C bus *******************************************************************/ void start_i2c() { SDA=1; //發(fā)送啟始條件的數(shù)據(jù)信號 nop(); SCL=1; nop();nop();nop();nop();nop(); //24LC02要求建立時間大于4,7S SDA=0; //發(fā)送起始信號 nop();nop();nop();nop();nop(); SCL=0; //鉗住I2C總線,準備發(fā)送數(shù)據(jù)或接收數(shù)據(jù) nop();nop(); } /******************************************************************* 停止總線函數(shù) 函數(shù)原型: void stop_i2c(); Function: stop the I2C bus *******************************************************************/ void stop_i2c() { SDA=0; //發(fā)送結束條件的數(shù)據(jù)信號 nop(); SCL=1; nop();nop();nop();nop();nop(); SDA=1; nop();nop();nop();nop(); } /*================================================================= 字節(jié)數(shù)據(jù)傳送函數(shù) 函數(shù)原型: void send_byte(uCHAR c); Function: 將數(shù)據(jù)C發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待回應,并對此狀態(tài) 位進行操作(不應答或非應答都使ack=0 ),發(fā)送數(shù)據(jù)正常,ack=1;ack=0 表示被控器無應答或損壞。 ==================================================================*/ void send_byte(uCHAR c) { uCHAR bit_count; for (bit_count=0;bit_count<8;bit_count++) { if ((c<<bit_count)&0x80) {SDA=1;} else {SDA=0;} nop(); SCL=1; nop();nop();nop();nop();nop(); SCL=0; } nop();nop(); SDA=1; nop();nop(); SCL=1; nop();nop();nop(); if (RC4==1) ack=0; else ack=1; //ASK=1為有應答信號 SCL=0; nop();nop(); } /*================================================================ 向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù) 函數(shù)原型: bit I_send_str(uCHAR sla,uCHAR suba,uCHAR s); Function: 從啟動總線到發(fā)送地址,數(shù)據(jù),結束總線的全過程,從器件地址sla。如果 返回1表示操作成功,否則操作有誤。 =================================================================*/ void I_send_str(uCHAR sla,uCHAR suba,uCHAR s) { start_i2c(); send_byte(sla); if (ack==0) i2c_error(); send_byte(suba); if (ack==0) i2c_error(); send_byte(s); if (ack==0) i2c_error(); stop_i2c(); } /***************************************************************** 延時函數(shù) 函數(shù)原型: void delay_250ms(); FUNCTION: 延明250ms *****************************************************************/ void delay_250ms() { unsigned int d=24999; while (--d); } /***************************************************************** 總線錯誤函數(shù) 函數(shù)原型: void i2c_error(); Function: 通過RD7閃動8次表示總線操作失敗一次報警。 *****************************************************************/ void i2c_error () { uCHAR i; for (i=0;i<8;i++) { RD7=0; delay_250ms(); RD7=1; delay_250ms(); } } /**********END**************/ |
|
|
|
| 免費注冊為維庫電子開發(fā)網會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |