《匠人手记》推荐网上购书渠道:
互动出版网(china-pub)购书入口   >>>
当当网(dangdang)购书入口   >>>
卓越亚马逊网 购书入口   >>>
淘宝网(taobao)购书入口   >>>
更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

 匠人观点: 好记性不如烂笔头  
 黑色幽默:三鹿门——后世畅想

96个key的零延时采集
程序匠人 发表于 2005-11-10 20:30:00  阅读全文 | 回复(0) | 引用通告 | 编辑

96个key的零延时采集
 
 
HotPower 发表于 2003-11-5 18:04 侃单片机 ←返回版面   

;-------96键演示程序-------------------------
;这是1个回复题中的应用示例,已通过软仿真“验证”
;这只是键扫描技术的1个“缩影”,方法实在太多.
;有“难看之处”,敬请高手们批评指教.
;HotPower将虚心接受,坚决改正.重新做人.
;发表目的: 在21IC中壮大游击队.
;----------------------------------------------------
;由于2051资源问题,本程序只取多任务键盘的压放键2个事件
;废除长压键(压键1段时间后才激活)事件
;废除长放键(放键1段时间后才激活)事件
;废除双击键事件
;废除任意组合键事件
;----------常数定义------------------------------
TIME208US  EQU -208;20mS/96=208uS
TIME50MS   EQU -5000;50000uS
;KEYCOUNT   EQU   1;键盘键个数(软仿真时用)
;------------------------------------------------
KEYCOUNT   EQU   96;键盘键个数(实际应用)


;----------RAM地址定义----------------------------
;--------96键键状态标志位数组Bits[12*8位]--------
KEYBUFF1   DATA  08H;08H~13H(12个字节96位)对应96键
;--------96键键跳变标志位数组Bits[12*8位]--------
KEYBUFF2   DATA  14H;14H~1FH(12个字节96位)对应96键
;------------------------------------------------
KEYNUM     DATA  30H;
HotPower_55H      DATA   6EH
HotPower_AAH      DATA   6FH
;---------------------------------------
SP_MIN       DATA HotPower_AAH
;-------主程序开始----------------------
    ORG   0000H
START:
    LJMP  MAINSTART;主程序开始
    ORG   0003H
;-------掉电保护中断INT0服务程序--------
INT0_INTADDR:
    RETI
    ORG   000BH
;-------定时器T0中断服务程序------------
;工作在8位自动装载方式,每208uS中断一次
T0_INTADDR:
    LJMP  T0INTPROC;定时器T0中断服务程序
    RETI
    ORG   0013H
;-------外部中断INT1服务程序------------
INT1_INTADDR:
    RETI
    ORG   001BH
;-------定时器T1中断服务程序------------
T1_INTADDR:
    LJMP  T1INTPROC;定时器T1中断服务程序
    RETI
;    ORG   0023H
;-------串行中断服务程序----------------
;SINT_INTADDR:
;    RETI
;-------------------------------------------
;    ORG   002BH
;-------定时器T2中断服务程序------------
;    LJMP  T2INTPROC;执行中断服务程序
;    RETI
;-------执行键盘命令----------------------
;本程序利用散转回收技术(指针函数)
;它的最大优点是散转处的子程序可被它用(函数)
;它比JMP @A+DPTR指令要“游击”很多,灵活和隐蔽了许多
;它在对付“反汇编”方面,比JMP @A+DPTR更“坏”
;HotPower打死也不用JMP @A+DPTR
KEYPROC:
;入口:  DPTR散转地址表
;       ACC 散转号
    CJNE  A,#KEYCOUNT,$+3
    JNC   KEYPROC_EXIT;非法键(96~255)防止程序飞,不散转
    RL    A;*2;地址需要2字节(像ARM的大端模式)
    ADD   A,DPL
    MOV   DPL,A
    CLR   A
    ADDC  A,DPH
    MOV   DPH,A
    MOV   A,#01H;低8位
    MOVC  A,@A+DPTR;取低8位地址
        PUSH  ACC;压入事件处理低8位地址
        CLR   A;高8位
    MOVC  A,@A+DPTR;取高8位地址
        PUSH  ACC;压入事件处理高8位地址
KEYPROC_EXIT:
    RET;执行键盘命令(散转JMP @A+DPTR)
;-------压键事件处理地址表--------------------
KEYJMPPROCTAB:
    DW    KEYPROC0;0键压键
    DW    KEYPROC1
    DW    KEYPROC2
;............................
    DW    KEYPROC95;95键压键
;-------放键事件处理地址表--------------------
KEYJMPPROCTABX:
    DW    KEYPROC0X;0键放键
    DW    KEYPROC1X
    DW    KEYPROC2X
;............................
    DW    KEYPROC95X;95键放键
MAINSTART:
;-------P0口初始化------------------
    MOV   P0,#11111111B
;-------P1口初始化------------------
    MOV   P1,#11111111B
;-------P2口初始化------------------
    MOV   P2,#11111111B
;-------P3口初始化------------------
    MOV   P3,#11111111B
;--------------------------------
    MOV   IE,#00000000B;EA=0,ES=ET2=ET1=EX1=ET0=EX0=0
    MOV   SP,#SP_MIN;
          MOV   PSW,#00000000B;RS1RS0=00,R0~R7=00H~07H
    MOV   A,#LOW(MAINNEXT)
    PUSH  ACC
    MOV   A,#HIGH(MAINNEXT)
    PUSH  ACC
    RETI
MAINPROC:
    LCALL MAININIT;系统初始化
        MOV   IE,#10001010B;开中断
;-------主循环-------------------------------
MAINLOOP:
    ORL   PCON,#10001101B;待机
    SJMP  MAINLOOP;死循环
MAINNEXT:
    MOV   A,#LOW(MAINPROC)
    PUSH  ACC
    MOV   A,#HIGH(MAINPROC)
    PUSH  ACC
    RETI
;-------主程序初始化------------------------
MAININIT:
;-------接口初始化--------------------------
;-------内存初始化-------------------------
    MOV   A,HotPower_55H
    XRL   A,HotPower_AAH
    CPL   A
    JZ    MAININITNEXT;内存未破坏
    MOV   HotPower_55H,#055H
    MOV   HotPower_AAH,#0AAH
    LCALL SYSTEMINIT;系统初始化
MAININITNEXT:
;-------运行初始化---------------
    LCALL SYSTEMSETUP;系统设置
    RET
SYSTEMINIT:
    LCALL KEYBUFFINIT
    RET
SYSTEMSETUP:
;-------系统主频12MHz---------------------------------
;    MOV   IP,#00100001B;中断优先级EX0>ET2>ET0>EX1>ES
     MOV   TMOD,#00010010B;T1=MODE1(16位定时器),T0=MODE2(8位定时器)
    MOV   TCON,#01010101B;启动定时器TR1EQUTR0EQU1,IT1EQUIT0EQU1
;------------------------------------------------------
    MOV   TL0,#TIME208US;设置定时器0时间常数
    MOV   TH0,#TIME208US;设置定时器0时间常数
;------------------------------------------------------
;    MOV   TL1,#LOW(TIMEXMS);设置定时器1时间常数
;    MOV   TH1,#HIGH(TIMEXMS)
;-------
KEYBUFFINIT:
    MOV   KEYNUM,#00H
    MOV   R0,#KEYBUFF1
KEYBUFFINITLOOP:
    MOV   @R0,#00H
    INC   R0
    CJNE  R0,#KEYBUFF2+12,KEYBUFFINITLOOP
    RET
;---------------------------------------------
INKEY:
;T0每中断1次,将进行1次键"扫描"
    LCALL TESTKEY;键盘测试(不扫但描)
;-------键盘软仿真测试点-----------------
;在此   A=0 无键压下,A<>0有键压下
;若调试n个键,需将KEYCOUNT设置为n.(KEYCOUNT=1~96)
;----------------------------------------
    JNZ   INKEY1;有键压下
INKEY0:
;-------无键压下------------------------
    LCALL GETKEYBIT;取键状态
    JZ    INKEY01;键状态未发生变化
        LCALL CLRKEYBIT;设置放键标志
    LCALL SETKEYBITK;设置跳变标志(防止放键抖动)
    RET
INKEY01:
    LCALL GETKEYBITK;取键跳变标志
    JZ    INKEY02;键未发生跳变(防止2次事件处理)
    LCALL CLRKEYBITX;设置重入标志
        MOV   A,KEYNUM;取键号
        MOV   DPTR,#KEYJMPPROCTABX;键盘放键事件处理表
    LCALL KEYPROC;执行键盘放键事件处理
INKEY02:
    RET
INKEY1:
;-------有键压下------------------------
    LCALL GETKEYBIT;取键状态
    JNZ   INKEY11;键状态未发生变化(防止2次事件处理)
        LCALL SETKEYBIT;设置压键标志
    LCALL SETKEYBITK;设置跳变标志(防止压键抖动)
    RET
INKEY11:
    LCALL GETKEYBITK;取键跳变标志
    JZ    INKEY12;键未发生跳变
    LCALL CLRKEYBITX;设置重入标志
        MOV   A,KEYNUM;取键号
        MOV   DPTR,#KEYJMPPROCTAB;键盘压键事件处理表
    LCALL KEYPROC;执行键盘压键事件处理
INKEY12:
    RET
GETKEYBITK:
    MOV   A,R0
    ADD   A,#12
    MOV   R0,A
    SJMP  GETKEYBITX
GETKEYBIT:
    LCALL GETKEYBITADDR
    LCALL GETKEYBITVAL
GETKEYBITX:
    MOV   A,@R0
        ANL   A,B
    RET
SETKEYBITK:
    MOV   A,R0
    ADD   A,#12
    MOV   R0,A
    SJMP  SETKEYBITX
SETKEYBIT:
    LCALL GETKEYBITADDR
    LCALL GETKEYBITVAL
SETKEYBITX:
    MOV   A,@R0
        ORL   A,B
    MOV   @R0,A
    RET
CLRKEYBITK:
    MOV   A,R0
    ADD   A,#12
    MOV   R0,A
    SJMP  CLRKEYBITX
CLRKEYBIT:
    LCALL GETKEYBITADDR
    LCALL GETKEYBITVAL
CLRKEYBITX:
    MOV   A,@R0
    XRL   B,#0FFH;取反B
        ANL   A,B
    XRL   B,#0FFH;还原B
    MOV   @R0,A
    RET
;-----------------------------------
;CPLKEYBITK:
;    MOV   A,R0
;    ADD   A,#12
;    MOV   R0,A
;    SJMP  CPLKEYBITX
;CPLKEYBIT:
;    LCALL GETKEYBITADDR
;    LCALL GETKEYBITVAL
;CPLKEYBITX:
;    MOV   A,@R0
;        XRL   A,B
;    MOV   @R0,A
;    RET
;---------------------------------------------
GETKEYBITVAL:
    MOV   A,KEYNUM
    ANL   A,#07H
    ADD   A,#GETKEYBITTAB-GETKEYBITTABOFF
    MOVC  A,@A+PC
GETKEYBITTABOFF:
    MOV   B,A
    RET
GETKEYBITTAB:
    DB    00000001B
    DB    00000010B
    DB    00000100B
    DB    00001000B
    DB    00010000B
    DB    00100000B
    DB    01000000B
    DB    10000000B
    RET
;----------------------------------------------
GETKEYBITADDR:
    MOV   A,KEYNUM
    ANL   A,#01111000B
    RR    A
    RR    A
    RR    A
    ADD   A,#KEYBUFF1
    MOV   R0,A
    RET
;-------键测试子程序--------------------------
TESTKEY:
;键号KEYNUM=000 0000B~101 1111B(0~95)
;入口   无
;出口   ACC==0 无键压下(键号KEYNUM)
;       ACC<>0 有键压下(键号KEYNUM)
    MOV   A,KEYNUM;取键号
    ANL   A,#0FH;取行号(键号低4位)
    ANL   P3,#0F0H;清行信号
    ORL   P3,A;发送行扫描信号DCBA;P3.3~P3.0
    MOV   A,KEYNUM;取键号
    ANL   A,#01110000B;取列号(键号高3位)
    SWAP  A;变换到低3位
    ADD   A,#TESTKEYTAB-TESTKEYTABOFF;得到表地址
        MOVC  A,@A+PC;取列表值
TESTKEYTABOFF:
    JZ    TESTKEYEXIT;6,7非法列,认为无键压下
    PUSH  B;保护现场
    MOV   B,A;暂存
    ANL   A,P1;接收列值P1.7~P1.2,有键压下为0
    XRL   A,B;有键压下非0
    POP   B;恢复现场
TESTKEYEXIT:
    RET
TESTKEYTAB:
    DB    00000100B;0列
    DB    00001000B;1列
    DB    00010000B;2列
    DB    00100000B;3列
    DB    01000000B;4列
    DB    10000000B;5列
    DB    00000000B;6列非法
    DB    00000000B;7列非法
;-------定时器T0中断服务程序--------------------
;每个键20mS扫描1次,并自动进行压键或放键消抖处理
;这是1个大规模(96键)的键盘游击战的非典战例
;特点:
;1.不需键扫描.(T0中断的次序即为键扫描号)
;2.不需键消抖.(在T0中断96次后自动消抖)
;3.压键放键事件分离(散转回收技术)
;4.用户事件"并行处理"(mS级分时)
T0INTPROC:
    PUSH  PSW
    PUSH  ACC
    PUSH  B
    PUSH  DPL
    PUSH  DPH
T0INTPROC_START:
    LCALL INKEY;键扫描并执行压放键事件处理
    INC   KEYNUM;准备下一键号(T0中断计数)
    MOV   A,KEYNUM
    CJNE  A,#KEYCOUNT,T0INTPROC_EXIT
    MOV   KEYNUM,#00H;开始下1轮键扫描
T0INTPROC_EXIT:
    POP   DPH
    POP   DPL
    POP   B
    POP   ACC
    POP   PSW
    RETI
;-------定时器T1中断服务程序------------
T1INTPROC:
    RETI
;-------0键压键事件处理---------------------
KEYPROC0:
;在此添加用户压键事件
    RET
;-------1键压键事件处理---------------------
KEYPROC1:
;在此添加用户压键事件
    RET
;-------2键压键事件处理---------------------
KEYPROC2:
;在此添加用户压键事件
    RET
;-------95键压键事件处理---------------------
KEYPROC95:
;在此添加用户压键事件
    RET
;-------0键放键事件处理---------------------
KEYPROC0X:
;在此添加用户放键事件
    RET
;-------1键放键事件处理---------------------
KEYPROC1X:
;在此添加用户放键事件
    RET
;-------2键放键事件处理---------------------
KEYPROC2X:
;在此添加用户放键事件
    RET
;-------95键放键事件处理---------------------
KEYPROC95X:
;在此添加用户放键事件
    RET
;-------全部程序结束--------------------------------------
    END
 
 
 

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    往日酷贴

     
     
     

    大千八卦

    友情连接

    新浪新闻:
    新浪财经:
    AK58新闻:
    新浪股票:
    新浪股票:
    证券之星:

     [更多酷站连接]

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [柔月阁]

    [八楼的呼吸]

    [hotpower 的水潭]

    [xwj的文君阁]

    [所长的BLOG]

    [阿摆手记]

    [电子伙伴]

    [unaided的笔记]

    [小飞的笔记]

    [单片机开发联盟]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [数字电视之家]

    [SMARTCODE电子书斋]

    [软件开发之窗]

    [Armoric]

    [我爱研发网]

    [infernal的笔记]

    [雄鹰的空中加油站]

    [SunK]

    [逍遥电子]

    [ningpanda的博客]

    [C-Design]

    [一网见天下]

    [海边淘沙]

    [嵌入式365]

    [水牛的仓库]

    [股剩是怎样炼成的]

    [PIC论坛]

    [ICC AVR开发网]

    [中国高校自动化网]

     

     

     

    MCU博客-中国电子工程师博客网 

    大学生电子网 

     

     

     

     

     

    !!! 《匠人的百宝箱》 !!!