⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 16

📁 CH452程序,带16个按键,LED显示按键值,已调试通过了
💻
字号:
;===CH452显示+按键程序,用CH452两线显示=======
;Modified by Hefanghua.
;MCU:STC89C58. DISPLAY:CH452,4位一体共阴数码管(共8位). USB DOWNLOAD:
;  CH341.  软件:伟福6000, STC-ISP
; 22.1184MHz(正常速度),11.0592MHZ(较慢显示)
;CH452_ADDR为1(默认拉高)
 ;目前已测过的键值(HEX值): 40H~47H ,78H~7FH
;无按键按下时为00H(HEX值)。
LEDA         BIT  P1.2 ;红色LED
LEDB         BIT  P1.3 ;绿色LED

CH452_CMD     DATA   31H
SDA   BIT P2.1 ;定义IIC串行数据线,CH452_SDA数码管显示
SCL   BIT P2.0 ;定义IIC串行时钟线,CH452_SCL数码管显示

STACK         EQU    0FH  ;键盘显示的堆栈区栈顶(向上延伸)
;---------------
LED0          EQU 62H      ;第0位,最右边的个位
LED1          EQU 63H      ;第1位
LED2          EQU 64H      ;第2位
LED3          EQU 65H      ;第3位
LED4          EQU 66H      ;第4位
LED5          EQU 67H      ;第5位
LED6          EQU 68H      ;第6位
LED7          EQU 69H      ;第7位,最高位
KEYBUF        EQU 6AH     ;存一个按键值
ONEBYTEHEX  EQU  6BH
BCDH        EQU  6CH
BCDL        EQU  6DH

ISP_CONTR  EQU  0E7h
ORG 0000H            ;复位后单片机入口
 JMP MAIN           ;进入主程序MAIN

;====================主程序开始===============================
ORG 0100H
MAIN:
 CLR EA         ;关中断
 MOV   SP, #7FH                  ;设置堆栈指针
 mov led7,#8
 mov led6,#8
 mov led5,#8
 mov led4,#8
 mov led3,#8
 mov led2,#8
 mov led1,#8
 mov led0,#8
  LCALL	DELAY1s ;等待CH452完全复位
;----------
; 启动CH452的显示驱动和键盘扫描,2线接口,兼容IIC时序
MOV   CH452_CMD,#04H    ;设置系统参数命令
MOV   A,#03H ;01H            ;禁止看门狗、键盘功能,使能显示驱动,
CALL  CH452_WRITE       ;发出命令
MOV   CH452_CMD,#05H    ;设置显示参数
MOV   A,#80H            ;BCD译码方式,扫描极限为8. #11000000b为扫描极限是4
CALL  CH452_WRITE       ;发出命令

  MOV A,PCON    ;+++++++++++++++
  ANL A,#10H    ;+++++++++++++++
  JZ RUN_ISP     ;判POF是否为1  ;+++++++++++++++
Initiate:           ;POF=1, 是冷启动--上电复位
     ANL PCON,#0EFH        ;将POF清0 ;+++++++++++++++
     ;......       ;初始化
 MOV   A,#0FFH
 MOV   P0,A
 MOV   P1,A             ;清端口状态
 MOV   P2,A
 MOV   P3,A
 CLR   A
 MOV   ONEBYTEHEX,#0FFH

    CALL DISPLAY452
    CALL cleardisplay
     SETB LEDA
     SETB LEDB
    LCALL DELAY1s
     CLR LEDA
     CLR LEDB
    LCALL DELAY1s
     SETB LEDA
     SETB LEDB
    CALL CH452_READ 
    LCALL DELAY1s

AGAIN:
    ;clr leda
     SETB LEDB
    CALL CH452_READ  ;查询式读取按键的值
    MOV KEYBUF,A
    MOV ONEBYTEHEX,A
    call ONEBYTE2BCD ;拆开
    mov led3,BCDH
    mov led2,BCDL
    MOV LED1,#17H   ;H
    CALL DISPLAY452   ;送CH452显示
    ;SETB LEDA
     CLR LEDB
    call KEYSjudge       ;判断按键的值,并执行对应程序
    CALL cleardisplay
    Lcall delay
  JMP AGAIN
RUN_ISP:
;软件实现系统复位到ISP区.POF=0, 是热重启--外部手动复位或看门狗复位
 ORL PCON,#10H        ;将POF置1 ;+++++++++++++++
 MOV ISP_CONTR, #11100000B ;复位并进ISP,#01100000B 只是软复位 ;++++++++++
 CALL DELAY1S                  ;++++++++++
  JMP Initiate                 ;ISP结束后自动恢复运行

;==========================================
;==========主程序结束======================
;==========================================
KEYSjudge:     ;处理KEYBUF中的键值
   CLR EA
   CLR C  ;清进位标志
   MOV A,KEYBUF
   jz endkeyscan    ;未按按键的处理
   SUBB A,#96  ;数据的一半值 20h+40H
   JC smaller96   ;若小于60H,则转

    larger96:   ;≥96
   CLR C        ;必须先清零,否则计算的结果不正确
   MOV A,KEYBUF
   SUBB A,#112  ;数据的一半值
   JC  smaller112

    larger112:  ;≥112
   CLR C
   MOV A,KEYBUF
   SUBB A,#120  ;数据的一半值
   JC smaller120

 larger120:     ;处理120~127
   MOV A,KEYBUF
   SUBB A,#120
   JZ KEYis120  ;120?
   MOV A,KEYBUF
   SUBB A,#121
   JZ KEYis121  ;121?
   MOV A,KEYBUF
   SUBB A,#122
   JZ KEYis122  ;122?
   MOV A,KEYBUF
   SUBB A,#123
   JZ KEYis123  ;123?
   MOV A,KEYBUF
   SUBB A,#124
   JZ KEYis124  ;124?
   MOV A,KEYBUF
   SUBB A,#125
   JZ KEYis125  ;125?
   MOV A,KEYBUF
   SUBB A,#126
   JZ KEYis126  ;126?
   MOV A,KEYBUF
   SUBB A,#127
   JZ KEYis127  ;127?
   jmp errorkey   ;其它为错误
                   ;RET
;中间跳转
smaller112: ljmp smallerthan112
smaller120: ljmp smallerthan120

KEYis120: ljmp KEY120
KEYis121: ljmp KEY121
KEYis122: ljmp KEY122
KEYis123: ljmp KEY123
KEYis124: ljmp KEY124
KEYis125: ljmp KEY125
KEYis126: ljmp KEY126
KEYis127: ljmp KEY127

endkeyscan:
 nop
  ret
;
smaller96:
   CLR C
   MOV A,KEYBUF
   SUBB A,#80  ;数据的一半值
   JNC larger80

    smaller80:
   CLR C
   MOV A,KEYBUF
   SUBB A,#72  ;数据的一半值
   JNC larger72

 smaller72:     ;处理64~71
 CLR C
   MOV A,KEYBUF
   SUBB A,#64
   JZ KEYis64  ;64?
   MOV A,KEYBUF
   SUBB A,#65
   JZ KEYis65  ;65?
   MOV A,KEYBUF
   SUBB A,#66
   JZ KEYis66  ;66?
   MOV A,KEYBUF
   SUBB A,#67
   JZ KEYis67  ;67?
   MOV A,KEYBUF
   SUBB A,#68
   JZ KEYis68  ;68?
   MOV A,KEYBUF
   SUBB A,#69
   JZ KEYis69  ;69?
   MOV A,KEYBUF
   SUBB A,#70
   JZ KEYis70  ;70?
   MOV A,KEYBUF
   SUBB A,#71
   JZ KEYis71  ;71?
   jmp errorkey   ;错误
;
KEYis64: ljmp KEY64
KEYis65: ljmp KEY65
KEYis66: ljmp KEY66
KEYis67: ljmp KEY67
KEYis68: ljmp KEY68
KEYis69: ljmp KEY69
KEYis70: ljmp KEY70
KEYis71: ljmp KEY71
;

    larger80:  ;≥80
   CLR C
   MOV A,KEYBUF
   SUBB A,#88
   JC smaller88
 larger88:     ;处理88~95
   ;......
   jmp errorkey

 smaller88:    ;处理80~87
   ;......
   jmp errorkey

 larger72 :    ;处理72~79
   ;......
   jmp errorkey

    smallerthan112:
   CLR C
   MOV A,KEYBUF
   SUBB A,#104
   JC smaller104

 larger104:    ;处理104~111
   ;......
   jmp errorkey

 smaller104:   ;处理96~103
   ;......
   jmp errorkey

 smallerthan120:   ;处理112~119
   ;......
   jmp errorkey
;

;---------------
KEY64:
 call run_key01
 jmp endkeyscan
KEY65:
 call run_key02
 jmp endkeyscan
KEY66:
 call run_key03
 jmp endkeyscan
KEY67:
 call run_key04
 jmp endkeyscan
KEY68:
 call run_key05
 jmp endkeyscan
KEY69:
 call run_key06
 jmp endkeyscan
KEY70:
 call run_key07
 jmp endkeyscan
KEY71:
 call run_key08
 jmp endkeyscan
;......
;......

KEY120:
 call run_key09
 jmp endkeyscan
KEY121:
 call run_key10
 jmp endkeyscan
KEY122:
 call run_key11
 jmp endkeyscan
KEY123:
 call run_key12
 jmp endkeyscan
KEY124:
 call run_key13
 jmp endkeyscan
KEY125:
 call run_key14
 jmp endkeyscan
KEY126:
 call run_key15
 jmp endkeyscan
KEY127:
 call run_key16
  jmp endkeyscan

RUN_KEY01:
 MOV LED7,#10H
 MOV LED6,#1
 CALL DISPLAY452
  RET
RUN_KEY02:
 MOV LED7,#10H
 MOV LED6,#2
 CALL DISPLAY452
  RET
RUN_KEY03:
 MOV LED7,#10H
 MOV LED6,#3
 CALL DISPLAY452
  RET
RUN_KEY04:
 MOV LED7,#10H
 MOV LED6,#4
 CALL DISPLAY452
  RET
RUN_KEY05:
 MOV LED7,#10H
 MOV LED6,#5
 CALL DISPLAY452
  RET
RUN_KEY06:
 MOV LED7,#10H
 MOV LED6,#6
 CALL DISPLAY452
  RET
RUN_KEY07:
 MOV LED7,#10H
 MOV LED6,#7
 CALL DISPLAY452
  RET
RUN_KEY08:
 MOV LED7,#10H
 MOV LED6,#8
 CALL DISPLAY452
  RET
RUN_KEY09:
 MOV LED7,#10H
 MOV LED6,#9
 CALL DISPLAY452
  RET
RUN_KEY10:
 MOV LED7,#1
 MOV LED6,#0
 CALL DISPLAY452
  RET
RUN_KEY11:
 MOV LED7,#1
 MOV LED6,#1
 CALL DISPLAY452
  RET
RUN_KEY12:
 MOV LED7,#1
 MOV LED6,#2
 CALL DISPLAY452
  RET
RUN_KEY13:
 MOV LED7,#1
 MOV LED6,#3
 CALL DISPLAY452
  RET
RUN_KEY14:
 MOV LED7,#1
 MOV LED6,#4
 CALL DISPLAY452
  RET
RUN_KEY15:
 MOV LED7,#1
 MOV LED6,#5
 CALL DISPLAY452
  RET
RUN_KEY16:
 MOV LED7,#1
 MOV LED6,#6
 CALL DISPLAY452
  RET

errorkey:
 mov ONEBYTEHEX,keybuf
 call ONEBYTE2BCD ;拆开
 mov led5,BCDH
 mov led4,BCDL
 mov led7,#0eh
 MOV LED6,#10H
 mov led3,#10h
 mov led2,#10h
 MOV LED1,#10H
 MOV LED0,#10H
 CALL DISPLAY452   ;送CH452显示
 clr leda
 SETB LEDB
  jmp $  ;停机



;---------------------------------
CH452_I2C_START:  SETB	SDA
		  CLR	SCL	;通知CH452,将要对其操作,此段时间不要再产生按键中断
CH452_I2C_START1: NOP
		NOP			;保留足够的时间给CH452产生中断
		NOP
		JNB	SDA,CH452_I2C_START1 ;CH452正在请求中断?
		NOP
		NOP
		CLR	EX1		;禁止键盘中断,防止开始时被CH452中断而进入中断服务程序中的START
		SETB  SDA
          	SETB  SCL
          	NOP
          	NOP
          	CLR   SDA
          	NOP
          	NOP
          	CLR   SCL     	 ;钳住总线,准备发数据
          RET
;结束总线子程序
CH452_I2C_STOP: CLR    SDA
          	NOP
          	NOP
          	SETB   SCL    		;发送结束条件的时钟信号
          	NOP
          	NOP
          	SETB   SDA    		;结束总线
          	CLR	IE1		;清除中断标志,因为通过SDA输出数据所以会误中断
          	SETB	EX1
          RET
;发送字节子程序
;字节数据放入ACC
CH452_IIC_WR: 	MOV  R7,#08H
CH452_IIC_WR1:	RLC   A              		;取数据位
		MOV   SDA,C
        	SETB  SCL
        	NOP
        	NOP
        	NOP
        	CLR  SCL
		DJNZ  R7,CH452_IIC_WR1
		NOP
		SETB	SDA
		SETB	SCL
		NOP
		NOP
		NOP
		CLR	SCL
        RET
;
;读取字节子程序
;读出的值在ACC
CH452_IIC_RD: 	MOV  R7,#08H
CH452_IIC_RD1: 	SETB  SDA
        	SETB  SCL                ;时钟线为高,接收数据位
        	NOP
        	NOP
        	MOV  C,SDA        	;读取数据位
        	CLR   SCL
        	RLC   A            		 ;进行数据位的处理
        	DJNZ  R7,CH452_IIC_RD1    	 ;未够8位,再来一次
		SETB	SDA
		SETB	SCL
		NOP
		NOP
		NOP
		CLR	SCL
        RET
; 无子地址器件写字节数据
; 入口参数: CH452_CMD命令高字节, ACC命令低字节
CH452_WRITE:  PUSH   ACC
CH452_WRITE1: LCALL  CH452_I2C_START      		;起动总线
	      MOV    A,CH452_CMD
	      RLC    A
	      ANL    A,#3EH
	      ORL    A,#60H		;当ADDR=0时此值为40H,当ADDR=1时此值为60H
	      LCALL  CH452_IIC_WR    	;发送命令高字节
	      POP    ACC       	;写数据
	      LCALL  CH452_IIC_WR
	      LCALL  CH452_I2C_STOP
	RET

; 读取按键值.返回按键值在ACC中:
CH452_READ: LCALL  CH452_I2C_START
	    MOV    A,#6FH ;发送读键盘命令,
;当ADDR=0时此值为4FH,当ADDR=1时此值为6FH
	    LCALL  CH452_IIC_WR ;发送命令高字节
	    LCALL  CH452_IIC_RD ;进行读字节操作
	    LCALL  CH452_I2C_STOP ;结束总线
	RET
;---------------------------------

;-------显示----------------------
display452:
 MOV	CH452_CMD,#0FH
 MOV	A,LED7		;7位显示
 CALL	CH452_WRITE
 MOV	CH452_CMD,#0EH
 MOV	A,LED6		;6位显示
 CALL	CH452_WRITE
 MOV	CH452_CMD,#0DH
 MOV	A,LED5		;5位显示
 CALL	CH452_WRITE
 MOV	CH452_CMD,#0CH
 MOV	A,LED4		;4位显示
 CALL	CH452_WRITE

 MOV  CH452_CMD,#0BH
 MOV  A,led3		;3位显示
 CALL CH452_WRITE
 MOV  CH452_CMD,#0AH
 MOV  A,led2		;2位显示
 CALL CH452_WRITE
 MOV  CH452_CMD,#09H
 MOV  A,led1		;1位显示
 CALL CH452_WRITE
 MOV  CH452_CMD,#08H
 MOV  A,led0		;0位显示
 CALL CH452_WRITE
;CH452支持特殊的BCD码:
;11H    -| -1 或加号
;12H    - 负号减号
;13H    = 等于号
;14H    [ 左方括号
;15H    ] 右方括号
;16H    _ 下划线
;17H    H 字母 H
;18H    L 字母 L
;19H    P 字母 P
;1AH    . 小数点
;1EH    自定义字符
;其余   空格
   ret
cleardisplay:  ;BCD译码模式清屏
 mov led7,#10H  ;7位显示空格
 mov led6,#10H  ;6位显示空格
 mov led5,#10H  ;5位显示空格
 mov led4,#10H  ;4位显示空格
 mov led3,#10H  ;3位显示空格
 mov led2,#10H  ;2位显示空格
 mov led1,#10H  ;1位显示空格
 mov led0,#10H  ;0位显示空格
  ret

ONEBYTE2BCD:
 MOV A,ONEBYTEHEX
 ANL A,#0F0H
 SWAP A
 MOV BCDH,A ;得高4位
 MOV A,ONEBYTEHEX
 ANL A,#0FH
 MOV BCDL,A ;得低4位
   RET
;----------延时子程序-------------
DELAY1S: MOV     R7,#181 ;1秒,22.1184MHz ;#98 ;约1秒,12MHz ,11.0592MHz
LOOP7:   MOV     R6,#100
LOOP6:   NOP
         mov   R5,#49
         DJNZ  R5,$
         DJNZ    R6,LOOP6
         DJNZ    R7,LOOP7
  RET
  
DELAY: MOV     R3,#100 
LOOP2:   MOV     R2,#55
LOOP1:   NOP
         mov   R1,#55
         DJNZ  R1,$
         DJNZ    R2,LOOP1
         DJNZ    R3,LOOP2
  RET
           END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -