找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2137|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

關(guān)于單片機驅(qū)動數(shù)碼管的計數(shù)程序(匯編),求解惑

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:693473 發(fā)表于 2020-3-26 22:39 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
程序目的是用單片機驅(qū)動四位一體的數(shù)碼管動態(tài)顯示計數(shù)從0~2000,計滿歸零,目前存在問題為仿真動態(tài)掃描的時候總是只有一個數(shù)碼管點亮,計數(shù)正常,但是數(shù)碼管卻輪流閃爍,想要的效果是視覺上四個數(shù)碼管都能正常顯示,程序如下,希望有大神為我解惑,萬分感激。


NAME HW
PROG        SEGMENT        CODE          ;定義代碼段
STACK        SEGMENT        DATA          ;定義數(shù)據(jù)段
RSEG STACK                                  ;選擇stack段                  
        DS    10H             ;16字節(jié)堆棧
        CSEG  AT   0              ;聲明代碼段開始位置
        USING        0             ;使用工作寄存器組0        rs1 rs0 =00
        LJMP  START                  ;跳轉(zhuǎn)至START執(zhí)行
        RSEG  PROG                  ;選擇PROG段
START:  MOV   SP,#STACK-1        ;重新選擇堆棧指針位置
              MOV 0x50,#0                ;0x50為全局變量 個位顯示
                MOV 0x51,#0                        ;十位顯示
                MOV 0x52,#0                ;百位顯示
                MOV 0x53,#0                        ;千位顯示
                SETB  P1.1
                CLR   P2.0
                CLR   P2.1
                CLR   P2.2
                CLR   P2.3
                SETB  0x10
KEY:        JB   P1.1,NEXT                ;判斷鍵是否按下
                MOV  R4, #10            ;延時去抖動
                CALL DELAY
                JB   P1.0, NEXT
LOOP:        JNB  P1.0, LOOP
        CPL  0x10
NEXT:   JNB  0X10, NEXT1    ;處理數(shù)碼管
                MOV  LEDVAL,0x50    ;將個位數(shù)字送入LEDVAL
                MOV  R4,#10  
                CALL SHOW_NUM
                SETB P2.3                                ;
                CALL DELAY
                CPL  P2.3
                MOV  LEDVAL,0x51    ;將十位數(shù)字送入LEDVAL
                CALL SHOW_NUM
                SETB P2.2                        ;               
                CALL DELAY
                CPL  P2.2
                MOV  LEDVAL,0x52    ;將百位數(shù)字送入LEDVAL
                CALL SHOW_NUM
                SETB P2.1                        ;               
                CALL DELAY
                CPL  P2.1
                MOV  LEDVAL,0x53    ;將千位數(shù)字送入LEDVAL
                CALL SHOW_NUM
                SETB P2.0                        ;               
                CALL DELAY
                CPL  P2.0
                INC  0x50
                MOV  A, #9                    
                CLR  C
                SUBB A, 0x50        ;A=A-(0X50)         判斷個位是否大于9
                JNC  NEXT1
                MOV  0X50,#0        ;個位清零
                INC  0x51
                MOV  A, #9                    
                CLR  C
                SUBB A, 0x51        ;A=A-(0X51)         判斷十位是否大于9
                JNC  NEXT1
                MOV  0X51,#0        ;十位清零
                INC  0x52
                MOV  A, #9                    
                CLR  C
                SUBB A, 0x52        ;A=A-(0X52)         判斷百位是否大于9
                JNC  NEXT1
                MOV  0X52,#0        ;百位清零
                INC  0x53
                MOV  A, #2                    
                CLR  C
                SUBB A, 0x53        ;A=A-(0X53)         判斷千位是否大于2
                JNC  NEXT1
                LJMP START          ;歸零
NEXT1:        LJMP KEY
SHOW_NUM:  PUSH DPL
           PUSH DPH                    ;為了防止DPTR被篡改
           MOV A,LEDVAL         
           MOV DPTR,#zixing_base
           MOVC A,@A+DPTR
           MOV  P0,A
           POP DPH
           POP DPL
           RET
DELAY:
NEXT2: MOV R5,#255
        MOV R6,#255
NEXT3: DJNZ  R5, NEXT3          ;循環(huán)255次
NEXT4: DJNZ  R6, NEXT4          ;循環(huán)255次
        DJNZ  R4, NEXT2          
        RET
zixing_base: DB 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
RSEG  STACK
LEDVAL:  DS  1
END

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:401564 發(fā)表于 2020-3-26 23:23 | 只看該作者
NAME HW
PROG        SEGMENT        CODE          ;定義代碼段
STACK        SEGMENT        DATA          ;定義數(shù)據(jù)段
RSEG STACK                                  ;選擇stack段                  
        DS    10H             ;16字節(jié)堆棧
        CSEG  AT   0              ;聲明代碼段開始位置
        USING        0             ;使用工作寄存器組0        rs1 rs0 =00
        LJMP  START                  ;跳轉(zhuǎn)至START執(zhí)行
        RSEG  PROG                  ;選擇PROG段
START:  MOV   SP,#STACK-1        ;重新選擇堆棧指針位置
你能完全理解這一段代碼什么意思嗎?
我看不明白,我是用匯編的,但我不想明白這一段代碼是干嘛的
匯編和硬件是直接關(guān)系的,代碼放什么位置都是很重要的,一個程序下來,代碼多功能卻單一,一個簡單的功能往往要很多代碼去執(zhí)行
所以,匯編最好是不要用太多偽指令,代碼開始用ORG 指定,一個功能最好用CALL子程序,而不是用JMP跳轉(zhuǎn),這樣一來,LOOP循環(huán)部分一般都是可以十來條指令就可以了,有問題就比較容易在子程序中查找
回復(fù)

使用道具 舉報

板凳
ID:123289 發(fā)表于 2020-3-27 06:47 | 只看該作者
如果你能不使用DELAY()就成功了!
寫程序先畫框圖,在框圖上直通再寫程序,當你在一個管子顯示時DELAY了其它三個管子這時會如何呢?是明?是暗?顯示了什么?你想過沒有?“閃”是什么意思呢?意味著什么呢?
想清楚了,弄明白了,程序就OK了。
回復(fù)

使用道具 舉報

地板
ID:693473 發(fā)表于 2020-3-27 11:16 | 只看該作者
yzwzfyz 發(fā)表于 2020-3-27 06:47
如果你能不使用DELAY()就成功了!
寫程序先畫框圖,在框圖上直通再寫程序,當你在一個管子顯示時DELAY了 ...

如果不用delay的話應(yīng)該就看不到顯示效果了吧,數(shù)碼管的動態(tài)掃描原理應(yīng)該是一個個掃描過去的啊,因為我用c51語言編寫也是這樣但是可以實現(xiàn),然后我這個匯編程序也是按照c51的思路來寫的,但是卻無法實現(xiàn),我也是第一次寫匯編可能不太懂,麻煩能不能詳細講講,萬分感謝。
回復(fù)

使用道具 舉報

5#
ID:693473 發(fā)表于 2020-3-27 11:24 | 只看該作者
Y_G_G 發(fā)表于 2020-3-26 23:23
NAME HW
PROG        SEGMENT        CODE          ;定義代碼段
STACK        SEGMENT        DATA      ...

我寫這一段的目的就相當于是初始化定義的作用,開辟地址空間可以使用,之所以不用ORG指定是想讓系統(tǒng)去自動分配,我也是第一次寫匯編程序,可能不太懂,我回去試試直接指定,還有感謝你的經(jīng)驗分享,然后我覺得我的顯示有問題是因為顯示的那段程序可能有問題,我自己看了很久也不知道怎么改,不知道能否幫忙看看,指導指導。
回復(fù)

使用道具 舉報

6#
ID:401564 發(fā)表于 2020-3-27 15:38 | 只看該作者
我看不太懂你的代碼
干脆我自己寫一個了,以下就是我寫的,這個程序仿真不一定行,但實際肯定是可以的,我已經(jīng)在自己的板子上燒錄運行過了,你可以參考一下
每個人寫代碼的習慣都是不一樣的, 我不太習慣由編譯器指定地址,有時候要用到連續(xù)的地址,我不知道由編譯指定的地址是不是連續(xù),所以,就自己指定了,久了就成了一種習慣了


/*0-2000計數(shù)程序
;單片機型號:STC8a4k32s2,使用片上24MHZ晶振
如果使用其它型號單片機,延時要調(diào)節(jié)一下
;COM1,COM2和OUT可以在EQU中修改
;仿真的時候自己做一些修改就可以了,這是一個已經(jīng)在開發(fā)板上驗證過的程序*/
;===========================================================================
COM0                        EQU                P2.0
COM1                        EQU                P2.1
COM2                        EQU                P2.2
COM3                        EQU                P2.3        ;數(shù)碼管的4個位選端口
S1                                BIT                P1.5        ;按鍵
OUT                                EQU                P0                ;PO用于顯示
P2M0                        EQU                096H        ;
P2M1                        EQU                095H        ;控制P2端口輸出模式的兩個寄存器
;===========================================================================
LED_1                        DATA        030H        ;顯示電壓用的LED位的個位
LED_10                        DATA        031H        ;顯示電壓用的LED位的十位
LED_100                        DATA        032H        ;顯示電壓用的LED位的百位
LED_1000                DATA        033H        ;顯示電壓用的LED位的千位
DIV_L                        DATA        034H        ;除法高位用的緩存器
DIV_H                        DATA        035H        ;除法低位用的緩存器
DATA_BUF_L                DATA        036H        ;數(shù)據(jù)暫存器的低位
DATA_BUF_H                DATA        037H        ;數(shù)據(jù)暫存器的高位
DATA_K_L                DATA        038H        ;數(shù)據(jù)2000的低位
DATA_K_H                DATA        039H        ;數(shù)據(jù)2000的高位
;===================================================
                ORG         0000H
                LJMP         MAIN
                ORG         0100H
MAIN:                MOV                DATA_K_L,#00H
                                MOV                DATA_K_H,#00H        ;
                                MOV                P2M1,#000H                ;
                                MOV                P2M0,#0FFH                ;P2端口設(shè)定成強推挽輸出
;========================================
LOOP_0:         JB                S1,LOOP_1                ;
                                CALL        S1_DISP                        ;調(diào)用按鍵處理子程序
LOOP_1:                        CALL        DISPLAY                        ;
                                JMP                LOOP_0                        ;
;==============================================================================================================
;按鍵處理子程序
S1_DISP:                CALL        DISPLAY                        ;調(diào)用顯示一次,就當作是去抖動
                                JNB                S1,S1_DISP                ;這個可以不要,有的話就是當你按下按鍵不放的時候,顯示不會滅燈,
                                                                                ;數(shù)字也不會一直的加上去,調(diào)試的時候不要這條指令,就可以快速的調(diào)到2000循環(huán)
                                ;========================
                                CLR                C                                ;
                                MOV                A,DATA_K_L                ;
                                ADD                A,#001H                        ;低位加1
                                MOV                DATA_K_L,A                ;
                                MOV                A,DATA_K_H                ;
                                ADDC        A,#000H                        ;高位帶進位加0
                                MOV                DATA_K_H,A                ;
                                ;========================
                                CLR                C
                                MOV                A,#LOW(2000)        ;
                                SUBB        A,DATA_K_L                ;
                                MOV                A,#HIGH(2000)        ;
                                SUBB        A,DATA_K_H                ;
                                JNC                S1_DISP_0                ;C進位標志位為0,就表示還沒有加到2000
                                MOV                DATA_K_L,#00H        ;
                                MOV                DATA_K_H,#00H        ;
S1_DISP_0:
RET                                ;返回
;===========================================================================
;顯示子程序                                               
DISPLAY:        MOV                B,DATA_K_L
                                MOV                A,DATA_K_H                 ;
                                CALL        DATA_DISP                 ;2000的10進制數(shù)據(jù)拆分為4個倍數(shù),并存放在四個地址中
                                ;===================================================
                                MOV                A,LED_1
                                CLR                COM0                        ;打開位選
                                CALL        DISP_LED                ;數(shù)碼管通過查表顯示
                                CALL        DELAY1MS                ;延時1mS
                                SETB        COM0                        ;關(guān)閉位選
                                ;===================================================
                                MOV                A,LED_10
                                CLR                COM1                        ;打開位選
                                CALL        DISP_LED                ;數(shù)碼管通過查表顯示
                                CALL        DELAY1MS                ;延時1mS
                                SETB        COM1                        ;關(guān)閉位選
                                ;===================================================
                                MOV                A,LED_100
                                CLR                COM2                        ;打開位選
                                CALL        DISP_LED                ;數(shù)碼管通過查表顯示
                                CALL        DELAY1MS                ;延時1mS
                                SETB        COM2                        ;關(guān)閉位選
                                ;===================================================
                                MOV                A,LED_1000
                                CLR                COM3                        ;打開位選
                                CALL        DISP_LED                ;數(shù)碼管通過查表顯示
                                CALL        DELAY1MS                ;延時1mS
                                SETB        COM3                        ;關(guān)閉位選
                                ;===================================================
RET
;=================================================================================================
;數(shù)碼管查表顯示
DISP_LED:                MOV         DPTR,#TABLE
                                MOVC         A,@A+DPTR
                                MOV         OUT,A                         ;
                /*                CALL        DELAY1MS                ;延時1mS,如果延時放在這里掃描顯示部分可以少一點,放在顯示那是為了方便理解而已*/
RET       
;==================================================================================================
;這個是1mS的延時程序,在STC下載器中可以用軟件自動計算
;如果是仿真,可以相應(yīng)的減少延時的時長                                       
DELAY1MS:                PUSH 30H
                                PUSH 31H
                                MOV 30H,#32
                                MOV 31H,#39
NEXT:                        DJNZ 31H,NEXT
                                DJNZ 30H,NEXT
                                POP 31H
                                POP 30H
RET
;===================================================================================================
;DATA_DISP==============數(shù)據(jù)拆分,把一個數(shù)拆分成四個數(shù),用于顯示======================
;把16進制的高低兩個字節(jié)分別放到A和B,處理之后,個十百千會分別放到4個地址中,使用減法運算來達到除法的效果
;進入之前要先把高位數(shù)據(jù)存放到A,低位數(shù)據(jù)存放到B               
DATA_DISP:                MOV                LED_1,#0
                                   MOV                LED_10,#0
                                   MOV                LED_100,#0
                                   MOV                LED_1000,#0                ;先把四個清除
                                   MOV                DATA_BUF_H,A        ;
                                   MOV                DATA_BUF_L,B        ;把數(shù)據(jù)傳送到緩沖器中
                                   MOV                R0,#0E8H                ;
                                   MOV                R1,#03H                        ;1000的16進制為03E8H
                                MOV                R2,#100
                                MOV                R3,#10
                                MOV                R4,#0
SUB_1000:                  CLR                C
                                MOV                A,DATA_BUF_L
                                SUBB        A,R0
                                MOV                DIV_L,A;
                                MOV         A,DATA_BUF_H;
                                SUBB        A,R1
                                MOV                DIV_H,A                       
                                JC                SUB_100                       
                                MOV                DATA_BUF_L,DIV_L
                                MOV         DATA_BUF_H,DIV_H
                                INC                LED_1000
                                JMP                SUB_1000
SUB_100:                CLR                C
                                MOV                A,DATA_BUF_L
                                SUBB        A,R2
                                MOV                DIV_L,A                       
                                MOV         A,DATA_BUF_H;
                                SUBB        A,R4
                                MOV                DIV_H,A                       
                                JC                SUB_10                       
                                MOV                DATA_BUF_L,DIV_L
                                MOV         DATA_BUF_H,DIV_H
                                INC                LED_100
                                JMP                SUB_100
SUB_10:                        MOV                A,DATA_BUF_L
                                MOV         B,R3
                                DIV                AB
                                MOV                LED_10,A
                                MOV                LED_1,B
RET
;===================================================================================
TABLE:                DB                 11111100B,01100000B,11011010B,11110010B,01100110B,10110110B,10111110B,11100000B,11111110B,11110110B        ;表:共陰數(shù)碼管 0-9
END

回復(fù)

使用道具 舉報

7#
ID:693473 發(fā)表于 2020-3-27 20:45 | 只看該作者
Y_G_G 發(fā)表于 2020-3-27 15:38
我看不太懂你的代碼
干脆我自己寫一個了,以下就是我寫的,這個程序仿真不一定行,但實際肯定是可以的,我已經(jīng) ...

好的,我好好參考一下,十分感謝,還勞煩親自寫一個。
回復(fù)

使用道具 舉報

8#
ID:87166 發(fā)表于 2020-3-27 21:55 | 只看該作者
三個亮,一個不良,你排查下問題,動態(tài)掃描,就是讓你的每一個燈的亮都延時一部分時間。一個不亮,要么你沒有點亮它,要么延遲的時間不夠,或者你在點亮的同時,干了其他事情把他滅了。不要老是看程序,主要要建立下邏輯思維。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表