|
技術(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總線問(wèn)題 |
作者:wanlian 欄目:IC設(shè)計(jì) |
各位好,小弟最近在玩一下I2C總線,可是用硬件真正做試驗(yàn),就是不出來(lái),我也仔細(xì)檢查了函數(shù),沒(méi)有發(fā)現(xiàn)什么錯(cuò)誤,敬請(qǐng)各位玩過(guò)I2C總線的指教,呵呵。 我用的是AT24C02,屬于E2PROM.現(xiàn)把我的函數(shù)發(fā)出來(lái),供大家欣賞。 void start(void)//開(kāi)始 { unsigned CHAR i; sda=1; scl=1; for(i=time;i<0;i--){} sda=0; for(i=time;i<0;i--){} } void stop(void)//結(jié)束 { unsigned CHAR i; sda=0; scl=1; for(i=time;i<0;i--){} sda=1; for(i=time;i<0;i--){} } void send(unsigned CHAR a)//發(fā)送一個(gè)字符函數(shù) { unsigned CHAR loop=8; unsigned CHAR TEMP=0; unsigned CHAR i=0; TEMP=a; for(;loop>0;loop--) { scl=0; for(i=time;i<0;i--){} if((0x80&TEMP)==0x80) sda=1; else sda=0; TEMP=TEMP<<1; scl=1; for(i=time;i<0;i--){} } sda=1; do { scl=0; for(i=time;i!=0;i--) {} scl=1; for(i=time;i!=0;i--) {} } while(sda); } unsigned CHAR read(void)//讀取一個(gè)字符函數(shù) { unsigned CHAR loop=8; unsigned CHAR dat=0; unsigned CHAR i; for(;loop>0;loop--) { scl=0; for(i=time;i<0;i--){} scl=1; for(i=time;i<0;i--){} if(sda==1) dat=dat|0x01; else dat=dat&0xfe; dat=dat<<1; } scl=0; sda=0; for(i=time;i<0;i--){} scl=1; for(i=time;i<0;i--){} scl=0; return dat; } void wr(unsigned CHAR add,unsigned CHAR num)//寫(xiě)一個(gè)字符 { start(); send(0xa0); send(add); send(num); stop(); } unsigned CHAR rd(unsigned CHAR add)//讀一個(gè)字符 { unsigned CHAR num; start(); send(0xa0); send(add); start(); send(0xa1); num=read(); stop(); return num; } |
2樓: | >>參與討論 |
作者: 1101334 于 2005/3/30 10:38:00 發(fā)布:
不懂 為何不用Verilog做?更簡(jiǎn)單. |
3樓: | >>參與討論 |
作者: echo_dream 于 2005/4/2 15:06:00 發(fā)布:
你的程序?qū)懙挠行┎环蟟2c協(xié)議,幾點(diǎn)建議 以前做過(guò)i2c,還記得些,以下是幾點(diǎn)建議: 1、SDA對(duì)MASTER和slave都是inout,在物理實(shí)現(xiàn)上i2c協(xié)議中說(shuō)得很明確,所以一般要在SDA上產(chǎn)生0信號(hào),是由MASTER或slave驅(qū)動(dòng)SDA為低電平,而產(chǎn)生1信號(hào),則是MASTER或slave不驅(qū)動(dòng)SDA,由上拉電阻自動(dòng)將SDA拉高。如果你寫(xiě)的程序是用單片機(jī)來(lái)實(shí)現(xiàn)i2c MASTER的功能,希望你的SDA=1表示的是不去驅(qū)動(dòng)SDA。 2、i2c協(xié)議中規(guī)定,SDA的變化發(fā)生在SCL為低電平時(shí),在設(shè)計(jì)時(shí),“一般”在SCL為低電平的“中點(diǎn)”變化。 你的程序void send(unsigned CHAR a)//發(fā)送一個(gè)字符函數(shù) 中,SDA的值變?yōu)橄乱粋(gè)要傳送的數(shù)據(jù)后,你的SCL“馬上”變?yōu)?。(從 SDA變化 到 SCL變?yōu)? 之間的時(shí)間,就你的程序而言,就是執(zhí)行TEMP=TEMP<<1;的時(shí)間,這個(gè)時(shí)間長(zhǎng)短就看你的系統(tǒng)了) 建議 發(fā)送一個(gè)字符函數(shù) 改動(dòng)如下: for(;loop>0;loop--) { scl=0; for(i=time;i<0;i--){} if((0x80&TEMP)==0x80) release sda; // <---- else sda=0; TEMP=TEMP<<1; for(i=time;i<0;i--){} // <---- time為SCL周期的1/4 release scl; // <---- for(i=time;i<0;i--){} for(i=time;i<0;i--){} // <---- } 而你的函數(shù)中的以下代碼,應(yīng)該是用來(lái)產(chǎn)生接收slave應(yīng)答的時(shí)鐘信號(hào)。 sda=1; do { scl=0; for(i=time;i!=0;i--) {} scl=1; for(i=time;i!=0;i--) {} } while(sda); 為什么要用do while呢?如果slave出錯(cuò),沒(méi)有給出ACK,你的程序就死在這了。此外,你還應(yīng)該在產(chǎn)生SCL的同時(shí),看slave是否給出了ACK信號(hào)(SDA為低電平)。如果沒(méi)有,就該報(bào)錯(cuò)并跳轉(zhuǎn)至出錯(cuò)處理程序段。建議改動(dòng)如下(僅適用于SINGLE MASTER的i2c系統(tǒng)): release sda; //以后應(yīng)該由slave驅(qū)動(dòng)sda產(chǎn)生ACK信號(hào) scl=0; for(i=time;i!=0;i--) {} for(i=time;i!=0;i--) {} release scl; if(sda) {跳轉(zhuǎn)到出錯(cuò)處理或結(jié)束} for(i=time;i!=0;i--) {} for(i=time;i!=0;i--) {} scl=0; for(i=time;i!=0;i--) {} 拋磚引玉,如果有什么不對(duì)的地方,相互交流:) |
免費(fèi)注冊(cè)為維庫(kù)電子開(kāi)發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 www.udpf.com.cn 浙ICP證030469號(hào) |