|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
看了半天TWI資料寫出操作EEPROM程序并不見得很好.請大蝦指點 |
| 作者:lism 欄目:單片機 |
利用AVR的TWI操作I2C E2PROM并不見得方便 。反而其仲裁功能要是遇上器件損壞時候,會傻等!請大蝦們指點! |
| 2樓: | >>參與討論 |
| 作者: hotpower 于 2006/12/31 6:43:00 發(fā)布:
愿聽其解,謝謝!!! * - 本貼最后修改時間:2006-12-31 6:43:50 修改者:hotpower |
|
| 3樓: | >>參與討論 |
| 作者: lism 于 2006/12/31 13:05:00 發(fā)布:
呵呵。高手來了。趕緊發(fā)問。 TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//發(fā)送STAR while (!(TWCR&(1<<TWINT)));//就這里,如果總線為短路。得不到控制權(quán),那么單片機就定在哪里了。 |
|
| 4樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/2 2:34:00 發(fā)布:
倒塌了~~~我以為樓主的村里有什么高招呢??? 這個問題本來就計劃在水潭里的尿童學堂里論述,想先聽聽樓主的高招,沒想到樓主止步了,真倒塌了~~~ 在程序的安全設(shè)計上,對于這些需要檢測硬件的回控信號后再進一步運行的程序,有很多需要考慮的細節(jié). 1.無硬件看門狗或有硬件看門狗時. 2.硬件次要或主要時. 3.中斷或查詢時. 先以樓主的程序為例: TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//發(fā)送STAR while (!(TWCR&(1<<TWINT)));//就這里,如果總線為短路。得不到控制權(quán),那么單片機就定在哪里了。 在無硬件看門狗時: 當發(fā)送START信號后,若出現(xiàn)TWINT一直低電平時,即使總中斷開啟并其他中斷正常運行時,都將永遠踏步死機. 如果系統(tǒng)設(shè)計為I2C數(shù)據(jù)很重要,無它系統(tǒng)沒意義必須重新啟動時,此程序片段就如PC藍屏需要人工重新啟動,倒也可行. 若數(shù)據(jù)不重要,即TWI接口壞可以放棄時,此程序就不對了. 應(yīng)該用一個軟件計數(shù)器或定時器在一定間隔內(nèi),若TWINT恒為0,就設(shè)置錯誤標志后退出while死循環(huán). 即: TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//發(fā)送STAR while (!(TWCR&(1<<TWINT)));//就這里,如果總線為短路。得不到控制權(quán),那么單片機就定在哪里了。 unsigned CHAR TWStart(void) { unsigned CHAR error = 1;//失敗 unsigned int i; TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//發(fā)送STAR for (i = 0; i < 0x....; i ++) {//時間間隔自定 if (TWCR&(1<<TWINT)) {//成功 error = 0; break; } } return error;//成功返回0 } 當系統(tǒng)檢測不通過就無法繼續(xù)運行需要復(fù)位時,基本如下所述的方法. 具體很難說清... 在有硬件看門狗時,喂狗信號的位置也比較有講究,特別是在長等待時. 一般原則是喂狗信號不能套入while內(nèi),應(yīng)該修改為: wdt_reset();// Watchdog復(fù)位 while(...){ };//只要保證測試時間不超過Watchdog定時器復(fù)位時間 如果測試時間不夠,可修改為: for(i = 0;i < N;i++) { wdt_reset();// Watchdog復(fù)位 while(...){ };//只要保證測試時間不超過Watchdog定時器復(fù)位時間/N } 而不應(yīng)該: while(...){ wdt_reset();// Watchdog復(fù)位 } 總之,我們養(yǎng)狗絕非害人甚至害自己!!! 因為即使器件硬件錯誤,我們只認為是I2C通訊失敗但系統(tǒng)其他更重要的設(shè)備 還要正常地運行,不能因為局部錯誤而復(fù)位整個系統(tǒng). * - 本貼最后修改時間:2007-1-2 2:52:35 修改者:hotpower |
|
| 5樓: | >>參與討論 |
| 作者: lism 于 2007/1/5 0:49:00 發(fā)布:
倒~~原以為是高手,卻是個尿童! 你說的大部分人都做。 等待計時,跟用軟件延時沒有太多的區(qū)別。單片機一樣停止運行其它程序。 個人認為TWI在操作EEPROM上,除了電平變化特征有優(yōu)勢,在方便應(yīng)用上沒有很多的優(yōu)勢。 * - 本貼最后修改時間:2007-1-5 0:56:47 修改者:lism |
|
| 6樓: | >>參與討論 |
| 作者: gtw 于 2007/1/5 8:19:00 發(fā)布:
TWI也不錯,至少在時序控制上好得多 問題是樓主這兒 不管什么,等待總不能死等,一定要加超時判斷 |
|
| 7樓: | >>參與討論 |
| 作者: xwj 于 2007/1/5 9:23:00 發(fā)布:
能深入思考是好的,要養(yǎng)成考慮和處理各種異常的習慣, 你就離高手的距離更近了 lism ,不管TWI有沒有優(yōu)勢或劣勢,編程時都必須要考慮各種異常的 |
|
| 8樓: | >>參與討論 |
| 作者: BitFu 于 2007/1/5 10:43:00 發(fā)布:
器件都損壞了還要這系統(tǒng)干什么 要不做個異步定時器監(jiān)督,超時退出。TWI還是很好用的。 |
|
| 9樓: | >>參與討論 |
| 作者: gtw 于 2007/1/5 12:48:00 發(fā)布:
不處理異常,很多情況下就等于交出控制權(quán) |
|
| 10樓: | >>參與討論 |
| 作者: lism 于 2007/1/5 15:14:00 發(fā)布:
不同場合有不同措施吧。 BitFu 發(fā)表于 2007-1-5 10:43 AVR 單片機 ←返回版面 8樓: 器件都損壞了還要這系統(tǒng)干什么 我們是做工業(yè)機器的,不能因為器件壞了,而機器沒有反映。 實時性也比較高,不能一直在等待一個器件反映。 |
|
| 11樓: | >>參與討論 |
| 作者: BitFu 于 2007/1/5 23:52:00 發(fā)布:
那到也是 我使用的場合正好相反,哈哈 我用TWI控制一外部實時時鐘,根據(jù)時鐘對某工業(yè)設(shè)備進行操作 如從幾點到幾點工作 用戶要求是寧可停止也不誤動作,如果器件損壞我的AVR就會停止在那里,直到人類來處理,他相信TWI通信如同相信自己的I/O口一樣。 當時我也想過實現(xiàn)象應(yīng)用層那樣的全能錯誤處理機制,可惜不能實現(xiàn)。例如我的單片機無法判斷每一個I/O引用是否損壞。就算知道了也不能決定下一步要干什么,因為硬件已經(jīng) 壞掉了。 究竟如何處理硬件損壞歡迎大家探討。! |
|
| 12樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/6 0:14:00 發(fā)布:
我認為有TWI硬件接口還需模擬I2C??? 應(yīng)該利用FIFO的思想去控制TWI,數(shù)據(jù)不一定非要同步處理,為什么不可以做異步處理呢??? 實際測試TWI損壞也很簡單,在一定的時間范圍內(nèi)重試N次后從機無應(yīng)答肯定壞了. 當然也可先用IO測試SCL,SDA是否釋放總線.然后在啟動TWI功能. TWI的硬件處理機制很完美,任何錯誤都可能以捕捉到,中斷事件處理難道還要用軟件IO模擬嗎??? 應(yīng)用好TWI的硬件模塊,對其操作根本不羅嗦,為什么我們還要停留在51的概念和陰影下呢??? |
|
| 13樓: | >>參與討論 |
| 作者: BitFu 于 2007/1/6 9:47:00 發(fā)布:
響應(yīng)HOTPOWER發(fā)一個FIFO控制模塊 頭文件 : #ifndef QUEUE_H_ #define QUEUE_H_ //隊列數(shù)據(jù)結(jié)構(gòu) typedef struct QUEUE_S { uint8 in_index;//入隊地址 uint8 out_index;//出隊地址 uint8 buf_size; //緩沖區(qū)長度 uint8 *pBuffer;//緩沖 volatile uint8 data_count; //隊列內(nèi)數(shù)據(jù)個數(shù) uint8 error; }HQUEUE,*PHQUEUE; void QueueInput(PHQUEUE Q,uint8 dat); uint8 QueueOutput(PHQUEUE Q); uint8 QueueGetDataCount(PHQUEUE Q); void QueueClear(PHQUEUE Q); void QueueCreate(PHQUEUE Q,uint8 *buffer,uint8 buf_size); #endif |
|
| 14樓: | >>參與討論 |
| 作者: BitFu 于 2007/1/6 9:48:00 發(fā)布:
實現(xiàn)文件 //向隊列插入一字節(jié) void QueueInput(PHQUEUE Q,uint8 dat) { if(Q->data_count < Q->buf_size) { Q->pBuffer[Q->in_index]=dat; //寫入數(shù)據(jù) Q->in_index=(Q->in_index+1) % (Q->buf_size);//調(diào)整入口地址 Q->data_count++; //調(diào)整數(shù)據(jù)個數(shù)(此操作不可被中斷) } else { if(Q->error<255) Q->error++; } } //從隊列讀出一字節(jié) uint8 QueueOutput(PHQUEUE Q) { uint8 Ret=0; if(Q->data_count > 0) { Ret=Q->pBuffer[Q->out_index]; //讀數(shù)據(jù) Q->out_index=(Q->out_index+1) % (Q->buf_size); //調(diào)整出口地址 Q->data_count--; } return Ret; } //獲得隊列中數(shù)據(jù)個數(shù) uint8 QueueGetDataCount(PHQUEUE Q) { return Q->data_count; } //清空隊列,執(zhí)行時不可被中斷 void QueueClear(PHQUEUE Q) { Q->in_index=0; Q->out_index=0; Q->data_count=0; Q->error=0; } //初始化一隊列 void QueueCreate(PHQUEUE Q,uint8 *buffer,uint8 buf_size) { Q->pBuffer=buffer; Q->buf_size=buf_size; QueueClear(Q); } |
|
| 15樓: | >>參與討論 |
| 作者: lism 于 2007/1/11 2:14:00 發(fā)布:
謝謝各位! 多謝BitFu大蝦分享經(jīng)驗!有時間研究一下。 |
|
| 16樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/12 19:17:00 發(fā)布:
哈哈~~~BitFu大蝦厲害~~~ |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |