|
|||||||||||
| 技術(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 |
arm指令集位操作有問題。! |
| 作者:wxpmy 欄目:ARM技術(shù) |
問題:arm的指令系統(tǒng)操作位變量有問題。。。。!難道arm不能用了。。 定義的位變量如下: struct { uint bzw0:1; uint bzw1:1; uint bzw2:1; uint bzw3:1; uint bzw4:1; uint bzw5:1; uint bzw6:1; uint bzw7:1; ... ... uint bzw31:1; }bit; 在內(nèi)存中的存儲形式如下: 假定存儲單元的名稱為ulongbzw,則32位的ulongbzw的存儲形式為: 位號:31 30 ...... 1 0 bzw31 bzw30 ...... bzw1 bzw0 假如主函數(shù)main.C中對bit.bzw0進行賦值操作,在定時中斷(假定1ms)中對bit.bzw2~bzw4進行賦值操作,就會出問題!。 簡要程序如下: 主循環(huán)程序: main() { ... while(1) { ... ... bit.bzw0=1; ... ... } } 1ms中斷程序: interrupt time0() { ... ... bit.bzw2=1; bit.bzw3=1; bit.bzw4=1; ... } 主循環(huán)中的bit.bzw0=1編譯成匯編的代碼為: 1) ldr r0,0x8000f958 ;提取bit.bzw0所在單元的地址(0x8000f958中存儲的是ulongbzw的地址) 2) ldr r0,[r0,#0] ;將ulongbzw的值賦給r0 3) orr r0,r0,#1 ;將r0的第0位(即bit.bzw0)賦1后存儲在r0中 4) ldr r1,0x8000f958 ; 5) str r0,[r1,#0] ;將r0的內(nèi)容存儲進ulongbzw的ram中,至此實現(xiàn)了對bit.bzw0=1的操作 假如在2) 和5)之間發(fā)生了中斷,中斷中執(zhí)行的是對bit.bzw2~bit.bzw4進行賦值的程序,中斷中成功的對bit.bzw2~bit.bzw4進行賦值了,但是當(dāng)中斷返回時執(zhí)行5)時又用原來的ulongbzw單元的內(nèi)容(r0中)刷新了經(jīng)過中斷操作后的 ulongbzw單元的內(nèi)容,結(jié)果是造成了中斷中的對bit.bzw2~bit.bzw4進行賦值的操作跳回到主循環(huán)后又恢復(fù)成0,造成邏輯紊亂!。! 如果再次進入中斷,且沒有上述的巧合的情況下bit.bzw2~bit.bzw4的賦值操作就成功了,但是bit.bzw2~bit.bzw4出現(xiàn)的毛刺是會影響邏輯的!!極限情況:如果一直在2) 和5)之間發(fā)上中斷,豈不是bit.bzw2~bit.bzw4一直處于0-1-0-1的跳變中。!這對程序邏輯來說是不能容忍的! * - 本貼最后修改時間:2007-5-9 10:53:45 修改者:wxpmy |
| 2樓: | >>參與討論 |
| 作者: 柔月 于 2007/5/9 10:03:00 發(fā)布:
先關(guān)中斷,操作完成后再開 |
|
| 3樓: | >>參與討論 |
| 作者: djyos 于 2007/5/9 10:27:00 發(fā)布:
故弄玄虛 會的人太多了. |
|
| 4樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/9 10:34:00 發(fā)布:
難道別人就沒出過問題! 不行,主循環(huán)中操作位變量的地方實在是太多了。!這樣作也太不可取了!IO口的輸出操作也存在類似的問題。。《矣行﹫龊鲜呛芪kU的!我在示波器上清楚的看到io口輸出的毛刺。。 |
|
| 5樓: | >>參與討論 |
| 作者: ap9805411 于 2007/5/9 10:36:00 發(fā)布:
能做你師父的太多了。 怕你孝敬不起啊。 不過話說回來,別人也未必想當(dāng)你師父。下次如果是想請教問題,還是別搞這么多花樣了。 |
|
| 6樓: | >>參與討論 |
| 作者: netjob 于 2007/5/9 10:38:00 發(fā)布:
TMD!SB問題。 wxpmy! |
|
| 7樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/9 10:43:00 發(fā)布:
大哥 我是真的遇到問題了!!程序不正常! 能對ram區(qū)直接尋址的單條指令是不會有這個問題的!但是arm中的或操作是要用r寄存器導(dǎo)一下來操作的,所以出了這種問題 |
|
| 8樓: | >>參與討論 |
| 作者: computer00 于 2007/5/9 10:57:00 發(fā)布:
這樣的操作必須要關(guān)中斷的。 在中斷里面賦值時,就要考慮到這個問題。保持?jǐn)?shù)據(jù)的完整性。例如8位機中使用32位的LONG int,同樣存在這這樣的問題。最簡單的辦法就是關(guān)中斷。如果你嫌麻煩,可以寫成宏。 |
|
| 9樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/9 10:59:00 發(fā)布:
computer00 前輩 寫成宏怎么寫!能避免這個問題么? |
|
| 10樓: | >>參與討論 |
| 作者: computer00 于 2007/5/9 11:08:00 發(fā)布:
就是將關(guān)中斷和位操作放在一起做為一個宏,跟函數(shù)差不多的 |
|
| 11樓: | >>參與討論 |
| 作者: djyos 于 2007/5/9 11:13:00 發(fā)布:
51后遺癥 你原來用的可能是51吧,51確實可以用一條指令操作一個IO口,所以其操作過程是不會被打斷的.但每種機器都有它的特點,有優(yōu)點也有缺點,需要學(xué)習(xí)掌握,然后靈活使用,而不是抱怨! 51是cisc指令集,指令集豐富,在操作io口上比arm方便,這是優(yōu)點,但其數(shù)據(jù)處理能力低下,是其弱點。 ARM是risc指令集,不能直接操作內(nèi)存(io也映射成內(nèi)存),需要用寄存器倒騰一下,是其弱點,但它的計算能力強,尋址范圍大,51一條指令時間ARM甚至可以執(zhí)行數(shù)十條指令,且是32位的,是其優(yōu)點。 這樣下來,操作io的指令,如果不容中斷的話,是要關(guān)中斷的,把關(guān)中斷和開中斷的時間也算進去,沒有cache或者cache不命中的話,ARM并不會比51快。 如果你的應(yīng)用中盡是些io操作,不妨用51。 圈圈版主已經(jīng)告訴你應(yīng)該怎樣做了,再說明白點,就是把開關(guān)中斷和操作io的代碼做成一個宏。 |
|
| 12樓: | >>參與討論 |
| 作者: 農(nóng)民講習(xí)所 于 2007/5/9 11:19:00 發(fā)布:
一般不這樣設(shè)計 好的程序就是要減少主程序(非實時)和中斷程序(實時任務(wù))的耦合性,所以采用了很多驅(qū)動技術(shù):消息,隊列等緩沖接口. 處理實時任務(wù)的過程就是: 中斷程序(實時任務(wù))->可被嵌套的中斷程序(弱實時)->主程序(非實時),是有個階梯層次的. |
|
| 13樓: | >>參與討論 |
| 作者: 農(nóng)民講習(xí)所 于 2007/5/9 11:23:00 發(fā)布:
比如你這個程序 只要再增加只在一個中斷中struct bit變量就可以解決,而在主循環(huán)中對該變量進行查詢->清除->寫入主循環(huán)struct bit變量這個過程就可以,這是最低級的緩沖接口方式. |
|
| 14樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/9 19:19:00 發(fā)布:
謝謝各位前輩 |
|
| 15樓: | >>參與討論 |
| 作者: mycatboys 于 2007/5/10 1:31:00 發(fā)布:
好的程序就是要減少主程序 wxpmy! ------------------------------------------------ 無論如何,不要忘記在身邊留兩本書:《圍城》《孤島訪談》。前者讓你放松且思考,后者讓你思考且放松。無論做[url=http://www.118cy.net/host]虛擬主機[/url]有多累,從[url=http://www.118cy.net/domain]申請域名[/url]公司下班后,都會找時間看書 |
|
| 16樓: | >>參與討論 |
| 作者: ayb_ice 于 2007/5/10 7:59:00 發(fā)布:
隨便說說 因為是RISC,任何對內(nèi)存的操作不可能在一條指令內(nèi)完成,所有是存在風(fēng)險的... 這是你的問題而不是ARM的錯... |
|
| 17樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/10 15:38:00 發(fā)布:
大俠幫忙 如果在宏定義加上開關(guān)中斷則占用太多的存儲空間(我的程序中位操作實在是太多了),我想寫成函數(shù),但是函數(shù)不能有位變量的參數(shù)。 比如說 bit.bzw2=1; bit.bzw3=1; bit.bzw4=1; 怎么能實現(xiàn)這樣的函數(shù)操作呢:bitoperate(bit.bzw2,1) bitoperate(bit.bzw3,1) bitoperate(bit.bzw4,1) 怎么定義這個函數(shù)bitoperate(?,?)。 |
|
| 18樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/10 15:39:00 發(fā)布:
圈圈和農(nóng)名代表知道么? |
|
| 19樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/10 15:59:00 發(fā)布:
大俠幫忙 |
|
| 20樓: | >>參與討論 |
| 作者: computer00 于 2007/5/10 16:12:00 發(fā)布:
你能不能先說說,你弄這些位變量是干什么用的? 如果是操作IO口的話,直接使用&|等操作更方便,而有些ARM芯片還提供CLR,SET等寄存器,那就更方便了。 如果是做為標(biāo)志用,還不如直接用int型或者CHAR型的,如果真的有那么多個位標(biāo)志,你的程序也夠復(fù)雜的了........ |
|
| 21樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/10 16:21:00 發(fā)布:
是的 程序很復(fù)雜!標(biāo)志位不下千八百個! |
|
| 22樓: | >>參與討論 |
| 作者: computer00 于 2007/5/10 18:07:00 發(fā)布:
這么多標(biāo)志都要到中斷里面去修改的?你的中斷服務(wù)夠忙活的..... #define FlagType unsigned int FlagType f1,f2; #define Bit0 0 #define Bit1 1 ................... #define GOOD 0 #define Bad 1 #define VeryGOOD 2 #define VeryBad 3 .................... void SetBit(FlagType f,unsigned int p,unsigned int v) { OffInt(); if(v) //如果設(shè)置為非0 { f|=(FlagType)(1<<p); } else //設(shè)置為0 { f&=~((FlagType)(1<<p)); } OnInt(); } //使用 SetBit(f1,Bit0,1); SetBit(f1,Bit1,0); SetBit(f2,GOOD,1); SetBit(f2,VeryBad,0); ....................... |
|
| 23樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/11 8:40:00 發(fā)布:
OffInt()和OnInt()函數(shù)是做什么的? |
|
| 24樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/11 8:44:00 發(fā)布:
圈圈!onint()和offint()是做什么的?這個函數(shù)是c的庫函數(shù)么? |
|
| 25樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/11 8:44:00 發(fā)布:
我怎么沒找到呢? |
|
| 26樓: | >>參與討論 |
| 作者: wxpmy 于 2007/5/11 10:07:00 發(fā)布:
圈圈!onint()和offint()是做什么的?這個函數(shù)是c的庫函數(shù)么? |
|
| 27樓: | >>參與討論 |
| 作者: computer00 于 2007/5/11 14:26:00 發(fā)布:
暈菜了....分別是關(guān)中斷和開中斷啊,你自己搞定它們了 不是說要關(guān)了中斷再操作的么. |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |