全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1477
推到 Plurk!
推到 Facebook!

外部中斷和串列傳輸合併使用的問題!

答題得分者是:
kokalin
一般會員


發表:13
回覆:19
積分:6
註冊:2004-07-29

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-07-10 11:57:00 IP:140.112.xxx.xxx 未訂閱
程式的目的為:利用外部中斷的負緣觸發來啟動"讀取P1埠資料"及"利用RS232將值傳給PC"兩個副程式    將程式放在最後(讀取P1埠資料不寫成迴圈是為了增加讀取速度),而我遇到的問題如下: 每次將8051reset後,其工作結果僅有一次(也就是"讀取P1埠資料"及"利用RS232將值傳給PC"這兩個副程式都RUN一次)傳給PC的值是對的,之後的結果似乎抓取資料的起始點一直有問題 @@||| 找了四天了還找不到關鍵點 到底是為什麼呢?    程式如下:  
$MOD51
;測試利用外部中斷當觸發點,觸發後利用P1埠讀取30筆資料,然後利用RS232將值傳給PC
;
SPVALUE        EQU        060H
SAV_ST        EQU        30H
SAV_NUM        EQU        30
;
        ORG     0000H
        LJMP    RESET
        ORG     0003H           ;INT0 INTERRUPT
        LJMP        INT_ET0
        ORG     000BH           ;TIMER0 INTERRUPT
        RETI
        ORG     0013H           ;INT1 INTERRUPT
        RETI
        ORG     001BH           ;TIMER1 INTERRUPT
        RETI
        ORG     0023H           ;SERIAL INTERRUPT
        RETI
;
RESET:        MOV        R0,#00H                ;暖機動作
        DJNZ        R0,$
        MOV        R0,#0FFH        ;清除內部RAM的值
CL_RAM:        MOV        @R0,#00H
        DJNZ        R0,CL_RAM
        MOV        SP,#SPVALUE        ;設定堆疊位置
; 
        CALL        SET_SERIAL        ;設定串列傳輸
        CALL        SET_INT                ;設定中斷
        NOP
HERE:        JMP        HERE                ;在此等待        
;
READ_ADC:                                ;讀取P1埠的副程式
        MOV        @R1,P1        ;POINT1
        INC        R1
        MOV        @R1,P1        ;POINT2
        INC        R1
        MOV        @R1,P1        ;POINT3
        INC        R1
        MOV        @R1,P1        ;POINT4
        INC        R1
        MOV        @R1,P1        ;POINT5
        INC        R1
        MOV        @R1,P1        ;POINT6
        INC        R1
        MOV        @R1,P1        ;POINT7
        INC        R1
        MOV        @R1,P1        ;POINT8
        INC        R1
        MOV        @R1,P1        ;POINT9
        INC        R1
        MOV        @R1,P1        ;POINT10
        INC        R1
        MOV        @R1,P1        ;POINT11
        INC        R1
        MOV        @R1,P1        ;POINT12
        INC        R1
        MOV        @R1,P1        ;POINT13
        INC        R1
        MOV        @R1,P1        ;POINT14
        INC        R1
        MOV        @R1,P1        ;POINT15
        INC        R1
        MOV        @R1,P1        ;POINT16
        INC        R1
        MOV        @R1,P1        ;POINT17
        INC        R1
        MOV        @R1,P1        ;POINT18
        INC        R1
        MOV        @R1,P1        ;POINT19
        INC        R1
        MOV        @R1,P1        ;POINT20
        INC        R1
        MOV        @R1,P1        ;POINT21
        INC        R1
        MOV        @R1,P1        ;POINT22
        INC        R1
        MOV        @R1,P1        ;POINT23
        INC        R1
        MOV        @R1,P1        ;POINT24
        INC        R1
        MOV        @R1,P1        ;POINT25
        INC        R1
        MOV        @R1,P1        ;POINT26
        INC        R1
        MOV        @R1,P1        ;POINT27
        INC        R1
        MOV        @R1,P1        ;POINT28
        INC        R1
        MOV        @R1,P1        ;POINT29
        INC        R1
        MOV        @R1,P1        ;POINT30
        RET
;
SEND_MESSAGE:                                ;傳送資料副程式
        CLR        TI
        MOV        A,@R1
        MOV        SBUF,A
        JNB        TI,$
        INC        R1
        DJNZ        R7,SEND_MESSAGE
        RET                
;
SET_SERIAL:
        MOV         TMOD,#00100000B                ;Timer1於mode2自動載入模式
        ANL        PCON,#01111111B
        MOV         TH1,#0FAH                ;(FA=>Baud rate=9600於SMOD沒有設定之下  震盪器頻率22.1184)
        SETB         TR1                        ;啟動timer1
        MOV         SCON,#01010000B                ;Serial Port 傳輸格式: 9600,N,8,1 mode1
        RET
;
SET_INT:
        SETB        IT0     ;FALLING TRIGGER ON INT0
        SETB        EX0        ;ENABLE INT0 INTERRUPT
        SETB    EA      ;ENABLE SYSTEM INTERRUPT
        RET
;
INT_ET0:
        CLR        P2.0                        ;利用P2.0觀察INT_ET0的整體時間
        CLR        EX0                        ;暫時MASK外部中斷
        MOV        R1,#SAV_ST                ;設定存放位置起始點
        MOV        P1,#0FFH                
        CALL        READ_ADC                ;呼叫讀取P1埠的副程式
        NOP
        MOV        R1,#SAV_ST                ;設定串列傳輸資料起始點
        MOV        R7,#SAV_NUM                ;設定傳輸資料數量
        CALL        SEND_MESSAGE                ;呼叫傳輸資料副程式
        SETB        EX0                        ;將mask的中斷打開
        SETB        P2.0
        RETI
;
        END
 
發表人 - kokalin 於 2005/07/10 17:43:48 發表人 - kokalin 於 2005/07/10 20:46:53

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-07-10 14:30:23 IP:220.134.xxx.xxx 未訂閱
先將你的程式前面部份改為這樣試試吧:
...
SPVALUE        EQU        40H
SAV_ST        EQU        30H
SAV_NUM        EQU        31H
;
        ORG     0000H
        LJMP    RESET
        ORG     0003H           ;INT0 INTERRUPT
        LJMP        INT_ET0
...
...
...
         ORG      50H
RESET:        MOV        R0,#00H                ;暖機動作
        DJNZ        R0,$
        MOV        R0,#0FFH        ;清除內部RAM的值
CL_RAM:        MOV        @R0,#00H
        DJNZ        R0,CL_RAM
        MOV        SP,#SPVALUE        ;設定堆疊位置
...
...
...
1>中斷不用的地方可以拿掉 2>注意你宣告變數的位址 3>程式堆疊請注意.你沒有設, 我把它給為程式由50H開始堆疊
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-07-10 15:02:54 IP:220.134.xxx.xxx 未訂閱
看了一下你的程式流程, 不曉得你為何要這樣寫耶... 變數設定-->中斷與Timer設定. 鮑率設定 -->進入等待迴圈, 等待中斷 INT0中斷副程式: 讀取P1值-->將P1值丟給sbuf(這樣它就會自動送出去了)-->傳輸完成後中斷返回
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?
kokalin
一般會員


發表:13
回覆:19
積分:6
註冊:2004-07-29

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-07-10 15:55:51 IP:140.112.xxx.xxx 未訂閱
1.一開始宣告的是變數,為什麼會有位置的問題呢?不是宣告變數之後,程式只要有相關的變數名稱,其值就會是所需告的值? 2.我程式會這樣寫是因為我在測試每個副程式的功能,到時候使用時不會按照這樣的順序去工作,而是還會再對抓取進來的資料作處理。 發表人 - kokalin 於 2005/07/10 20:57:07
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-07-10 16:12:26 IP:218.171.xxx.xxx 未訂閱
請問P1是連接到什麼樣的,硬體呢 8051在讀取P1資料時,與連接的硬體有做資料傳輸同步控制嗎 否則可能在讀取資料就有問題了,再傳給PC也是錯誤的資料
kokalin
一般會員


發表:13
回覆:19
積分:6
註冊:2004-07-29

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-07-10 16:24:30 IP:140.112.xxx.xxx 未訂閱
P1讀取的資料為一顆高速ADC(TLC5510)的輸出 其輸出的致能和外部中斷的時間是相同的,也就是說當外部中斷開始時也是高速ADC輸出值的同時,因此讀取值的部分應該是沒有什麼問題!
addn
高階會員


發表:64
回覆:221
積分:202
註冊:2005-03-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-07-10 18:33:22 IP:218.171.xxx.xxx 未訂閱
引言: P1讀取的資料為一顆高速ADC(TLC5510)的輸出 其輸出的致能和外部中斷的時間是相同的,也就是說當外部中斷開始時也是高速ADC輸出值的同時,因此讀取值的部分應該是沒有什麼問題!
依照TLC5510 spec看起來 如果TLC5510的clock使用獨立的clock 8051還是有機會讀到clock上緣瞬間的不穩定值 所以8051在讀取TLC5510的輸出值 應考慮避免在clock正緣時讀取
kokalin
一般會員


發表:13
回覆:19
積分:6
註冊:2004-07-29

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-07-10 20:56:34 IP:140.112.xxx.xxx 未訂閱
我找到問題的所在了: 我的中斷程式不會主動將IE0這個旗標清除為0 因此每當中斷程式結束後,其實IE0還是1,因而觸發了下一次的中斷,所以之後中斷的起發生時間就跟外部輸入信號沒有交集了 難怪僅有reset後的第一次能夠抓對,之後的抓取時間都不對 修改的方法就是在倒數第四行程式(SETB EX0)的上方再加入(CLR IE0)這行程式一切都解決了 YAYA 不過很奇怪的是:書本明明寫說,使用負緣中斷時,當中斷程式啟動後IE0會由硬體自動清除為0的阿,怎麼實驗起來卻沒有這狀況,難道是我使用mask把EX0暫存器disable的關係嗎?

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-07-10 22:01:28 IP:220.134.xxx.xxx 未訂閱
你的設定中斷有問題! 基本上RETI後, 旗標IE0會自動清為0 . 給你個參考,單純用INT0中斷時的設法:
    SETB  INT0          ;設定INT0為負緣觸發
    MOV   IP,#00000001B ;設定INT0為高中斷優先權
    MOV   IE,#10000001B ;致能INT0, 注意EA也要設為1    
你試試看就知道了.基本上不須要寫程式去clear它的. 它會自己清為0的.
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?
系統時間:2024-05-04 5:20:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!