打印

这样设置扫描按键对吗?

[复制链接]
3552|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mugangzhu|  楼主 | 2009-12-22 16:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
;*******************************
;系统寄存器
;********************************
IE  EQU 00H
IRQ EQU 01H
TM0 EQU 02H
T0L EQU 04H
T0H EQU 05H
PORTA EQU 08H
PORTB EQU 09H
PORTC EQU 0AH;输出口
PORTD EQU 0BH;输入口
TBR   EQU 0EH
INX   EQU 0FH
DPL   EQU 10H
DPM   EQU 11H
DPH   EQU 12H
PDCR  EQU 1BH
PCCR  EQU 1AH
T0    EQU 1EH
WDT   EQU 1FH
;**************
;用户定义寄存器
;**************
AC_BACK EQU 30H
TEMP    EQU 31H
CT1     EQU 32H;
CT0     EQU 33H;延时用寄存器
KEY_ST  EQU 34H;键状态
T0M_CT  EQU 35H;计时用3s
T0M_CT_1 EQU 36H
T0M_CT_2 EQU 37H
T0M_1    EQU 38H;bit0=1关闭输出=0开启输出
YS_1     EQU 39H
YS_2     EQU 3AH
YS_3     EQU 3BH
TEMP5    EQU 3CH
FLAGE5   EQU 3DH;位0=1,5m时间到,位1=1
KEY_OLD  EQU 3EH
KEY_NEW  EQU 3FH
T5MS_CT1 EQU 40H
T5MS_CT2 EQU 41H
TMP_T0   EQU 42H
F_TIMER  EQU 43H
;***************
;程序
;****************
               ORG       0000H
               JMP       REST               
               RTNI               
               JMP       TIMER0_ISP               
               RTNI               
               RTNI                        
;****************************
;延时3S TM0中断服务子程序
;****************************
TIMER0_ISP:
              STA AC_BACK,00H
              ANDIM IRQ,1011B              
              SBIM T5MS_CT1,01H
              LDI TMP_T0,00H
              SBCM T5MS_CT2,00H
              OR T5MS_CT1,00H
              BNZ TIMER0_END ;没到5ms, 跳转
              LDI F_TIMER,0001B ;设置“5ms 到”标志
              LDI T5MS_CT2,01H ;重置5ms 计数器
              LDI T5MS_CT1,04H                           
TIMER0_END:   
              LDI IE,0100B                        
              LDA AC_BACK,00H
              RTNI                                                   
;****************
;上电初始化
;*****************
REST:
               NOP
               NOP            
               LDI  DPL,00H
               LDI  DPM,03H
               LDI  DPH,00H               
POWER_RESET_1:
               LDI  INX,00H
               ADIM DPL,01H
               LDI  TEMP,00H
               ADCM DPM,00H
               BA3  POWER_RESET_2
               JMP  POWER_RESET_3
POWER_RESET_2:
               ADIM DPH,01H
POWER_RESET_3:
               SBI  DPH,01H
               BNZ  POWER_RESET_1
               SBI  DPM,04H
               BNZ  POWER_RESET_1              
               CALL XTJCQ_IST              ;初始化系统寄存器
XTJCQ_IST:
               LDI  PORTD,00H
               LDI  PDCR,00H;输入口
               LDI  PORTC,00H
               LDI  PCCR,0FH;输出口                                            
               LDI  T0,00H;选择外部时钟
               LDI  T0L,06H
               LDI  T0H,00H
               LDI  TM0,07H;               
               LDI  PORTD,0FH;使用低电平按键有效
               LDI  T5MS_CT2,01H
               LDI  T5MS_CT1,04H;            
               LDI IE,0100B
               
                                       
;主程序
MAIN:                              
               ADI F_TIMER,0001B
               BA0 HALTMODE ;未到5ms, 跳转
               ANDIM F_TIMER,1110B ;清"5ms 到"标志
               NOP                           
               LDA PORTD,00H
               STA TEMP,00H
               SBI TEMP,0FH;=0,没有按键动作跳走
               BAZ YS_4                                             
               ADIM TEMP5,01H
               SBI TEMP5,01H;是否是第一次按键按下是的话存起来初次按键值
               BAZ YS_5
               LDA KEY_OLD,00H
               SUB TEMP,00H
               BNZ YS_4
               SBI TEMP5,08H;扫描8次按键未完成继续扫描
               BNZ MAIN
               LDA TEMP,00H
               STA YS_2,00H
               LDI YS_1,01H
               
HALTMODE:
                NOP
                HALT
                NOP
                NOP
                JMP MAIN
YS_4:
               ANDIM F_TIMER,1110B
               LDI TEMP5,00H
               JMP MAIN               
YS_5:
               LDA TEMP,00H
               STA KEY_OLD,00H
               RTNI                                                   
              END
沙发
warm_ice| | 2009-12-23 10:16 | 只看该作者
原则你都清楚了,只要按原则实现就可以了.
你可以这样测试一下,在每次读键的时候,对另一个没有用到的I/O口输出电平进行取反,然后在外边用示波器测试即可.

使用特权

评论回复
板凳
mugangzhu|  楼主 | 2009-12-23 10:46 | 只看该作者
呵呵,我试了基本没有什么问题,调试一下就好了,人眼能够分辨的最短时间是多少?

使用特权

评论回复
地板
mugangzhu|  楼主 | 2009-12-23 10:52 | 只看该作者
还有就是同一个程序中我想用到两个定时器TIMER0和TIMER1,这样在中断服务程序中设置应注意哪些地方?芯片不用的管脚应该怎么处理?

使用特权

评论回复
5
warm_ice| | 2009-12-23 11:24 | 只看该作者
1.一般人眼能够分辨的最短时间为0.1秒.
2.用两个定时器的话,入口地址要写好,打开中断和关闭中断时以及清除IRQ时注意不要影响到另一个中断.
3.不用的管脚只要不悬空(输入不开上下拉)都可以,具体设置根据实际情况处理.

使用特权

评论回复
6
mugangzhu|  楼主 | 2009-12-23 11:37 | 只看该作者
我用两个定时器中断,为什么同时打开中断LDI IE,0110B时,就不工作了呢?

使用特权

评论回复
7
warm_ice| | 2009-12-23 11:54 | 只看该作者
我用两个定时器中断,为什么同时打开中断LDI IE,0110B时,就不工作了呢?
mugangzhu 发表于 2009-12-23 11:37

中断入口地址写了没有?
中断服务程序写了没有?
中断服务程序中是否有重置IE?
中断服务程序中是否有错误的清除IRQ?
.....

有了问题,要先自己多想想,自己如果能找到问题点,印象会更深,进步更快.

使用特权

评论回复
8
mugangzhu|  楼主 | 2009-12-23 12:04 | 只看该作者
本帖最后由 mugangzhu 于 2009-12-23 13:25 编辑

LIST P=69P42
ROMSIZE=3072
;*******************************
;系统寄存器
;********************************
IE  EQU 00H
IRQ EQU 01H
TM0 EQU 02H
TM1 EQU 03H
T0L EQU 04H
T0H EQU 05H
T1L EQU 06H
T1H EQU 07H
PORTA EQU 08H
PORTB EQU 09H
PORTC EQU 0AH;输出口
PORTD EQU 0BH;输入口
TBR   EQU 0EH
INX   EQU 0FH
DPL   EQU 10H
DPM   EQU 11H
DPH   EQU 12H
PDCR  EQU 1BH
PCCR  EQU 1AH
T0    EQU 1EH
WDT   EQU 1FH
;**************
;用户定义寄存器
;**************
AC_BACK EQU 30H
TEMP    EQU 31H
CT1     EQU 32H;
CT0     EQU 33H;延时用寄存器
KEY_ST  EQU 34H;键状态
T0M_CT  EQU 35H;计时用3s
T0M_CT_1 EQU 36H
T0M_CT_2 EQU 37H
T0M_1    EQU 38H;bit0=1关闭输出=0开启输出
YS_1     EQU 39H
YS_2     EQU 3AH
YS_3     EQU 3BH
TEMP5    EQU 3CH
FLAGE5   EQU 3DH
KEY_OLD  EQU 3EH
DELAY1   EQU 3FH;TIMER1延时用
T5MS_CT1 EQU 40H
T5MS_CT2 EQU 41H
TMP_T0   EQU 42H
F_TIMER  EQU 43H;位0=1 TIMER0延时5ms时间到,位1=1 TIMER1延时时间到
AC1_BACK EQU 44H
;***************
;程序
;****************
               ORG       0000H
               JMP       REST               
               RTNI               
               JMP       TIMER0_ISP               
               JMP       TIMER1_ISP               
               RTNI                        
;****************************
;延时5mS TM0中断服务子程序
;****************************
TIMER0_ISP:
              STA AC_BACK,00H
              ANDIM IRQ,1011B              
              SBIM T5MS_CT1,01H
              LDI TMP_T0,00H
              SBCM T5MS_CT2,00H
              OR T5MS_CT1,00H
              BNZ TIMER0_END ;没到5ms, 跳转
              ORIM F_TIMER,0001B ;设置“5ms 到”标志
              LDI T5MS_CT2,01H ;重置5ms 计数器
              LDI T5MS_CT1,04H                           
TIMER0_END:   
              ORIM IE,0100B                        
              LDA AC_BACK,00H
              RTNI
;****************************
;延时3S TM1中断服务子程序
;****************************
TIMER1_ISP:
              STA AC1_BACK,00H
              ANDIM IRQ,1101B              
              ADIM DELAY1,01H
              SBI  DELAY1,06H
              BNZ  TIMER1_END
              ORIM F_TIMER,0010B                           
TIMER1_END:   
              ORIM IE,0010B                        
              LDA AC1_BACK,00H
              RTNI                                                                  
;****************
;上电初始化
;*****************
REST:
               NOP
               NOP            
               LDI  DPL,00H
               LDI  DPM,03H
               LDI  DPH,00H               
POWER_RESET_1:
               LDI  INX,00H
               ADIM DPL,01H
               LDI  TEMP,00H
               ADCM DPM,00H
               BA3  POWER_RESET_2
               JMP  POWER_RESET_3
POWER_RESET_2:
               ADIM DPH,01H
POWER_RESET_3:
               SBI  DPH,01H
               BNZ  POWER_RESET_1
               SBI  DPM,04H
               BNZ  POWER_RESET_1              
               CALL XTJCQ_IST              ;初始化系统寄存器
XTJCQ_IST:
               LDI  PORTD,00H
               LDI  PDCR,00H;输入口
               LDI  PORTC,00H
               LDI  PCCR,0FH;输出口
               LDI  PORTD,0FH;使用低电平按键有效                                          
               LDI  T0,00H;选择外部时钟
               LDI  T0L,06H;timer0设置
               LDI  T0H,00H
               LDI  TM0,07H; 1分频比
               LDI  T1L,00H;timer1设置
               LDI  T1H,00H
               LDI  TM1,00H;2048分频                             
               LDI  T5MS_CT2,01H
               LDI  T5MS_CT1,04H;延时5ms                           
               ORIM IE,0110B ;打开timer0、timer1中断                                                     
;主程序
MAIN:                              
               ADI F_TIMER,0001B
               BA0 HALTMODE ;未到5ms, 跳转
               ANDIM F_TIMER,1110B ;清"5ms 到"标志            
               NOP                           
               LDA PORTD,00H
               STA TEMP,00H
               SBI TEMP,0FH;=0,没有按键动作跳走
               BAZ YS_4                                             
               ADIM TEMP5,01H
               SBI TEMP5,01H;是否是第一次按键按下是的话存起来初次按键值
               BAZ YS_5
               LDA KEY_OLD,00H
               SUB TEMP,00H
               BNZ YS_4
               SBI TEMP5,05H;扫描8次按键未完成继续扫描
               BNZ MAIN
               LDA KEY_OLD,00H
               STA PORTC,00H                              
               JMP MAIN
               
                             
HALTMODE:
                NOP
                HALT
                NOP
                NOP
                JMP MAIN
YS_4:
               ANDIM F_TIMER,1110B
               LDI TEMP5,00H
               JMP MAIN               
YS_5:
               LDA TEMP,00H
               STA KEY_OLD,00H
               RTNI                                                   
              END

使用特权

评论回复
9
warm_ice| | 2009-12-23 13:28 | 只看该作者
产生中断后IE会被硬件清零,您的程序中每个中断在恢复IE时,只找开了自己的IE位,这样,别外的中断就被关闭了.

使用特权

评论回复
10
mugangzhu|  楼主 | 2009-12-23 13:33 | 只看该作者
只找开了自己的IE位,这样,别外的中断就被关闭了?????

使用特权

评论回复
11
warm_ice| | 2009-12-23 13:35 | 只看该作者
是"只打开"

使用特权

评论回复
12
mugangzhu|  楼主 | 2009-12-23 13:36 | 只看该作者
没有啊,我用的ORIM 指令啊,不是ANDIM指令啊,

使用特权

评论回复
13
warm_ice| | 2009-12-23 13:54 | 只看该作者
看来你对指令还不熟悉啊.
ORIM指令是将相应位置1,你在TIMER0中断退出时用"ORIM IE,0100B ",这样只打开了TIMER0中断,而IE在产生中断时被硬件清零,则此时TIMER1中断就被关闭了,IE值为0100B.

明白了?

使用特权

评论回复
14
mugangzhu|  楼主 | 2009-12-23 14:00 | 只看该作者
ORIM不是或指令吗?就和数字电路中的或门一样啊,与0相或并不影响他的值啊,教程中也是说这个是或指令啊???

使用特权

评论回复
15
zw20045| | 2009-12-23 18:34 | 只看该作者
:)

使用特权

评论回复
16
mugangzhu|  楼主 | 2009-12-24 09:03 | 只看该作者
?????

使用特权

评论回复
17
warm_ice| | 2009-12-24 09:04 | 只看该作者
ORIM不是或指令吗?就和数字电路中的或门一样啊,与0相或并不影响他的值啊,教程中也是说这个是或指令啊???
mugangzhu 发表于 2009-12-23 14:00

关于ORIM指令,你说的没错,但是我一直在强调一句话"中断产生后IE会被硬件清零",你明白了么?
例如:在退出TIMER0中断的时候,在未执行ORIM   IE  0100B时,IE的是值是0,执行过后,IE的值为0100B,这样就只打开了TIMER0中断,而TIMER1中断就被"关闭"了

当然,实际情况是,哪个中断产生及响应,就会将另一个中断关闭.

使用特权

评论回复
18
mugangzhu|  楼主 | 2009-12-24 09:14 | 只看该作者
哦,你的意思是说只要中断产生就会硬件就会强制把IE的四位都清零啊,如果是这样的话就这个程序而言直接用
LDI  IE,0110B指令也可以的?我说怎么回事呢

使用特权

评论回复
19
woshiwml| | 2009-12-24 13:11 | 只看该作者
5# warm_ice 0.1秒放一幅图,你能看成是连续的动画???

使用特权

评论回复
20
warm_ice| | 2009-12-24 13:26 | 只看该作者
5# warm_ice 0.1秒放一幅图,你能看成是连续的动画???
woshiwml 发表于 2009-12-24 13:11

0.1S是通常来讲一般人能看出来的运动和静止的分界限.
就像市电50HZ(20MS),如果换成10HZ(100MS),你肯定就会觉得它在"闪"了.

使用特权

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

本版积分规则

70

主题

358

帖子

1

粉丝