新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > OK6410 裸機(jī)中斷最簡(jiǎn)單代碼

        OK6410 裸機(jī)中斷最簡(jiǎn)單代碼

        作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
        近來想學(xué)ARM開發(fā),使用了S3C6410核的OK6410開發(fā)板,為了學(xué)習(xí)ARM的底層技術(shù),想從裸機(jī)開始學(xué)習(xí),結(jié)果一路挫折,問題多多,經(jīng)過很長(zhǎng)一段時(shí)間的摸索也沒有太多成果,因?yàn)槠匠I习啵?xiàng)目的事情也忙,看書的時(shí)間也不夠多,結(jié)果走進(jìn)中斷編程都經(jīng)過了將近一個(gè)月!!

        本文引用地址:http://www.104case.com/article/201611/317128.htm

        中斷,我認(rèn)為在初學(xué)單片機(jī)開發(fā)的時(shí)候是一個(gè)比較麻煩的事情,所有想把這個(gè)東西弄懂,結(jié)果在網(wǎng)上找了遍,都沒有找到可以用的代碼!為什么呢?因?yàn)槎娜耍X得沒有必要,不懂的人反正是不懂,就像我一樣。在論壇上http://bbs.witech.com.cn/thread-3809-1-1.html ,我覺得那個(gè)裸機(jī)視頻很好,至少我在視頻的幫助下,很快可以完成點(diǎn)燈了,那種興奮是非常好的,但想走入中斷,那就是一個(gè)很麻煩的事。高手們寫的代碼,太長(zhǎng)太多,像我只是知道一點(diǎn)點(diǎn)的,是看不懂太多代碼的,至于官方的代碼,更是難懂,因?yàn)樘嗵珡?fù)雜,對(duì)于初學(xué)者不利,容易打退堂鼓。(……好像說了太多廢話了,其實(shí)我想說的是,初學(xué)這東西,還是要有點(diǎn)韌性好)


        如果想在OK6410開發(fā)板上學(xué)著寫一個(gè)裸機(jī)程序,那本文是非常適合你的,我會(huì)讓你知道寫中斷的一切我知道,而你也同樣需要的知識(shí)。如果您是高手,請(qǐng)莫見笑,并煩請(qǐng)指教。

        本文將使用最簡(jiǎn)代碼來完成定時(shí)器0的中斷,每秒中斷一次,并輪流顯示開發(fā)板上的四個(gè)小LED燈。

        程序兩個(gè)部分,一部分是啟動(dòng)代碼(匯編),另一部分是中斷C程序。

        節(jié)選啟動(dòng)復(fù)位代碼:

        [cpp]view plaincopy
        1. ;允許中斷
        2. ENABLE_IRQ
        3. MRSR0,CPSR;將CPSR保存至R0寄存器中
        4. BICR0,R0,#0x80;R0=R0&~0x80,清除中斷位
        5. MSRCPSR_c,R0;將R0寫回CPSR狀態(tài)寄存器
        6. MOVPC,LR;返回到調(diào)用代碼
        7. ResetInit
        8. LDRR14,=0x50100000;初始化一下棧指針
        9. BLENABLE_IRQ;打開中斷允許位
        10. BMain;跳入MAIN程序

        上面的代碼就是一個(gè)簡(jiǎn)單的啟動(dòng)代碼,當(dāng)然來包括中斷向量配置這些,這些請(qǐng)查看上傳的工程文件。

        如果需要完成中斷,那么一定得打開中斷允許位,不然,任意中斷都是不會(huì)產(chǎn)生的,這是我摸索過程中的一個(gè)問題。這個(gè)問題很難嗎?不是,而是因?yàn)闆]有人告訴你這么做,后來我在周立功出的ARM基礎(chǔ)書上看到的。總之,要完成一個(gè)中斷的產(chǎn)生,需要具備三個(gè)條件:(1)初始化了中斷源,(2)配置了中斷向量允許位,(3)狀態(tài)寄存器的標(biāo)志位請(qǐng)零。上述代碼完成了第三個(gè)條件,下面,我通過代碼來完成中斷源的初始化工作。下面給出一張周立功給出的一張圖:

        如果您因?yàn)橹袛嗖荒苓M(jìn)入,請(qǐng)檢查是否滿足前面的三個(gè)條件,也對(duì)應(yīng)于本圖的三個(gè)環(huán)。

        當(dāng)我發(fā)現(xiàn)中斷不進(jìn)入的時(shí)候,也看到過此圖,但并沒有理解,只到我調(diào)度的時(shí)候,在AXD下查看CPU寄存器的時(shí)候,發(fā)現(xiàn)I與F的標(biāo)志,將手對(duì)修改了I標(biāo)志,結(jié)果中斷程序的斷點(diǎn)進(jìn)入了,至此明白了這個(gè)圖。有時(shí)候一個(gè)圖在這里,如果你沒有理解這個(gè)圖,或者理解這圖背后的原理,是很難明白繪圖者的真正函義。圖對(duì)于理解了的,很容易記憶,而且有用,對(duì)于其它人而言,也容易理解,但有時(shí)候理解并不能把握真實(shí)的函義,所以需要學(xué)習(xí),將圖的理解,并最終成為自己的記憶。

        下面代碼通過設(shè)置寄存器來完成配置工作。在這里的代碼,如果你手上沒有芯片文檔,那基本上是看不懂的天書。因?yàn)槲沂遣锁B,所以我覺得我的問題可能是一些初學(xué)者的問題。比如,下面的代碼為什么是這樣寫的,這樣寫的依據(jù)是從哪里來的?你告訴我去參考文檔,我知道了這個(gè)配置的原理,但我還是無法融匯貫通啊?我當(dāng)時(shí)看文檔的時(shí)候總是問自己這些問題。為什么呢?因?yàn)槲臋n太長(zhǎng)太多,而且是英文的,我手里的S3C6410文檔就有1371頁(yè),是不是我寫LED就只看GPIO部分了呢?的確是這樣,但你想寫中斷了,是不是只看定時(shí)器單節(jié)就可以了,這里回答肯定不是這樣的,你需要查看中斷相關(guān)節(jié),可能還要查看前面幾節(jié)關(guān)于CPU的特性介紹,中斷功能的介紹等信息,這也意味著,走入中斷,表示你對(duì)這個(gè)CPU也有所了解了,通過對(duì)中斷的理解,也表明你可以做更多有意義的事情了。看文檔,看資料是必須的,遇到問題再去看資料的時(shí)候,會(huì)得到一些靈感。

        [cpp]view plaincopy
        1. //初始化定時(shí)器0,重動(dòng)重載計(jì)數(shù)值
        2. //這里為什么是這樣的順序,為什么這么寫,請(qǐng)參考S3C6410芯片文檔
        3. voidtimer_init(void)
        4. {
        5. rTINT_CSTAT|=1<<0;//開timer0中斷,允許timer0中斷發(fā)生
        6. rVIC0INTENABLE|=1<<23;//開timer0的使能(相當(dāng)于關(guān)掉mask)
        7. rTCFG0&=~0xFF;//清除預(yù)分頻因子位
        8. rTCFG0|=0x42;//設(shè)置分頻因子(66分頻),定時(shí)器時(shí)鐘頻率為1Mhz
        9. rTCFG1&=~0x11;//設(shè)置DividerMUX0為零1分頻
        10. rTCNTB0=1000000;//設(shè)初值(1s)
        11. rTCON|=1<<1;//開ManualUpdate(UpdateTCNTB0,TCMPB0)設(shè)置初值后要更新TCNTB
        12. rTCON|=1<<3;//AutoReloadon自動(dòng)重裝開啟
        13. rTCON|=1<<0;//timer0open;
        14. rTCON&=~(1<<1);//不再UpdateTCNTB0,TCMPB0
        15. }
        上在的代碼完也了定時(shí)器的初始化,開始,我通過寫定時(shí)器狀態(tài)零位,打開TIME0中斷,然后,基本中斷向量允許位,這也是中斷條件(2)需要的,這樣定時(shí)器中斷配置就配置好了,然后, 需要初始人中斷源的配置信息,這是條件(1)所要求的,我們需要定時(shí)器完成定時(shí)任務(wù),就需要定時(shí)器計(jì)數(shù)到零的時(shí)候,自動(dòng)裝載計(jì)算值,重新計(jì)數(shù),以重新產(chǎn)生中斷。這里為什么要這么設(shè)置了,設(shè)置的順序在文檔中有說明的,比如這里對(duì)rTCON的配置就是要求的一個(gè)順序。定時(shí)器分頻在S3C6410文檔的PWM節(jié)有描述,這里將時(shí)間頻率設(shè)為1MHz,這樣我們就好計(jì)算定時(shí)的時(shí)間了。

        關(guān)于定時(shí)器初值的計(jì)算,我說一下我的理解。

        MHz是兆赫茲,表示一秒內(nèi)振蕩的資料,這表示1MHz = 每秒震蕩1000 000次,反過來,如果你需要一秒的定時(shí),你需要計(jì)數(shù)1000,000次,也就是要求頻率為1MHz,那如何配置頻率為1MHz呢?參考手冊(cè)上有這個(gè)參數(shù):

        Timer input clock Frequency = PCLK / ( {prescaler value + 1} ) / {divider value}

        這樣如果需要一秒的時(shí)間一次中斷,在沒有配置PPL(可以配置CPU的倍頻的東西)的情況下,CPU的頻率為FOSC的頻率,即66MHz,在分頻為66,預(yù)分頻為0,那么需要設(shè)置計(jì)數(shù)值為1000,000,這樣就可以產(chǎn)生每秒一次的中斷了。

        中斷初始化完成之后,主程序可以進(jìn)入死循環(huán),等待中斷的來臨……

        在等待之前,我們需要正確設(shè)置中斷向量,進(jìn)入C語(yǔ)言代碼的中斷程序,再正確返回到程序的原為位置。中進(jìn)入中斷向量之前,CPU進(jìn)入中斷狀態(tài),使用中斷狀態(tài)下的特殊寄存器,通過寄存器仍然使用中斷之前模式的,為了防止破壞中斷之前的代碼,需要備份這些寄存器,之后,將中斷函數(shù)的返回地址設(shè)置好后,就可以進(jìn)入實(shí)際中斷處理函數(shù)了。中斷處理函數(shù)返回后,需要恢復(fù)寄存器現(xiàn)場(chǎng),并通過將PC設(shè)置為中斷前的地址,以使主程序斷續(xù)。

        [cpp]view plaincopy
        1. IRQHandler
        2. STMFDSP!,{r0-r3,r12,lr};保存現(xiàn)場(chǎng)
        3. ldrlr,=int_return;設(shè)置中斷異常處理程序返回地址到下面的位置
        4. BIRQ_Exception;直接進(jìn)入到中斷函數(shù)處理
        5. int_return
        6. LDMFDSP!,{r0-r3,r12,lr};恢復(fù)現(xiàn)場(chǎng)
        7. SUBSPC,LR,#4;返回進(jìn)入中斷前的代碼
        通過上面的簡(jiǎn)陋代碼,可以讓中斷進(jìn)入到我們的C程序IRQ_Exception程序中。

        下面給出簡(jiǎn)單的中斷跑馬燈代碼:

        [cpp]view plaincopy
        1. inti=0;
        2. //IRQ異常中斷
        3. voidIRQ_Exception()
        4. {
        5. i%=4;
        6. //打開一個(gè)燈,并閉另外一個(gè)燈
        7. rGPMDAT=~(1<
        8. //清除定時(shí)器中斷狀態(tài)位
        9. while((rTINT_CSTAT&0x20))rTINT_CSTAT|=(1<<5);
        10. }
        中斷程序很簡(jiǎn)單,切換燈,并清除中斷。清除中斷是我最后的一個(gè)難點(diǎn),這一行代碼,我查了很多資料,還不是很明白。首先,中斷狀態(tài)一定要清除的,不然程序進(jìn)入中斷后,將不會(huì)再出來了,因?yàn)橹袛酄顟B(tài)不清,中斷將會(huì)不斷的產(chǎn)生。還有中斷狀態(tài)清除是通過置位寄存器指定位來清零的,如果不加入while等待,那么清除指令操作很可能沒有正確執(zhí)行,導(dǎo)致中斷會(huì)馬上再次進(jìn)入,而且表現(xiàn)在燈效果上,就是四個(gè)燈只有兩個(gè)隔著亮,這里的原因是第二次清中斷,一條指令就可以成功,第一次不會(huì)成功。如果在中斷加入延時(shí)代碼,也會(huì)每次都成功。后來分析,并參考資料,說是在電平中斷時(shí),只有在中斷無效狀態(tài)時(shí),該位置位才有效。這也是這里為什么一定會(huì)使用while等待的原因了。

        好了,中斷程序就這樣介紹完了,這里還有如何設(shè)置啟動(dòng)代碼,寄存器如果定義等相關(guān)內(nèi)容,可以參考由上面給出的飛凌論壇的《裸機(jī)教學(xué)視頻第一季》。如果出了第二季,我就不會(huì)這么走的如此艱辛了。
        程序下載地址:http://download.csdn.net/source/3567988




        關(guān)鍵詞: OK6410裸機(jī)中

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 岳池县| 招远市| 浙江省| 株洲市| 孙吴县| 新兴县| 九江县| 绿春县| 娱乐| 双辽市| 广饶县| 霞浦县| 济源市| 内乡县| 肇庆市| 漯河市| 江阴市| 鸡东县| 闻喜县| 永寿县| 儋州市| 莲花县| 周口市| 长治县| 丽江市| 四会市| 黎城县| 钟山县| 绥化市| 阳西县| 齐齐哈尔市| 阿巴嘎旗| 定州市| 来安县| 兴仁县| 娱乐| 安泽县| 阿鲁科尔沁旗| 策勒县| 山西省| 教育|