打印

C51控制继电器的问题,请帮小女子看看

[复制链接]
3624|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yrezer|  楼主 | 2008-6-25 22:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这两天在用89C51做一个按键选择的汇编程序,P2.0-P2.7分别接8个继电器,初始状态设为低电平,P3.3和P3.4分别接两个按键,初始为高电平。P3.3用于选择,程序一开始是选定P2.0 ,按一下P3.3,选择P2.1 ,再按一下P3.3选择P2.2,一直选到P2.7再回到P2.0开始继续选择。P3.4用来确定当前的选择,假如P3.3选到P2.5时,按下P3.4,那么P2.5所接的继电器导通,反之则关闭。下面是我写的程序,接触单片机时间不长,这是我写的第一个东西,不太会用中断,只能用这种笨方法来写,总觉得哪不对,又找不出来。请大家帮我看看,水平有限,见笑了。

        ORG   0000H
        LJMP  START

        ORG   0100H

START:  MOV  SP, #5FH
               MOV  P2,  #00H
               MOV 70H, #01H
        
K1:     CLR  A
        MOV  C, P3.3
        MOV  ACC.0, C
        CJNE  A, #01H, K2         ;相等不转移
        
        CLR  A
        MOV  C, P3.4
        MOV  ACC.0, C
        CJNE  A, 70H, K12         
        AJMP  K1

K12:    CPL  P2.0               ;取反
           MOV   70H, P3.4

K2:     CLR A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #0H,  K3

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0, C
        CJNE  A,  70H,  K22
        AJMP  K2

K22:    CPL  P2.1
           MOV  70H, P3.4

K3:     CLR A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #1H,  K4

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0,  C
        CJNE  A, 70H,  K32
        AJMP  K3

K32:    CPL  P2.2
        MOV  70H, P3.4

K4:     CLR A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #0H,  K5

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0,  C
        CJNE  A,  70H,  K42
        AJMP  K4

K42:    CPL  P2.3
        MOV  70H, P3.4

K5:     CLR A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #1H,  K6

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0, C
        CJNE  A,  70H,  K52
        AJMP  K5

K52:    CPL  P2.4
        MOV  70H, P3.4

K6:     CLR  A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #0H,  K7

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0,  C
        CJNE  A,  70H,  K62
        AJMP  K6

K62:    CPL  P2.5
        MOV  70H, P3.4

K7:     CLR A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #1H,  K8

        CLR  A
        MOV  C,  P3.4
        MOV  ACC.0,  C
        CJNE  A,  70H,  K72
        AJMP  K7

K72:    CPL  P2.6
        MOV  70H, P3.4

K8:     CLR  A
        MOV  C,  P3.3
        MOV  ACC.0,  C
        CJNE  A,  #0H,  TURN1
        ACALL  K81
TURN1:  LJMP  K1

K81:    CLR  A
        MOV  C,  P3.4
        MOV  ACC.0,  C
        CJNE  A,  70H,  K82
        AJMP  K8

K82:    CPL  P2.7
        MOV  70H, P3.4
        LJMP  K1        

        END

相关帖子

沙发
一级菜鸟| | 2008-6-25 22:28 | 只看该作者

又来个小女子?

使用特权

评论回复
板凳
5880527| | 2008-6-25 23:40 | 只看该作者

有些散乱,不过也值得鼓励一下

个人感觉用一个定时器来做扫描比较直观和简单。你“按一下”所以应该保存当前的状态以供下次比较使用,需要检测沿。另外还需要简单的消抖,否则你按一下就不知道跑哪个继电器了。可以直接用一个寄存器初始状态为01H,每按一次左移一位后保存(以记录到哪一位了),同时当前值结合P3.4的状态,和00H或0FFH相与后输出到P2口就可以了。程序没个标准写法,只要动作可靠就行,编译后没谁能看出你写得不流畅啥的

使用特权

评论回复
地板
yrezer|  楼主 | 2008-6-28 11:01 | 只看该作者

用定时器扫描是不是整个程序都要重新写呢

还有我用那种可以锁死的按键,还用消抖吗

使用特权

评论回复
5
fiann| | 2008-6-28 13:38 | 只看该作者

同意用定时器扫描

使用特权

评论回复
6
电子灵| | 2008-6-29 01:11 | 只看该作者

这个程序还用定时器和中断?

1:按键操作必须有消抖,每次按键跳一位,可以增加一段检测按键释放的功能。就三四行程序而已。
2:不需要用定时器和中断了,你是51系列的,内部是有弱上拉的,可以直接接按键开关,如果没有拉低的话,内部会上拉到高电平,可以直接用位跳转程序。
3:每次按键,跳一位继存器,顺序的,所以,设一个移位寄存器,初始值为01,每一次按键左移一位或右移一位,移位后的数据刚好对应你的继存器。
4:应该是你的确认键了吧。当然如果检测到这个按键,就用你的移位寄存器异或输出口,就可以改变的相应的继存器的工作状态,也只有几行程序而已。
几点意见,仅供参考。
          本人用51的时候已经是四五年前的事,现在用精简子令的单片机多。依记得一些指令,故随便写一下,指令符号可能会有错误,但是整个流程可以表达出程序的流程。
start:
          call   scankey     ;键扫描子程序
          mov    a,keyname
          cjne   a,#1,next   ;是否是按键1?不是跳转到next处
          call   delay20ms   ;20MS时间消抖
          call   scankey     ;再扫描
          mov    a,keyname
          cjne   a,#1,next   ;还是按键1吗,不是就跳转到next处,键错误.
          clr    c           ;确认是按键1,寄存器r0左移一位,c=1?
          rl     r0
          jbs    c,return    ;如果C=1,那么最高位r0.7已经被移出
          mov    a,#1        ;所以R0重付01,相当于8位数据一直在循环。
          mov    r0,a
next:
          mov    a,keyname
          cjne   a,#2,return
          call   delay20ms
          call   scankey
          mov    a,keyname
          cjne   a,#2,return    ;确认是按键2(确认键)
          mov    a,r0           ;把循环的值送到P2端口,因为八位中,只
          (xor   p2,a)
          mov    p2,a           ;有一位数据是高,其他七位是低,所以可
return:                         ;以电路设计成,高开继电器,低关继电器
          call   delay50MS      ;如果要对当前哪位取反的话,就用异或指
          jmp    start          ;令。
delay20ms:
          nop ...
          ret
scankey:
          mov   a,p3
          rl    a
          rl    a
          and   a,#03
          mov   keyname,a
          ret
如果需要检测按键可以释放的话,就要增加一个寄存器存按键的前一个状态,如果在按键全部释放时才清零,当有键时,就对比一下,相同就返回不执行。



   



使用特权

评论回复
7
5880527| | 2008-6-29 10:20 | 只看该作者

个人感觉6楼的程序写在书本上很容易懂,但不太实用

关键是键盘部分有些值得商榷,当然就象我在3楼说的那样,程序没个标准模式,也不象学校里考试有标准答案,只要可靠实现了所需功能就可以

使用特权

评论回复
8
ningling| | 2008-6-29 11:13 | 只看该作者

只要程序有功能

只要程序有功能,没问题就不用追究了。

使用特权

评论回复
9
aihe| | 2008-6-29 22:09 | 只看该作者

P2.0-P2.7分别接8个继电器?

能行吗?

使用特权

评论回复
10
gyt| | 2008-6-30 12:44 | 只看该作者

当然行

使用特权

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

本版积分规则

3

主题

7

帖子

0

粉丝