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