📄 adkey.asm
字号:
#include <P16F877A.inc> ;
KEYRES EQU 0X20 ;键值的ASCII码
ADKEYH EQU 0X21 ;模拟键盘输入A/D转换结果的高8位
KEYRES_B EQU 0X22 ;键值转存
countline EQU 0X23 ;延时计数器
LED_DATA EQU 0X24 ;要显示的数值
CLKCOUNT EQU 0X25 ;脉冲记数器
#DEFINE SRCLK PORTC,3; SPI CLK
#DEFINE RCLK PORTC,4; 完成脉冲线
#DEFINE SER PORTC,5; SPI SDO
;因程序在2K范围内,goto ,call指令不考虑对PCLATH的处理,查表例外。
org 0x00
nop
goto adkey_1
org 0X10 ;读取键值判断测试程序入口
adkey_1
call InitADKEY;
CALL PRELED;
movlw 0xff
movwf countline;
adkey_2
call GetADKEY
movlw 0x30
xorwf KEYRES,W
btfss STATUS,Z
GOTO adkey_3 ;键值不为30(有键),去抖动
goto adkey_2
adkey_3
decfsz countline,F;延时去抖动
goto adkey_3
movf KEYRES,W
movwf KEYRES_B ;转移键值
adkey_4
call GetADKEY ;
movlw 0x30
xorwf KEYRES,W
btfss STATUS,Z
goto adkey_4 ;键未释放,键值与前一次读入一致,继续AD,
movf KEYRES_B,W ;键已释放,键值为0x30
MOVWF LED_DATA;insert some display,USE PORTC;
CALL MONILED;
movlw 0xff
movwf countline
GOTO adkey_2
InitADKEY ;A/D 转换初始化子程序
CLRF PIR1;
MOVLW 0X41;
MOVWF ADCON0; ENABLE AD,AN0,LEFT MODE,VDD,AD 转换时钟为 FOSC/8
BSF STATUS,RP0;
CLRF INTCON; 采用查询法,不需要中断
CLRF PIE1;
BSF TRISA,0;
MOVLW 0X0e; 右移位模式,高8位存在ADRESH,only RA0 analog port,VDD,VSS
MOVWF ADCON1;
RETURN
;************************************
GetADKEY ;读取键值处理子程序
BSF ADCON0,GO ;启动AD转换
BTFSC ADCON0,GO ;等待A/D转换结束
GOTO $-1
MOVF ADRESH,W ;读取并存储A/D 转换结果
MOVWF ADKEYH ;判断键值1~9,若无键按下,认为键值为0
MOVLW 0X31 ;
MOVWF KEYRES
KEY1 MOVLW 0XCB ;CC为S1按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W ;比较阈值设为CB可增强抗干扰能力
BTFSS STATUS,C ;采用逐键比较判断
GOTO KEY2
GOTO KEYOUT
KEY2 INCF KEYRES,F
MOVLW 0XA8 ;A9为S2按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY3
GOTO KEYOUT
KEY3 INCF KEYRES,F
MOVLW 0X8F ;90为S3按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY4
GOTO KEYOUT
KEY4 INCF KEYRES,F
MOVLW 0X7D ;7E为S4按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY5
GOTO KEYOUT
KEY5 INCF KEYRES,F
MOVLW 0X6F ;70为S5按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY6
GOTO KEYOUT
KEY6 INCF KEYRES,F
MOVLW 0X63 ;64为S6按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY7
GOTO KEYOUT
KEY7 INCF KEYRES,F
MOVLW 0X5A ;5B为S7按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY8
GOTO KEYOUT
KEY8 INCF KEYRES,F
MOVLW 0X53 ;54为S8按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY9
GOTO KEYOUT
KEY9 INCF KEYRES,F
MOVLW 0X4C ;4D为S9按下对应A/D转换数字量的高8位
SUBWF ADKEYH,W
BTFSS STATUS,C
GOTO KEY0
GOTO KEYOUT
KEY0 MOVLW 0x30 ;无键按下,返回30作为主函数判断有无键按下的设定值
MOVWF KEYRES ;也可以设定其他不与键值冲突的数值
KEYOUT
RETURN
PRELED
CLRF PORTC;
MOVLW 0X8
MOVWF CLKCOUNT;
BSF STATUS,RP0;
CLRF TRISC; MAKE RC3,RC4,RC5 OUTPUT
BCF STATUS,RP0;
RETURN
MONILED; 入口参数LED_DATA,为0-9ASCALL码
;芯片全部在时钟上升沿完成动作,故需在低电平期间完成数据的变化。
MOVLW HIGH LED_TABLE
MOVWF PCLATH;
MOVLW 0X0F;
ANDWF LED_DATA,F;得到0-9;
MOVF LED_DATA,W;
CALL LED_TABLE;
MOVWF LED_DATA; 得到0-9对应的LED段码;该码表与SPI主模式下码表一致,故模拟时,高位 ; 先送出,芯片最高工作频率30M故不需要特别的延时
MOVLW HIGH MONILED
MOVWF PCLATH; 切换PC高位
BCF RCLK;
GOGOGO
BCF SRCLK;
RLF LED_DATA,F;
BTFSC STATUS,C;
GOTO SETSER;
GOTO CLRSER;
SETSER
BSF SER;
GOTO SETSRCLK;
CLRSER
BCF SER;
SETSRCLK
NOP
NOP
BSF SRCLK
NOP
DECFSZ CLKCOUNT,F;
GOTO GOGOGO;
BCF RCLK;干扰太厉害,必须在这清0,然后制造上升沿
NOP
NOP
BSF RCLK;
MOVLW 0X8;
MOVWF CLKCOUNT;
RETURN
LED_TABLE ;七段码调整 如果表出现PCL溢出,要调整表的位置
ADDWF PCL,F
DT 0X00,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -