|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
為答謝大家,現(xiàn)將已調(diào)通的"I/O口模擬I2C字節(jié)讀寫"源碼貢獻于此 |
| 作者:碧水長天 欄目:單片機 |
感謝大家對小弟關于“動態(tài)掃描顯示電路亮度不夠的問題”的熱心指點,無以為謝,特將剛調(diào)試通過的單片機I/O口模擬I2C協(xié)議字節(jié)讀寫的源碼貢獻于此,希望能給有需要的站友帶來便利。 順便聲明一下:這里只用到字節(jié)讀寫,有關字讀寫的函數(shù)我也擴充了,但發(fā)現(xiàn)讀寫均無效果(用燒錄器發(fā)現(xiàn)24C02內(nèi)部數(shù)據(jù)未改變),但是我將字讀寫函數(shù)擴充了,貼在最后,請高手指點,看看紕漏在什么地方,謝謝。 以下為源代碼,共享之。 ------ sbit I2C_SCL = P3^6; //移植時需重寫 sbit I2C_SDA = P3^7; //移植時需重寫 void Delay_Xms(uint x_ms) //延時函數(shù),最大為65536ms { uint i; uchar j; for (i = 0; i < x_ms; i++) for (j = 0; j < 120; j++) ;//Fosc=12MHZ } void I2C_Wait(void) { ; } void I2C_Start(void) //當SCL為高時,SDA由高到低,開始,然后SCL到低 { I2C_SDA = 1; I2C_SCL = 1; I2C_Wait(); I2C_SDA = 0; I2C_Wait(); I2C_SCL = 0; } void I2C_Stop(void) //當SCL為高時,SDA由低到高 { I2C_SDA = 0; I2C_Wait(); I2C_SCL = 1; I2C_Wait(); I2C_SDA = 1; } bit I2C_Send_Byte(uchar bytedata) //sent bytedata to slave DEVICE { uchar i; bit ack; for (i = 0; i < 8; i++) // { if (bytedata & 0x80) I2C_SDA = 1; else I2C_SDA = 0; bytedata <<= 1; I2C_Wait(); I2C_SCL = 1; I2C_Wait(); I2C_SCL = 0; I2C_Wait(); } I2C_SDA = 1; //發(fā)送器件釋放SDA線 I2C_Wait(); I2C_SCL = 1; //產(chǎn)生第九個脈沖的高電平 I2C_Wait(); ack = I2C_SDA; //接收從器件的確認位 I2C_SCL = 0; I2C_Wait(); return ack; } uchar I2C_Receive_Byte(void) //read bytedata from slave DEVICE { uchar i; uchar bytedata = 0; for ( i = 0; i < 8; i++) { I2C_SCL = 1; I2C_Wait(); bytedata <<= 1; if (I2C_SDA) bytedata |= 0x01; //若SDA=1,則將接收到的數(shù)據(jù)加1(bit0設為1),否則但左移一位時就將bit0自動清0 I2C_SCL = 0; I2C_Wait(); } return bytedata; } void Send_Ack(bit ack) //send ack(1 or 0) to slave DEVICE:ACK=0.NON-ACK=1 { I2C_SDA = ack; I2C_SCL = 1; I2C_Wait(); I2C_SCL = 0; } //任意設備任意地址寫入一字節(jié)數(shù)據(jù) void I2C_Byte_Write(uchar DEVICE_ID,uchar address,uchar bytedata) { uchar i; bit ack; Flag_Timeout = 1; for(i = 0; i < 10; i++) //time out,retry=10 { I2C_Start(); ack = I2C_Send_Byte(DEVICE_ID); if (ack) { I2C_Stop(); continue; } ack = I2C_Send_Byte(address); if (ack) { I2C_Stop(); continue; } ack = I2C_Send_Byte(bytedata); if (ack) { I2C_Stop(); continue; } I2C_Stop(); Flag_Timeout = 0; if(0 == ack) break; } Delay_Xms(10); //EEPROM每寫入一個字節(jié)必須延遲10ms } uchar I2C_Byte_Read(uchar DEVICE_ID,uchar address) { uchar bytedata; I2C_Start(); I2C_Send_Byte(DEVICE_ID); I2C_Send_Byte(address); I2C_Start(); I2C_Send_Byte(0xa1); //發(fā)送 讀控制字 0xa1 bytedata = I2C_Receive_Byte(); Send_Ack(1); I2C_Stop(); return bytedata; } //write byte data into EEPROM24C02 void EEPROM_Byte_Write(uchar addr,uchar VALUE) { I2C_Byte_Write(0xa0,addr,VALUE); //24C02 's DEVICE id is 0xa0 } uchar EEPROM_Byte_Read(uchar addr) { return(I2C_Byte_Read(0xa0,addr)); } //字節(jié)讀寫代碼完畢 //下面為擴充的字讀寫函數(shù),調(diào)試時似乎不能讀寫數(shù)據(jù),請高手幫忙看看,謝謝! ------------------------ void EEPROM_Word_Write(uchar addr,uint VALUE) { I2C_Byte_Write(0xa0,addr,((uchar)(VALUE>>8))); //高8位寫入 I2C_Byte_Write(0xa0,(addr+1),((uchar)(VALUE))); //低八位數(shù)據(jù),寫入"地址+1"的空間 } uint EEPROM_Word_Read(uchar addr) { uint datatmp = 0; datatmp = (uint)I2C_Byte_Read(0xa0,addr);   |
| 2樓: | >>參與討論 |
| 作者: 最愛韶涵 于 2005/7/12 23:01:00 發(fā)布:
#include <IIC_zlgmcu_com.h> /* MODIFIED by youfeng */ |
|
| 3樓: | >>參與討論 |
| 作者: hotpower 于 2005/7/12 23:05:00 發(fā)布:
函數(shù)名搞得太多... http://www.21icbbs.com/club/bbs/showessence.asp?id=6494 |
|
| 4樓: | >>參與討論 |
| 作者: lizhongyi 于 2005/7/17 11:23:00 發(fā)布:
好啊 |
|
| 5樓: | >>參與討論 |
| 作者: sulin1 于 2005/7/18 12:21:00 發(fā)布:
這個I/O模擬I2C應該很成熟了 網(wǎng)上相關程序很多,仔細比較一下,就會解決的 |
|
| 6樓: | >>參與討論 |
| 作者: wincpu 于 2005/7/18 12:26:00 發(fā)布:
好人啊,正在找呢 |
|
| 7樓: | >>參與討論 |
| 作者: 不愛說話 于 2005/7/18 13:32:00 發(fā)布:
我試了你的程序,不好使. 不知怎么回事,寫入字節(jié)部分還可以能使,就是讀字節(jié)部分可能有問題,讀回來的全是FFH,是編譯的時候有些選項需要設置嗎? |
|
| 8樓: | >>參與討論 |
| 作者: chenlr217 于 2005/7/18 13:56:00 發(fā)布:
好象有些不妥 |
|
| 9樓: | >>參與討論 |
| 作者: 劍寒情暖 于 2005/7/18 16:35:00 發(fā)布:
碧水長天 你在字寫入的時候高字節(jié)和低字節(jié)寫入之間加一點延時看看 * - 本貼最后修改時間:2005-7-18 16:43:32 修改者:劍寒情暖 |
|
| 10樓: | >>參與討論 |
| 作者: 碧水長天 于 2005/7/18 17:11:00 發(fā)布:
解釋一下: 讀字節(jié)時注意“I2C_Send_Byte(0xa1); //注意:發(fā)送 讀控制字 0xa1 ”發(fā)送的是0xa1。 uchar I2C_Byte_Read(uchar device_ID,uchar address) { uchar bytedata; I2C_Start(); I2C_Send_Byte(device_ID); I2C_Send_Byte(address); I2C_Start(); I2C_Send_Byte(0xa1); //注意:發(fā)送 讀控制字 0xa1 bytedata = I2C_Receive_Byte(); Send_Ack(1); I2C_Stop(); return bytedata; } ----------- 另外,若晶振頻率較高,則可在I2C_Wait(void)里加些延時。 void I2C_Wait(void) { ; } |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |