打印
[51单片机]

新人学习51,该程序不能正常复位,其他程序可以求原因

[复制链接]
1288|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
迹水湾|  楼主 | 2015-5-27 20:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 迹水湾 于 2015-5-27 21:29 编辑

结果正确就是不能复位,其他的程序都可以复位
;按键控制数码管显示加减
;单片机stc89c52rc         12Mhz
;共阴数码管
;两片74hc573控制8位数码管
SW0        BIT        P1.0                ;定义SW0为按键加
SW1        BIT        P1.1                ;定义SW1为按键-
D_EN        BIT        P1.2        ;定义段码锁存端
W_EN        BIT        P1.3        ;定义位码锁存端
COM        EQU        P0                        ;将P0定义为数据端
SHIWEI        EQU        40H                ;定义十位存到40h
GEWEI        EQU        41H                ;定义个位存到41h
BUFFER        EQU        42H                ;定义缓存区

        ORG        0000H                ;复位初始化地址
        SJMP        START        ;
        ORG        0030H                ;
START:                                ;初始化
        MOV        SP,60H                ;移动堆栈指针
        SETB        SW0                ;按键+置一
        SETB        SW1                ;按键-置一
        SETB        W_EN        ;打开位选使能
        MOV        COM,#0FFH        ;让所有的数码管都不选中
        CLR        W_EN                ;关闭位选使能
        SETB        D_EN        ;打开段选使能
        MOV        COM,#00H        ;熄灭所有的数码管
        CLR        D_EN                ;关闭段选使能
        CLR        BUFFER                ;清空缓冲区
        MOV        DPTR,#TAB        ;让DPTR指向显示表列
        CLR        SHIWEI                ;清空十位
        CLR        GEWEI                ;清空个位

MAIN:                                ;主函数
        CALL        KEYPORT        ;执行按键扫描程序
        CALL        SHOW        ;执行显示程序
        SJMP        MAIN        ;形成主循环

KEYPORT:                                ;按键子程序
                CALL        DELAY10_MS        ;延时10ms跳过按键抖动区
                JNB        SW0,JIA                        ;判断按键+是否按下,按下执行加法程序
                JNB        SW1,JIAN                ;判断按键-是否按下,按下执行减法程序
        HUI:RET                                        ;若未按下返回主循环
        JIA:                                        ;加法程序
                JNB        SW0,$                        ;判断按键是否释放,未释放pc指针不变
                INC        BUFFER                        ;缓冲区数据加1
                SJMP        HUI                        ;返回主程序
        JIAN:                                        ;减法程序
                JNB        SW1,$                        ;缓冲区数据
                DEC        BUFFER                        ;缓冲区数据减1
                SJMP        HUI                        ;返回主程序

SHOW:                                        ;显示子程序
        MOV        A,BUFFER                ;将缓冲区数据给累加器a
        MOV        B,#10                        ;给寄存器b赋值10
        DIV        AB                                ;执行A/b,结果商(十位)自动存到A,余数(个位)存到b
        MOV        SHIWEI,A                ;将累加器a的十位保存
        MOV        GEWEI,B                        ;将寄存器b中的个位保存
                                                ;显示十位
        MOV        A,SHIWEI                ;将十位的数据给a
        MOVC        A,@A+DPTR        ;将A+DPTR的结果作为地址找到显示的数据
        SETB        W_EN                ;打开位锁存
        MOV        COM,#0FEH                ;设定显示位
        CLR        W_EN                        ;关闭位锁存
        SETB        D_EN                ;打开段锁存
        MOV        COM,A                        ;将显示数据给数码管显示
        CLR                D_EN                ;关闭段锁存
        CALL        DELAY_US        ;延时显示
        SETB        D_EN                ;打开段锁存
        MOV        COM,#00H                ;熄灭数码管,消影
        CLR        D_EN                        ;关闭段锁存
                                                ;显示个位
        MOV        A,GEWEI                        ;将个位数据给a
        MOVC        A,@A+DPTR        ;将a+DPTR作为地址找到显示数据
        SETB        W_EN                ;打开位锁存
        MOV        COM,#0FDH                ;设定显示位
        CLR        W_EN                        ;关闭位锁存
        SETB        D_EN                ;打开段锁存
        MOV        COM,A                        ;将个位数据送到数码管显示
        CLR                D_EN                ;关闭段锁存
        CALL        DELAY_US        ;延时显示
        SETB        D_EN                ;打开段锁存
        MOV        COM,#00H                ;熄灭数码管
        CLR        D_EN                        ;关闭段锁存
        RET                                        ;返回主程序

DELAY10_MS:                        ;延时大约10ms,跳过按键抖动区
        MOV        R7,#50                ;给外层循环赋值50
        D0:        
        MOV        R6,#100                ;给内层循环赋值100
        DJNZ        R6,$        ;R6-- != 0,PC指针不变
        DJNZ        R7,D0        ;R7-- != 0,        再次进入内层循环
        RET                                ;延时子程序返回按键子程序

DELAY_US:                        ;设定数码管显示时间
        MOV        R7,#6                ;给外层循环赋值6
        D1:        
        MOV        R6,#100                ;给内层循环赋值100
        DJNZ        R6,$        ;6-- != 0,PC指针不变
        DJNZ        R7,D1        ;R7-- != 0,        再次进入内层循环
        RET                                ;返回显示子程序


TAB:                                ;共阴数码管显示表列0->9
        DB        03fH,006H,05bH,04fH,066H
        DB        06dH,07dH,007H,07fH,06fH

        END                                ;汇编结束

相关帖子

沙发
迹水湾|  楼主 | 2015-5-27 20:21 | 只看该作者
在加减过后数码管的显示不变,并且还能在加减,说明42h单元复位保持就是复位pc指针没有跳到0000h单元
其他的程序都能够复位

使用特权

评论回复
板凳
迹水湾|  楼主 | 2015-5-27 20:28 | 只看该作者
本帖最后由 迹水湾 于 2015-5-27 21:30 编辑

找不到原因

使用特权

评论回复
地板
迹水湾|  楼主 | 2015-5-27 20:30 | 只看该作者
;按键控制数码管显示加减
;单片机stc89c52rc         12Mhz
;共阴数码管
;两片74hc573控制8位数码管
SW0        BIT        P1.0                ;定义SW0为按键加
SW1        BIT        P1.1                ;定义SW1为按键-
D_EN        BIT        P1.2        ;定义段码锁存端
W_EN        BIT        P1.3        ;定义位码锁存端
COM        EQU        P0                        ;将P0定义为数据端
SHIWEI        EQU        40H                ;定义十位存到40h
GEWEI        EQU        41H                ;定义个位存到41h
BUFFER        EQU        42H                ;定义缓存区
       
        ORG        0000H                ;复位初始化地址
        SJMP        START        ;
        ORG        0030H                ;
START:                                ;初始化
        MOV        SP,60H                ;移动堆栈指针
        SETB        SW0                ;按键+置一
        SETB        SW1                ;按键-置一
        SETB        W_EN        ;打开位选使能
        MOV        COM,#0FFH        ;让所有的数码管都不选中
        CLR        W_EN                ;关闭位选使能
        SETB        D_EN        ;打开段选使能
        MOV        COM,#00H        ;熄灭所有的数码管
        CLR        D_EN                ;关闭段选使能
        CLR        BUFFER                ;清空缓冲区
        MOV        DPTR,#TAB        ;让DPTR指向显示表列
        CLR        SHIWEI                ;清空十位
        CLR        GEWEI                ;清空个位

MAIN:                                ;主函数
        CALL        KEYPORT        ;执行按键扫描程序
        CALL        SHOW        ;执行显示程序
        SJMP        MAIN        ;形成主循环

KEYPORT:                                ;按键子程序
                CALL        DELAY10_MS        ;延时10ms跳过按键抖动区
                JNB        SW0,JIA                        ;判断按键+是否按下,按下执行加法程序
                JNB        SW1,JIAN                ;判断按键-是否按下,按下执行减法程序
        HUI:RET                                        ;若未按下返回主循环
        JIA:                                        ;加法程序
                JNB        SW0,$                        ;判断按键是否释放,未释放pc指针不变
                INC        BUFFER                        ;缓冲区数据加1
                SJMP        HUI                        ;返回主程序
        JIAN:                                        ;减法程序
                JNB        SW1,$                        ;缓冲区数据
                DEC        BUFFER                        ;缓冲区数据减1
                SJMP        HUI                        ;返回主程序

SHOW:                                        ;显示子程序
        MOV        A,BUFFER                ;将缓冲区数据给累加器a
        MOV        B,#10                        ;给寄存器b赋值10
        DIV        AB                                ;执行A/b,结果商(十位)自动存到A,余数(个位)存到b
        MOV        SHIWEI,A                ;将累加器a的十位保存
        MOV        GEWEI,B                        ;将寄存器b中的个位保存
                                                ;显示十位
        MOV        A,SHIWEI                ;将十位的数据给a
        MOVC        A,@A+DPTR        ;将A+DPTR的结果作为地址找到显示的数据
        SETB        W_EN                ;打开位锁存
        MOV        COM,#0FEH                ;设定显示位
        CLR        W_EN                        ;关闭位锁存
        SETB        D_EN                ;打开段锁存
        MOV        COM,A                        ;将显示数据给数码管显示
        CLR                D_EN                ;关闭段锁存
        CALL        DELAY_US        ;延时显示
        SETB        D_EN                ;打开段锁存
        MOV        COM,#00H                ;熄灭数码管,消影
        CLR        D_EN                        ;关闭段锁存
                                                ;显示个位
        MOV        A,GEWEI                        ;将个位数据给a
        MOVC        A,@A+DPTR        ;将a+DPTR作为地址找到显示数据
        SETB        W_EN                ;打开位锁存
        MOV        COM,#0FDH                ;设定显示位
        CLR        W_EN                        ;关闭位锁存
        SETB        D_EN                ;打开段锁存
        MOV        COM,A                        ;将个位数据送到数码管显示
        CLR                D_EN                ;关闭段锁存
        CALL        DELAY_US        ;延时显示
        SETB        D_EN                ;打开段锁存
        MOV        COM,#00H                ;熄灭数码管
        CLR        D_EN                        ;关闭段锁存
        RET                                        ;返回主程序

DELAY10_MS:                        ;延时大约10ms,跳过按键抖动区
        MOV        R7,#50                ;给外层循环赋值50
        D0:       
        MOV        R6,#100                ;给内层循环赋值100
        DJNZ        R6,$        ;R6-- != 0,PC指针不变
        DJNZ        R7,D0        ;R7-- != 0,        再次进入内层循环
        RET                                ;延时子程序返回按键子程序

DELAY_US:                        ;设定数码管显示时间
        MOV        R7,#6                ;给外层循环赋值6
        D1:       
        MOV        R6,#100                ;给内层循环赋值100
        DJNZ        R6,$        ;6-- != 0,PC指针不变
        DJNZ        R7,D1        ;R7-- != 0,        再次进入内层循环
        RET                                ;返回显示子程序


TAB:                                ;共阴数码管显示表列0->9
        DB        03fH,006H,05bH,04fH,066H
        DB        06dH,07dH,007H,07fH,06fH

        END                                ;汇编结束
               

使用特权

评论回复
5
cuya| | 2015-5-27 21:04 | 只看该作者
我会非常非常佩服那个能仔细阅读你的汇编程序并指出错误的人。

使用特权

评论回复
6
迹水湾|  楼主 | 2015-5-27 21:24 | 只看该作者
cuya 发表于 2015-5-27 21:04
我会非常非常佩服那个能仔细阅读你的汇编程序并指出错误的人。

木有人回复,软件仿真可以,为什么事实就是可以运行,结果也正确,就是不能复位不能成功

使用特权

评论回复
7
迹水湾|  楼主 | 2015-5-27 21:27 | 只看该作者
cuya 发表于 2015-5-27 21:04
我会非常非常佩服那个能仔细阅读你的汇编程序并指出错误的人。

之前是copy的贴吧里的发表,它缺掉了制表符

使用特权

评论回复
8
lyjian| | 2015-5-27 22:15 | 只看该作者
CLR是位操作指令,不是字节操作指令。
CLR        BUFFER                ;清空缓冲区
CLR        SHIWEI                ;清空十位
CLR        GEWEI    
这几条都是错的

使用特权

评论回复
9
lyjian| | 2015-5-27 22:22 | 只看该作者
改成:
CLR        A
MOV       BUFFER,A             ;清空缓冲区
MOV       SHIWEI,A              ;清空十位
MOV       GEWEI,A  

使用特权

评论回复
10
迹水湾|  楼主 | 2015-5-27 22:34 | 只看该作者
对只能clr A和bit非常感谢上面那位大神

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

44

帖子

1

粉丝