|
|||||||||||
| 技術(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 |
51新手問題:中斷響應(yīng)后片子里面哪些地方改寫了 |
| 作者:bg6nw 欄目:單片機 |
我是一個單片機初學(xué)者,剛剛學(xué)了七八天,試著寫了一個小程序,翻了一些資料,頭都大了,好不容易擠出了一些代碼,但是出現(xiàn)了一個莫名其妙的現(xiàn)象,希望哪位弟兄百忙之中抽空看看,這里先謝過。 這是一個電話遙控電器的試驗,2051的p1.7接光耦,檢測振鈴,來振鈴將p1.7拉低,p1.1到p1.5接CM8870的std,D,C,B,A,用來檢測摘機后撥進(jìn)來的雙音碼,如果依次是*,0兩個碼,就向電話線送【嘀嘀聲】然后打開電器,這里我做了兩個定時中斷都是十秒左右的,在檢測振鈴時用一個,兩次振鈴間隔超過十秒就回到開始【start】;另一個是摘機后十秒內(nèi)不輸完密碼就回到開始【start】。開機從頭到尾執(zhí)行起來都正常,出現(xiàn)了這樣的問題: 如果從開機復(fù)位,振鈴6次到摘機后,不輸密碼,等待定時中斷超時回到開始掛斷電話,再重新送振鈴6次摘機,摘機后定時中斷不起作用了,多少秒鐘以后也不掛斷,這時輸入密碼也可以向下執(zhí)行。硬件復(fù)位后第一次超時掛機正常。 我已經(jīng)黔驢技窮了,呵呵。弄了兩整天,改代碼,寫片子,2051都寫了100多次了,還是不行。我想可能是中斷響應(yīng)之后半路跳到【start】,還有什么東西沒有復(fù)位造成的,請各位弟兄指點指點。 代碼如下,第一次寫程序,有點亂-------那位老弟又說了:豈止亂,那是真亂呀 ;單片機是89c2051,晶振是4MHZ org 0000h ajmp start org 000bh ;定時器0的中斷向量地址 ajmp time0 ;跳轉(zhuǎn)到真正的定時器程序處 org 0030h start: mov p1,#0ffh ;將p1口全置高,作為輸入端 mov p3,#00h ;將p3口全置低,作為輸出端 clr a ;累加器a清零 mov sp, #5fh ;堆棧起始設(shè)置 mov 30h, #00h ;軟件計數(shù)器清零 mov tmod, #00000001b ;定時/計數(shù)器0工作于方式1 mov th0, #3ch ;裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 總數(shù)是15536,即計數(shù)到50000 setb ea ;開總中斷 setb et0 ;開定時/計數(shù)器0允許 l1:jnb p1.7,d2 ;p1.7為高則向下執(zhí)行,為低即跳至d2 ljmp l1 ;跳回l1 d2:setb tr0 ;定時/計數(shù)器0開始運行 mov 30h, #00h ;軟件計數(shù)器清零 lcall delay ;調(diào)用2秒延時 inc a ;累加器a加1 cjne a, #6, l1 ;判斷累加器a里面的數(shù)字為6否,是6,向下,不是6,回l1 clr tr0 ; 定時/計數(shù)器停止運行 setb p3.7 ;現(xiàn)在摘機, 推動一個繼電器,將一個300歐姆電阻并到電話線上 lcall delay ;調(diào)用2秒延時,這時將有一個音樂片說一聲【請輸入密碼】 clr a ;累加器a清零mov 30h, #00h ;軟件計數(shù)器清零 mov th0, #3ch ;重置定時器,裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 setb tr0 ;定時/計數(shù)器0開始運行 mima:jnb p1.1, mima ;檢測8870的15腳,低電平循環(huán),高電平向下執(zhí)行 jnb p1.2, start ;d位電平高繼續(xù) jb p1.3, start ;c位電平低繼續(xù) jnb p1.4, start ;b位電平高繼續(xù) jnb p1.5, start ;a位電平高繼續(xù),這四個是第一位密碼 【*】 mima2:jb p1.1, mima2 ;檢測8870的15腳,高電平循環(huán),低電平向下執(zhí)行 mima3:jnb p1.1, mima3 ;檢測8870的15腳,低電平循環(huán),高電平向下執(zhí)行 jnb p1.2, start ;d位電平高繼續(xù) jb p1.3, start ;c位電平低繼續(xù) jnb p1.4, start ;b位電平高繼續(xù) jb p1.5, start ;a位電平低繼續(xù),這四個是第二位密碼 【0】 lcall didixiang ;以下重復(fù)嘀嘀響十次 nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop kaiguan:setb p3.4 ljmp kaiguan ;p3.4推動一個繼電器,打開被控制的電器開關(guān) ;未完待續(xù)------掛機電路還沒想起來,寫到這里卡殼了 ;-----------------以下為嘀嘀響程序---------------------- didixiang: mov r7, #100 didi1: mov r6, #200 setb p3.5 ;p3.5推動一個三極管,去調(diào)制電話線,送出斷續(xù)方波 didi2: djnz r6, didi2 clr p3.5 djnz r7, didi1 mov r7, #100 didi3: mov r6, #200 didi4: djnz r6, didi4 djnz r7, didi3 ret ;-----------------;以下為2秒延時----------------------- delay: mov r7, #250 y1: mov r6, #200 y2: mov r5, #5 y3: djnz r5, y3 djnz r6, y2 djnz r7, y1 ret ;---------------------------------------------------------- time0: ;定時器0的中斷處理程序 PUSH acc inc 30h ;軟件定時器加1 mov a, 30h ;軟件定時器送累加器a cjne a, #65, tret ;到65了嗎?到了向下執(zhí)行,未到65轉(zhuǎn)到tret ljmp start ;回到開始,掛掉電話,重來。 tret: mov th0, #3ch ;重置定時器,裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 pop acc reti end |
| 2樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 16:46:00 發(fā)布:
中斷也要保護(hù)psw 因為用了cjne a, #65, tret 破壞了CY |
|
| 3樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 16:53:00 發(fā)布:
我曾經(jīng)加了 曾經(jīng)這樣改過 ;---------------------------------------------------------- time0: ;定時器0的中斷處理程序 PUSH.html">PUSH acc PUSH PSW inc 30h ;軟件定時器加1 mov a, 30h ;軟件定時器送累加器a cjne a, #65, tret ;到65了嗎?到了向下執(zhí)行,未到65轉(zhuǎn)到tret ljmp start ;回到開始,掛掉電話,重來。 tret: mov th0, #3ch ;重置定時器,裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 POP PSW pop acc reti end 是不是在ljmp start之前也要加上一句呀 謝謝。 |
|
| 4樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 17:47:00 發(fā)布:
我剛剛寫了片子試了 我剛剛寫了片子試了 time0: ;定時器0的中斷處理程序 PUSH acc PUSH psw inc 30h ;軟件定時器加1 mov a, 30h ;軟件定時器送累加器a cjne a, #65, tret ;到65了嗎?到了向下執(zhí)行,未到65轉(zhuǎn)到tret pop psw pop acc ljmp start ;回到開始,掛掉電話,重來。 tret: mov th0, #3ch ;重置定時器,裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 pop psw pop acc reti 即使是這樣,還是老問題。差哪兒呢 |
|
| 5樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 17:51:00 發(fā)布:
不要這樣軟復(fù)位 time0: ;定時器0的中斷處理程序 PUSH acc PUSH psw inc 30h ;軟件定時器加1 mov a, 30h ;軟件定時器送累加器a cjne a, #65, tret ;到65了嗎?到了向下執(zhí)行,未到65轉(zhuǎn)到tret ;/////////////////////////////////////////////////// ;//ljmp start ;回到開始,掛掉電話,重來。 acall treti;//空調(diào)用一次reti clr a PUSH acc PUSH acc reti;//調(diào)用第二次reti//;回到開始,掛掉電話,重來。 ;//////////////////////////////////////////////////// tret: mov th0, #3ch ;重置定時器,裝入預(yù)置數(shù)高位 mov tl0, #0b0h ;裝入預(yù)置數(shù)低位 pop psw pop acc treti: reti 再: start處最好加mov ie,#0;或clr ea 作為"一個單片機初學(xué)者,剛剛學(xué)了七八天" 能編出這樣的程序來,菜農(nóng)在這里敬禮了~~~ |
|
| 6樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 19:25:00 發(fā)布:
向高手敬禮 不愧是高手呀,經(jīng)菜農(nóng)這么一改,寫到片子里居然就解決了。但是老哥我還有問題: 一,我還是沒看懂,調(diào)用兩次reti為什么就能使程序回到start去,又沒有用ljmp start語句。reti語句不是回到被打斷的PC指針那里嗎,怎么跑到start去了?翻書也沒有找到相關(guān)內(nèi)容。 二,acall treti;//空調(diào)用一次reti 這一句執(zhí)行過以后PC指針跑其他地方去了吧,他下面的一句clr a PUSH acc..........是怎么被執(zhí)行到的?我老是繞不過來這個彎。 三,如果在start后面加上【關(guān)總中斷】語句,我在后面隔幾句又有【開總中斷】,會不會這里會有一個小BUG?刹豢梢栽趕tart后面用clr tr0 語句,待第一個振鈴脈沖來到之后再setb tr0 說幾句題外話,在單片機方面我確實是個低低手,剛學(xué)這個幾天,今年三十六了,從上初中就熱愛無線電,至今未輟,還在無線電運動協(xié)會里考了個呼號:BG6NW。曾經(jīng)搞過維修,買過電器,在無線電廠里做過設(shè)計,就是沒有真正接觸過單片機。前些時在其他壇子里泡,就看見有人說,不會單片機就不算玩電子的,這才想著要發(fā)憤學(xué)習(xí)單片機的。硬件倒是沒有什么困難的,主要是以前沒有接觸過編程,有很多概念都沒理解,這幾天搞得每天做夢都在寫代碼,求算法?礃幼游沂敲陨狭。。。。。 |
|
| 7樓: | >>參與討論 |
| 作者: lpf336 于 2007/1/22 19:34:00 發(fā)布:
老哥我 今年三十六了 好像沒hotpower大 |
|
| 8樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 19:45:00 發(fā)布:
不好意思 我一直以為我這樣的老【電癡】不太多,我錯了,對不住 |
|
| 9樓: | >>參與討論 |
| 作者: twz8858877 于 2007/1/22 20:11:00 發(fā)布:
這是初學(xué)者易犯的一個錯誤 51系列中斷系統(tǒng)的硬件中還包含了兩個不可尋址的“優(yōu)先級激活”觸發(fā)器,該觸發(fā)器在響應(yīng)中斷時由CPU置位,以阻斷同級或低優(yōu)先級的中斷,該觸發(fā)器的置位只能由reti語句釋放,所以在你原程序中l(wèi)jmp start語句后由于沒有reti語句,此時CPU仍然認(rèn)為處于定時器0的中斷服務(wù)程序中,此時將不再響應(yīng)同級中斷,也就是說將不再響應(yīng)t0的中斷了。至于其他的幾個問題: 1、acall treti;//空調(diào)用一次reti,這一句執(zhí)行過以后PC指針跑其他地方去了吧,他下面的一句clr a PUSH acc..........是怎么被執(zhí)行到的?我老是繞不過來這個彎。 acall treti指令執(zhí)行時首先cpu會自動將當(dāng)前pc值壓棧,然后執(zhí)行reti時cpu做了兩件事 1、釋放“優(yōu)先級激活”觸發(fā)器;2、將堆棧內(nèi)容彈回pc;所以程序還是會返回原處繼續(xù)執(zhí)行的。至于后面的PUSH acc.......等到是可以由一條語句ljmp start代替了。 如果在start后面加上【關(guān)總中斷】語句,我在后面隔幾句又有【開總中斷】,會不會這里會有一個小BUG?刹豢梢栽趕tart后面用clr tr0 語句,待第一個振鈴脈沖來到之后再setb tr0 由于你只開了一個t0中斷,所以你這樣做也可以的,clr ea也不存在有什么BUG,如果開了多個中斷,最好還是clr ea |
|
| 10樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 20:24:00 發(fā)布:
哈哈~~~至少小我一輪~~~倒塌了~~~網(wǎng)上沒大小,隨便就好~~~ 很是佩服~~~ 記得80多歲的老父50歲學(xué)日語(第3外語)的時候...前幾年還在寫書...文革被母親撕了英文詞典... 確實是我一生難忘!!!菜農(nóng)我自愧不如~~~ 奔五的人能在此倒塌,心里就知足了...所以我要向您敬禮!!! 要看電視"臥薪嘗膽"了~~~回頭我會講解的...
|
|
| 11樓: | >>參與討論 |
| 作者: hq_y 于 2007/1/22 20:26:00 發(fā)布:
佩服樓主,向樓主學(xué)習(xí)! 告訴樓主一個秘密: 有什么不懂的,抓住hotpower就行了~~~~~~~~~~~ |
|
| 12樓: | >>參與討論 |
| 作者: conwh 于 2007/1/22 20:54:00 發(fā)布:
前面的CLR A,再加上2個PUSH A,就是設(shè)置了返回指針00了 |
|
| 13樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 20:55:00 發(fā)布:
都是熱心的高手 后面還有密碼掛機,忙音檢測部分。想想頭都大了,下一步我還打算把這個小程序弄完,要不我會天天睡不著的:) 接下來還會遇到這樣那樣的問題,還不少麻煩諸位。 |
|
| 14樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 21:05:00 發(fā)布:
這個程序就先別搞了,先突擊學(xué)習(xí)C51三天再編程序 這樣的程序結(jié)構(gòu)本來就沒骨架,再搭一點東西就會倒塌了~~~ 真的,不騙您~~~ 回此帖就是覺得這個程序很有創(chuàng)意~~~但不能做產(chǎn)品~~~
|
|
| 15樓: | >>參與討論 |
| 作者: conwh 于 2007/1/22 21:31:00 發(fā)布:
LS的你最好不要再發(fā)4眼的圖片了,看得都成4眼了,暈! 同意HOTPOWER的意見,結(jié)構(gòu)式的程序是你進(jìn)步的梯子。再就是這樣復(fù)位方式不好,能不這樣使用就盡量不這么使用。該掛機就掛機,應(yīng)該不是個麻煩的事情。盡量使用模塊結(jié)構(gòu),對于變量要使用變量名,總比30H、31H等好的多。 |
|
| 16樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 22:28:00 發(fā)布:
理解了兩個小時,想通一點了 經(jīng)過conwh 一點撥,我的明白了,菜農(nóng)前輩的這幾句 acall treti;//空調(diào)用一次reti clr a PUSH acc PUSH acc reti;//調(diào)用第二次reti 是把四個0壓入堆棧,等reti的時候,送給PC指針的是四個0呀,那不就回到開始了。 |
|
| 17樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 22:32:00 發(fā)布:
理解估計有些偏差,twz8858877解釋的很好~~~ 先到菜地里玩玩~~~等會給你幾個鏈接. 主要是如何搭匯編的骨架... |
|
| 18樓: | >>參與討論 |
| 作者: xwj 于 2007/1/22 22:39:00 發(fā)布:
先把程序結(jié)構(gòu)學(xué)好再說,過分追求技巧舊落了下乘了(雕蟲小技而已) 等你到了一定程度再去講究精益求精、化腐朽為神奇吧 |
|
| 19樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 22:45:00 發(fā)布:
LS放小鳥搗蛋,不怕尿童射小鳥??? |
|
| 20樓: | >>參與討論 |
| 作者: xwj 于 2007/1/22 22:46:00 發(fā)布:
你敢!小心你的 小JJ |
|
| 21樓: | >>參與討論 |
| 作者: xwj 于 2007/1/22 23:00:00 發(fā)布:
軟復(fù)位不是那么簡單的,還有很多事要做的 IO SP PSW 中斷標(biāo)志和配置 IE 中斷占用 清內(nèi)存 部分特殊寄存器 外圍器件的釋放 正常初始化 等等等等。。。 系統(tǒng)可靠性要考慮的東西很多的,LZ想的還是過于簡單了哦 雖然現(xiàn)在能用,但不保證以后或現(xiàn)場不出錯誤哦 對你的領(lǐng)悟和應(yīng)用能力表示贊賞,再接再厲,把結(jié)構(gòu)化編程和可靠性考慮成為習(xí)慣,把51徹底研究透徹,把思路和知識面無限擴展,那你就是高手了 加油吧! |
|
| 22樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/22 23:02:00 發(fā)布:
三十而立~~~不晚~~~ |
|
| 23樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/22 23:40:00 發(fā)布:
平凡老師的教材真好 我是一個星期之前開始看的【平凡的單片機】,之前沒有接觸過單片機,看了他的教程依葫蘆畫瓢寫的這個半拉的,漏洞百出的,貌似程序的東東,見笑。 因為本人文化程度不高,初中畢業(yè),基礎(chǔ)不好,只能看這些速成的教材,至于程序結(jié)構(gòu)之類的,呵呵,看不懂的準(zhǔn) |
|
| 24樓: | >>參與討論 |
| 作者: dengm 于 2007/1/23 0:17:00 發(fā)布:
加 IE=0, 確保不被中斷 TIMER_1 DATA 30H ;.... INC TIMER_1 ;....... acall treti;//空調(diào)用一次reti clr a PUSH acc PUSH acc MOV IE, A ; 加 IE=0, 確保不被中斷 treti: reti;//調(diào)用第二次reti//;回到開始,掛掉電話,重來。 |
|
| 25樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/23 0:33:00 發(fā)布:
又來一個~~~學(xué)好匯編,要先拜鄧苗同志為師~~~ 在此處加不加clr ea不是很重要,當(dāng)然最好加上,否則其他中斷可能要搞一些破壞活動. 但復(fù)位后應(yīng)該clr ea或mov ie,#0,且設(shè)置好sp后再經(jīng)過2次reti后再開始運行初始化程序為好. |
|
| 26樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/23 11:11:00 發(fā)布:
我想也是 還有很多問題,軟復(fù)位太難了 特別是堆棧部分,堆進(jìn)去多少,就要彈出來多少,要不幾十個軟復(fù)位下來,堆棧就可能溢出到其他地方,到時候執(zhí)行的是什么就不好說了。 我現(xiàn)在還不知道軟復(fù)位之后怎么清堆棧呢,是不是像菜農(nóng)前輩說的設(shè)置好SP后用兩個ERTI彈空它 |
|
| 27樓: | >>參與討論 |
| 作者: xwj 于 2007/1/23 11:25:00 發(fā)布:
堆棧不成問題,你重設(shè)SP后原來的就都不管了:-) 當(dāng)然,之前的數(shù)據(jù)丟失、程序中斷(中止)、外圍模塊操作到一半等會不會造成問題就看你想沒想到了 所以才說軟復(fù)位沒你想的那么簡單 |
|
| 28樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/23 11:39:00 發(fā)布:
我想好了,做硬復(fù)位 我想好了,軟復(fù)位太難,不是我現(xiàn)在現(xiàn)學(xué)可以弄成的,就像各位大俠說的,有一個地方照顧不到,就會出現(xiàn)不可欲知的問題。 下一步我想用空端口做一個硬復(fù)位,知難而退了,呵呵 |
|
| 29樓: | >>參與討論 |
| 作者: computer00 于 2007/1/23 12:08:00 發(fā)布:
真是暈菜,搞個主循環(huán)不就得了?還要搞復(fù)位? |
|
| 30樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/23 12:17:00 發(fā)布:
主程序里要有00(圈圈)~~~ |
|
| 31樓: | >>參與討論 |
| 作者: dengm 于 2007/1/23 12:22:00 發(fā)布:
沒那么復(fù)雜 STACK_BUF EQU 60H F_55 DATA 7EH F_AA DATA 7FH ;------------------------------- ORG 0000H AJMP START NOP INT_RET: RETI START: CLR A MOV IE, A MOV PSW, A CPL A MOV P1, A MOV P3, A MOV SP, #(STACK_BUF-1) ACALL INT_RET ACALL INT_RET MOV A, F_55 CPL A XOR A, F_AA JNZ CLR_RAM_1 MOV A, #55H XOR A, F_AA JZ SKIP_CLR_RAM CLR_RAM_1: CLR A MOV R0, A CLR_RAM: MOV @R0, A DJNZ R0, CLR_RAM MOV F_55, #55H MOV F_AA, #0AAH SKIP_CLR_RAM: ;.... ;... ;.... ;.... * - 本貼最后修改時間:2007-1-23 12:32:25 修改者:dengm |
|
| 32樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/23 15:18:00 發(fā)布:
謝謝鄧大俠 看了半天,理解一點了 等會我把你的這個初始化程序粘貼到我的程序頭上,試試,來個貂續(xù)狗尾。 |
|
| 33樓: | >>參與討論 |
| 作者: hotpower 于 2007/1/23 16:10:00 發(fā)布:
XOR A, F_AA改為XRL A, F_AA 學(xué)鄧大俠你可要小心點~~~他根基太深,小心把你套牢~~~ |
|
| 34樓: | >>參與討論 |
| 作者: caai 于 2007/1/23 20:23:00 發(fā)布:
這么強! 不是吧~~ 7.8天 不要這樣無情的打擊我的自信心啊 還是去做點端盤子的事算了~~ |
|
| 35樓: | >>參與討論 |
| 作者: bg6nw 于 2007/1/23 21:09:00 發(fā)布:
還強呢 我寫的這些東東,對前面幾位大俠來說,呵呵。 打個比方吧,就像你看三年級小學(xué)生寫的作文一樣 |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |