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

利用INT0和計時器0做轉數計算

答題得分者是:阿信
cheng07
一般會員


發表:8
回覆:12
積分:4
註冊:2005-05-09

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-11-25 17:26:31 IP:210.240.xxx.xxx 未訂閱
這是我畢業專題要做的東西 構想是以風力驅動風扇,帶動光柵使光遮斷器產生方波,再將方波送到INT0,計時器0計時1秒後,將總方波數除以光柵數,乘以60轉換成轉速RPM,再送到20*2的LCD上顯示。如果允許的話再將轉速轉換成風速一起顯示在LCD上。 程式的寫法是將中斷副程式作對A+1的動作來做計數,目前卡到的問題是A計數的值是2進位還是16進位?A的值要如何做計算?還有要怎麼將計算的結果顯示在LCD特定的位置上?例如第一行第幾個字等等。    現在剩下一個月的時間可以做了,可是感覺程式怎麼樣都搞不定,所以來版上請教各位 以下附上程式碼及電路圖
        ORG     0000H
        JMP     START
        ORG     0003H
        JMP     INT0    START:  ACALL   INIT
        MOV     TCON,#00000001B
        MOV     IP,#00000010B
        SETB    EA
        SETB    EX0
        SETB    ET0
        ACALL   TIME0    INIT:   ACALL   DELAY            MOV     A,#38H
        ACALL   WRINS
        MOV     A,#38H
        ACALL   WRINS
        MOV     A,#38H
        ACALL   WRINS
        MOV     A,#38H
        ACALL   WRINS            MOV     A,#08H
        ACALL   WRINS            MOV     A,#01H
        ACALL   WRINS            MOV     A,#06H
        ACALL   WRINS            MOV     A,#0CH
        ACALL   WRINS
        ACALL   LINE1
        MOV     DPTR,#TAB1
        ACALL   DISPLAY            ACALL   LINE2
        MOV     DPTR,#TAB2
        ACALL   DISPLAY
        CLR     A
        RET
;
DISPLAY:MOV     R7,#00H
NEXT:   MOV     A,R7
        MOVC    A,@A+DPTR
        CJNE    A,#10H,DSP
        RET
DSP:    ACALL   WRDATA
        INC     R7
        AJMP    NEXT    INT0:   INC     A
        RETI    LINE1:  MOV     A,#10000000B
        ACALL   WRINS
        RET    LINE2:  MOV     A,#11000000B
        ACALL   WRINS
        RET    WRINS:  MOV     P2,#00011111B   ;RS=0,R/W=0,E=0
        NOP
        SETB    P2.5            ;E=1
        MOV     P0,A
        NOP
        CLR     P2.5            ;E=0
        ACALL   DLY1
        RET    WRDATA: MOV     P2,#10011111B   ;RS=1,R/W=0,E=0
        NOP
        SETB    P2.5            ;E=1
        MOV     P0,A
        NOP
        CLR     P2.5            ;E=0
        ACALL   DLY2
        RET
;
DELAY:  MOV     R6,#100
DL:     MOV     R7,#200
        DJNZ    R7,$
        DJNZ    R6,DL
        RET
;
DLY1:   MOV     R6,#20
DL1:    MOV     R7,#200
        DJNZ    R7,$
        DJNZ    R6,DL1
        RET
;
DLY2:   MOV     R6,#80
        DJNZ    R6,$
        RET    TIME0:  MOV     TMOD,#00000001B
        MOV     TH1,#0
        MOV     TL1,#0
        MOV     TCON,#01000000B
DEL1S:  MOV     R7,#20
A2:     MOV     TH0,#>(65536-50000)
        MOV     TL0,#<(65536-50000)
        SETB    TR0
A1:     JNB     TF0,A1
        CLR     TR0
        CLR     TF0
        DJNE    R7,A2
        RET
;
TAB1:   DB      'Speed:     R.P.M'
        DB      10H
TAB2:   DB      'Wind:     m/s'
        DB      10H            END
很感謝各位能把我的問題看完,小弟絞盡腦汁能寫出的程式碼就只有如上了,還望板上各位板友幫忙,謝謝!
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-11-28 10:44:16 IP:61.66.xxx.xxx 未訂閱
你的程式還差很多的樣子 計時器都沒有設定    首先要產生1秒的計時中斷 累加器要16位元    下面是一個基本的程式架構 程式要模組化    
        org        0000H
        jmp        START
        org        0003H
        jmp        INT0
        org        000BH
        jmp        Timer0
;-------------------------
        org        0030H
Start:        ;啟動
        call        Init
  Loop: ;無窮迴圈
        
        jmp Loop
;-------------------------
Init:        ;初始化設定            ret
;-------------------------
INT0:        ;外部中斷副程式
        PUSH        A
        PUSH        PSW            POP        PSW
        POP        A
        reti
;-------------------------
Timer0:        ;計時中斷副程式
        PUSH        A
        PUSH        PSW            POP        PSW
        POP        A
        reti
;-------------------------
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-11-30 17:34:44 IP:61.66.xxx.xxx 未訂閱
下面是我修改的程式 你的光柵是幾格跟RPM與風速的比例關係為何    你去找到4位數的16進制轉BCD程式 跟16位元除8位元除法程式 再把它補進去
--------------------------------
;R3:PULSE_HIGH(脈波計數高位元組)
;R4:PULSE_LOW (脈波計數低位元組)    DISP10        EQU        40H        ;LCM緩衝區 第一列
DISP20        EQU        50H        ;LCM緩衝區 第二列    fg_1S        .REG        20H.0        ;1秒旗標            CNT_1S        EQU        30H        ;1秒的計數器
;--------------------------------
        ORG     0000H
        JMP     START
        ORG     0003H
        JMP     INT0
        ORG        000BH
        JMP        INT_TIMER0
;--------------------------------
        ORG        0030H
START:
        CALL        INIT
  LOOP:
        JNB        fg_1S,LOOP
        CLR        fg_1S
        CALL        DISP_RPM
        
        JMP        LOOP        
;--------------------------------
INIT:                ;初始化
        CALL        INIT_RAM
        CALL        INIT_LCM
        CALL        INIT_INT
        RET
;--------------------------------
DISP_RPM:
;設光柵為60格 則RPM=1秒脈波數*60/60格        
;RPM=(R6,R5)
;將(R6,R5)轉為4位數字顯示在LCM上
                    ;-----
DISP_SP:
;設風速為RPM/100(M/S)            
        CALL        DISPLAY                    RET
;--------------------------------
INIT_RAM:        ;RAM初始化
        CLR     A
        MOV        R0,#7FH
  IR_LP:
        MOV        @R0,A
        DJNZ        R0,IR_LP            CLR        R3
        CLR        R4            MOV        CNT_1S,#50            RET
;--------------------------------
INIT_LCM:        ;LCM初始化
        ACALL   DELAY
        MOV     A,#38H        ;8位元 雙排 5*7
        ACALL   WRINS
        MOV     A,#08H        ;關閉LCD顯示
        ACALL   WRINS
        MOV     A,#01H        ;清除DD RAM
        ACALL   WRINS
        MOV     A,#06H        ;寫入字元時 AC=AC 1
        ACALL   WRINS
        MOV     A,#0CH        ;開啟LCD顯示 游標不顯示
        ACALL   WRINS
        CALL        LOAD        ;載入顯示資料
        CALL        DISPLAY        ;顯示
        RET
;--------------------------------
INIT_INT:        ;中斷初始化
        MOV        SP,#60H                ;堆疊指標於60H
        MOV        TMOD,#01H        ;TIMER0為模式1
        MOV        IE,#10000011B        ;致能主中斷,外部中斷及TIMER0中斷
        MOV        TH0,#>(65536-20000)        ;TIMER0中斷 每20mS
        MOV        Tl0,#<(65536-20000)
        MOV     TCON,#00010001B        ;TIMER0啟動 INT0為負緣觸發
        MOV     IP,#00000010B        ;TIMER0為高優先權
        RET
;--------------------------------
LOAD:                ;載入預設字元到顯示緩衝區
        MOV        DPTR,#TAB1
        MOV        R0,#DISP10
        CALL        STRBUF
        MOV        DPTR,#TAB2
        MOV        R0,#DISP20
        CALL        STRBUF
        RET
;--------------------------------
STRBUF:                ;由DPTR載入16BYTE到R0顯示緩衝區
        MOV        R2,#10H
  STR1:
        CLR        A
        MOVC        A,@A DPTR
        MOV        @R0,A
        INC        R0
        INC        DPTR
        DJNZ        R2,STR1
        RET
cheng07
一般會員


發表:8
回覆:12
積分:4
註冊:2005-05-09

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-11-30 22:01:27 IP:140.109.xxx.xxx 未訂閱
很謝謝阿信大大撥空幫我修改程式 我這兩天也照您的方法把程式重新改過,不知道這樣子會不會好一點 如下
        ORG        0000H
        JMP        START
        ORG        0003H
        JMP        INT0
        ORG        000BH
        JMP        Timer0
;-------------------------
        ORG        0030H
Start:                                ;啟動
        CALL        Init                ;初始化lcd
        ACALL   LINE1                ;設定顯示第一行第一字
        MOV     DPTR,#TAB1        ;設定顯示
        ACALL   DISPLAY                ;將字元碼送到lcd            ACALL   LINE2                ;設定顯示第二行第一字
        MOV     DPTR,#TAB2
        ACALL   DISPLAY                ;將字元碼送到lcd
        MOV        IE,#10000011        ;設定int0 timer0中段致能
        MOV        IP,#00000010        ;設定timer0高優先權
        MOV        R4,#20                ;令r4=20,以便延時50ms*20=1000ms=1杪
        ACALL        SETUP                ;設定timer0計時時間    Loop:                                  ;無窮迴圈
        
        JMP         Loop
;-------------------------
Init:        
        ACALL        DELAY                ;lcd初始化設定
        MOV        A,#38H
        ACALL        WRINS
        MOV        A,#38H
        ACALL        WRINS
        MOV        A,#38H
        ACALL        WRINS
        MOV        A,#38H
        ACALL        WRINS            MOV        A,#08H
        ACALL        WRINS            MOV        A,#01H
        ACALL        WRINS            MOV        A,#06H
        ACALL        WRINS            MOV        A,#0CH
        ACALL        WRINS                
        RET
;-------------------------
DISPLAY:MOV        R7,#00H                ;將字串字元碼送到lcd
NEXT:        MOV        A,R7
        MOVC        A,@A DPTR
        CJNE        A,#10H,DSP
        RET
DSP:        ACALL        WRDATA
        INC        R7
        AJMP        NEXT
;-------------------------
SETUP:        MOV        TMOD,#00000001B                ;計時器設定計時50ms
        MOV        TL0,#<(65536-50000)
        MOV        TH0,#>(65536-50000)
        RET        
;-------------------------
LINE1:        MOV        A,#10000000B        ;設定從00h開始顯示
        ACALL        WRINS
        RET
;-------------------------
LINE2:        MOV        A,#11000000B        ;設定從40h開始顯示
        ACALL        WRINS
        RET
;-------------------------
LINE3:        MOV        A,#10000110B        ;設定從06h開始顯示轉速
        ACALL        WRINS
        RET
;-------------------------
LINE4:        MOV        A,#11000110B        ;設定從46h開始顯示風速
        ACALL        WRINS
        RET
;-------------------------
INT0:                                ;外部中斷副程式
        INC        A
        RETI
;-------------------------
Timer0:                                ;計時中斷副程式
        PUSH        A
        PUSH        PSW
        ACALL        SETUP                ;重新設定計時值
        DJNZ        R4,#CONT                ;若r4-1不為0則跳至cont
        MOV        R4,#20                ;重新設定r4值
        ACALL        CALCU                   ;跳到計算副程式            POP        PSW
        POP        A
        CLR        A
CONT:        RETI
;-------------------------
WRINS:        MOV        P2,#00011111B   ;RS=0,R/W=0,E=0寫入指令
        NOP
        SETB        P2.5            ;E=1
        MOV        P0,A
        NOP
        CLR        P2.5            ;E=0
        ACALL        DLY1
        RET
;-------------------------
WRDATA:        MOV        P2,#10011111B   ;RS=1,R/W=0,E=0送入資料至lcd
        NOP
        SETB        P2.5            ;E=1
        MOV        P0,A
        NOP
        CLR        P2.5            ;E=0
        ACALL        DLY2
        RET
;-------------------------
CALCU:                                ;計算轉速副程式(還沒有寫出來)            
;-------------------------
DELAY:        MOV        R6,#100                ;延時40ms
DL:        MOV        R7,#200
        DJNZ        R7,$
        DJNZ        R6,DL        
        RE
;-------------------------
DLY2:        MOV        R6,#80                ;延時160us
        DJNZ        R6,$
        RET
;-------------------------
TAB1:        DB        'Speed:     R.P.M'        ;顯示轉速
        DB        10H
;-------------------------
TAB2:        DB        'Wind :     m/s'        ;顯示風速
        DB        10H
;-------------------------            END
我先用市面上的風速計測轉速與風速的關係是1rpm=0.001m/s,等到成品做出來以後,我會再用風速計來校正這個比例的關係 光柵因為我是用厚紙板剪的...所以應該是沒辦法到60格,我只有剪6格來做光柵(不知道這樣會不會有什麼影響?) 我會再去找出4位數16進位轉BCD程式和16位元除8位元除法的程式來補上 還有阿信大您所修改的程式
;R3:PULSE_HIGH(脈波計數高位元組)
;R4:PULSE_LOW (脈波計數低位元組)    DISP10        EQU        40H        ;LCM緩衝區 第一列
DISP20        EQU        50H        ;LCM緩衝區 第二列    fg_1S        .REG        20H.0        ;1秒旗標            CNT_1S        EQU        30H        ;1秒的計數器
這一部分我找了很多書的指令,都看不出來是在做什麼,可以再麻煩您解釋嗎? 再次感謝各位願意把這一大串文章看完... 希望各位能給小弟一些意見 感激不盡 發表人 - CHENG07 於 2005/11/30 22:07:36
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-12-01 09:22:33 IP:211.21.xxx.xxx 未訂閱
//fg_1S        .REG        20H.0        ;1秒旗標         這是定義位元(bit)位址在20H.0    //CNT_1S        EQU        30H        ;1秒的計數器 這是定義位元組(byte)位址在30H    //我只有剪6格來做光柵(不知道這樣會不會有什麼影響?) 會影響解析度 6格的解析度是10RPM 不過這樣程式反而好寫 設在最高轉速為2550RPM就只要用1個位元組就可以計算了 做除法時也簡單 也不用16位元除法副程式了    下面是昨天沒po完的  
DISPLAY:        ;顯示緩衝區資料 顯示在LCM上
        CALL        LINE1        ;第一列
        MOV        R0,#DISP10
        MOV        R2,#10H
  DP1:
        MOV        A,@R0
        CALL        WRDATA
        INC        R0
        DJNZ        R2,DP1
   ;---
        CALL        LINE2        ;第二列
        MOV        R0,#DISP20
        MOV        R2,#10H
  DP2:
        MOV        A,@R0
        CALL        WRDATA
        INC        R0
        DJNZ        R2,DP2
        RET
;--------------------------------
LINE1:  MOV     A,#10000000B
        ACALL   WRINS
        RET
;--------------------------------
LINE2:  MOV     A,#11000000B
        ACALL   WRINS
        RET
;--------------------------------
WRINS:                ;寫指令
        CALL        CKBUSY
        MOV     P2,#00011111B   ;RS=0,R/W=0,E=0
        NOP
        SETB    P2.5            ;E=1
        MOV     P0,A
        NOP
        CLR     P2.5            ;E=0
        RET
;--------------------------------
WRDATA:                ;寫資料
        CALL        CKBUSY
        MOV     P2,#10011111B   ;RS=1,R/W=0,E=0
        NOP
        SETB    P2.5            ;E=1
        MOV     P0,A
        NOP
        CLR     P2.5            ;E=0
        RET
;--------------------------------
CKBUSY:                ;讀取BUZY旗標
        MOV        P0,#0FFH
        CLR        P2.7        ;RS
        SETB        P2.6        ;RW
        SETB        P2.5        ;EN
        MOV        C,P0.7
        CLR        P2.5        ;EN
        JC        CKBUSY
        RET
;--------------------------------
DELAY:  MOV     R6,#100
DL:     MOV     R7,#200
        DJNZ    R7,$
        DJNZ    R6,DL
        RET
;--------------------------------
TIME0:  MOV     TMOD,#00000001B
        MOV     TH1,#0
        MOV     TL1,#0
        MOV     TCON,#01000000B
DEL1S:  MOV     R7,#20
A2:     MOV     TH0,#>(65536-50000)
        MOV     TL0,#<(65536-50000)
        SETB    TR0
A1:     JNB     TF0,A1
        CLR     TR0
        CLR     TF0
        DJNE    R7,A2
        RET
;--------------------------------
INT0:                ;外部中斷
        PUSH        A
        ;PUSH        PSW
        INC     R3        ;16位元脈波累加
        MOV        A,R3
        JNZ        INT0_EX
        INC        R4
INT0_EX:
        ;POP        PSW
        POP        A
        RETI
;--------------------------------
INT_TMR0:        ;TIMER0中斷 20mS
        PUSH        A
        PUSH        PSW
        DJNZ        CNT_1S,IT0_EX
        MOV        CNT_1S,#50
        ;1秒到
        MOV        R5,R3        ;取出計數的值
        MOV        R6,R4
        CLR        R3
        CLR        R4
        SET        fg_1S        ;設定1秒旗標
IT0_EX:
        POP        PSW
        POP        A
        RETI
 
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-12-01 16:11:30 IP:211.21.xxx.xxx 未訂閱
把下面這段DISP_RPM的副程式補上 應該就能顯示轉速跟風速了 程式不是很嚴謹  但學生專題應該可以了 你把程式看懂  再做後續修改 把程式做最佳化!    PS.完成後拍張照片來看看ㄋㄟ     
;--------------------------------
DISP_RPM:
;光柵為6格 則RPM=1秒脈波數*60/6格        
;RPM=(R6,R5)
;將(R6,R5)轉為4位數字顯示在LCM上
 DR_1000:        ;取千位數 R5/100的商
        MOV        A,R5
        MOV        B,#100
        DIV        AB
        AND        A,#30H
        MOV        47H,A        ;把千位數放到第一列第7位
 DR_100:        ;取百位數 餘數/10
        MOV        A,B
        MOV        B,#10
        DIV        AB
        AND        A,#30H
        MOV        48H,A        ;把百位數放到第一列第8位
 DR_10:                ;取十位數 餘數
        MOV        A,B
        AND        A,#30H
        MOV        49H,A        ;把十位數放到第一列第9位
 DR_1:                ;個位數 固定為0
        MOV        4AH,#30H;把個位數放到第一列第10位
   ;-----
DISP_SP:  
;設風速為RPM/80(M/S) (以10的倍數比例 以簡化程式)
 DS_10:                ;取十位數
        MOV        A,R5
        MOV        B,#80 ;<-風速比
        DIV        AB
        AND        A,#30H
        MOV        57H,A        ;把十位數放到第二列第7位
 DS_1:                ;取個位數
        MOV        A,B
        MOV        B,#8  ;<-風速比
        DIV        AB
        AND        A,#30H
        MOV        58H,A        ;把個位數放到第二列第8位
 DS_DOT:        ;小數點
        MOV        59H,#2EH;把小數點放到第二列第9位
 DS_DOT1:        ;取小數
        MOV        A,B
        MOV        B,#10
        MUL        AB        ;先乘10 才能取小數
        MOV        B,#8  ;<-風速比
        DIV        AB
        AND        A,#30H
        MOV        5AH,A        ;把小數放到第二列第10位
        
        CALL        DISPLAY                    RET
;--------------------------------
 
cheng07
一般會員


發表:8
回覆:12
積分:4
註冊:2005-05-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-12-01 22:13:00 IP:210.240.xxx.xxx 未訂閱
PO上成品一起分享,這是當然一定要的! 上次請教的那一段程式,我真的還是一點也看不懂他在作什麼? 課本上也找不到REG EQU這些指令碼 這是因為課本太舊了嗎?    
;R3:PULSE_HIGH(脈波計數高位元組)
;R4:PULSE_LOW (脈波計數低位元組)    DISP10        EQU        40H        ;LCM緩衝區 第一列
DISP20        EQU        50H        ;LCM緩衝區 第二列    fg_1S        .REG        20H.0        ;1秒旗標            CNT_1S        EQU        30H        ;1秒的計數器
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-12-02 08:29:12 IP:211.21.xxx.xxx 未訂閱
這些是假指令(pseudo instruction) ORG : ORG nnH 定義下一行程式的起始位址 END : END 程式結束 DB : Define Byte 定義位元組資料 DW : Define Word 定義字元組資料 EQU : ABC equ 50H 宣告記憶體 REG : bDEF equ 20H.1 宣告位元記憶體 另附上參考網址 http://mail.savs.hcc.edu.tw/~anita/8051/instpseudo.htm
系統時間:2024-07-06 11:15:28
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!