📄 ch375451.asm
字号:
; CH375/CH372/CH451 EVT
; U2(AT89C51) Program
;
; Website: http://winchiphead.com
; Email: tech@winchiphead.com
; Author: W.ch 2003.12
;
;****************************************************************************
;
; 应用层定义
CONST_CMD_LEN EQU 07H ; 命令块的长度
; 由于命令与数据都是通过数据下传管道(USB端点2的OUT)下传, 为了防止两者混淆,
; 我们可以在计算机应用程序与单片机程序之间约定, 命令块的长度总是7, 而数据块的长度肯定不是7, 例如64,32等
; 另外, 可以约定, 命令块的首字节是命令码, 等等
DEMO_CH451_CMD EQU 56H ; PC发送命令给CH451
DEMO_TEST_DATA EQU 91H ; 测试命令,将PC机发来的命令包的所有数据取反后返回
DEMO_UP_CLEAR EQU 0A0H ; 连续上传数据块之前进行同步,实际是让单片机清除上传缓冲区的已有内容
DEMO_UP_DATA EQU 0A1H ; 连续上传数据块,指定外部RAM缓冲区起始地址,不限长度
DEMO_DOWN_DATA EQU 0A2H ; 连续下传数据块,指定外部RAM缓冲区起始地址,不限长度
;
STACK EQU 0FH ;堆栈区栈顶(向上延伸)
;
; CH375的命令代码定义
$INCLUDE (..\..\MCU_IF1\MCS51ASM\CH375INC.ASM)
;
; 需要主程序定义的参数
CH375_CMD_PORT EQU 0BDF1H ;CH375命令口的地址,地址译码后自动片选
CH375_DAT_PORT EQU 0BCF0H ;CH375命令口的地址,地址译码后自动片选
;
; 有关CH451的定义
CH451_DCLK BIT P1.7 ;串行数据时钟,上升沿激活
CH451_DIN BIT P1.6 ;串行数据输出,接CH451的数据输入
CH451_LOAD BIT P1.5 ;串行命令加载,上升沿激活
CH451_DOUT BIT P3.3 ;INT1,键盘中断和键值数据输入,接CH451的数据输出
CH451_KEY DATA 28H ;存放键盘中断中读取的键值
LAST_KEY DATA 29H ;保存上次的键值
;
; 有关CH375的定义
CH451_CMD_H DATA 30H ;PC机发给CH451的高4位命令,为0FFH则命令无效
CH451_CMD_L DATA 31H ;PC机发给CH451的低8位命令
BUF_ADDR_L DATA 32H ;保存用于传输的外部RAM或者内部RAM缓冲区的地址,低8位
BUF_ADDR_H DATA 33H ;保存用于传输的外部RAM或者内部RAM缓冲区的地址,高8位
BUF_LEN_L DATA 34H ;当前剩余的要传输的数据长度,低8位
BUF_LEN_H DATA 35H ;当前剩余的要传输的数据长度,高8位
CMD_BUFFER DATA 38H ;命令包缓冲区,本程序约定命令包长度为CONST_CMD_LEN
CMD_BUFFER_NOT DATA 39H ;命令码的反码,用于校验命令包
CMD_BUFFER_ID DATA 3AH ;命令包缓冲区次字节,缓冲区识别码,针对MCS51单片机定义: 1-专用功能寄存器SFR, 2-内部RAM, 3-外部RAM, 不过本程序实际只演示内部RAM
CMD_BUFFER_ADRL DATA 3BH ;命令包缓冲区第3字节,缓冲区地址低8位
CMD_BUFFER_ADRH DATA 3CH ;命令包缓冲区第4字节,缓冲区地址高8位
CMD_BUFFER_LENL DATA 3DH ;命令包缓冲区第5字节,数据总长度低8位
CMD_BUFFER_LENH DATA 3EH ;命令包缓冲区第6字节,数据总长度高8位
; 由于MCS-51单片机存取外部RAM的读写速度低于内部RAM, 并且需要用到DPTR, 所以读写速度较慢, 其程序可以参考本程序修改
;
; 定义位标志
FLAG_INT_WAIT BIT 2FH.2 ;中断等待标志,1指示有中断数据正在CH375中等待发送
;
;
;****************************************************************************
;主程序,用于配合演示CH375和CH451功能
ORG 0000H ;复位后单片机入口
LJMP START
ORG 0003H ;CH375中断
LJMP CH375_INTER
ORG 0013H ;CH451中断,键盘中断后将通知PC机应用层
LJMP CH451_INTER
;
START:
; 以下初始化指令不是必要的,将单片机恢复为默认状态
CLR EA ;关中断
MOV SP,#STACK ;置堆栈初值
MOV A,#0FFH
MOV P0,A
MOV P1,A ;清端口状态
MOV P2,A
MOV P3,A
CLR A
MOV IE,A ;清中断允许控制寄存器
MOV IP,A ;清中断优先级控制寄存器
MOV PSW,A ;清程序状态字
MOV TCON,A ;清定时器/计数器控制寄存器
MOV TMOD,A ;清定时器/计数器工作方式寄存器
MOV PCON,A ;清电源控制寄存器
MOV R7,#0FFH
CALL DELAY_MS ;延时等待CH375初始化完成
; 初始化
CALL CH375_INIT ;初始化
CALL CH451_INIT ;初始化
; .....
; 启动CH451的显示驱动和键盘扫描
MOV B,#04H ;设置系统参数命令
MOV A,#03H ;禁止看门狗,使能键盘功能,使能显示驱动
CALL CH451_WRITE ;发出命令
MOV B,#05H ;设置显示参数
MOV A,#8CH ;BCD译码方式,12级亮度
CALL CH451_WRITE ;发出命令
MOV CH451_KEY,#0FFH ;清除按键代码,在使能键盘前,CH451的DOUT输出串行数据
MOV LAST_KEY,#0FFH ;有可能被当作键盘中断请求INT1,所以要先清除
MOV CH451_CMD_H,#0FFH ;清除CH451的命令码
; 由于在CH451启动键盘功能前的串行输出数据有可能产生键盘中断,所以需要再次取消中断
CLR IE1
SETB EA ;允许中断
; ...
;
; 如果P2的第5脚和第6脚之间插上短路子则由单片机控制演示,否则由PC机通过USB控制进行演示
JB P3.5,WAIT_USB_REQ ;T1,由PC机通过USB演示
;
; 由单片机控制演示,等待按键,然后先左移原显示,再加上按键值
MOV B,#0FH
MOV A,#17H ;向第1个数码管加载数据'H'
CALL CH451_WRITE ;发出命令
MOV B,#0EH
MOV A,#0EH ;向第2个数码管加载数据'E'
CALL CH451_WRITE ;发出命令
MOV B,#0DH
MOV A,#18H ;向第3个数码管加载数据'L'
CALL CH451_WRITE ;发出命令
MOV B,#0CH
MOV A,#19H ;向第4个数码管加载数据'P'
CALL CH451_WRITE ;发出命令
MOV B,#0BH
MOV A,#10H ;向第5个数码管加载数据' '
CALL CH451_WRITE ;发出命令
MOV B,#0AH
MOV A,#14H ;向第6个数码管加载数据'['
CALL CH451_WRITE ;发出命令
MOV B,#09H
MOV A,#88H ;向第7个数码管加载数据'8.'
CALL CH451_WRITE ;发出命令
MOV B,#08H
MOV A,#15H ;向第8个数码管加载数据']'
CALL CH451_WRITE ;发出命令
MOV B,#06H ;闪烁控制
MOV A,#30H ;第3个和第4个数码管闪烁
CALL CH451_WRITE ;发出命令
;
; 以下演示为显示按键代码,并且左移
WAIT_KEY: MOV A,#0FFH
XCH A,CH451_KEY ;取按键值并清除原值
MOV R2,A
XRL A,#0FFH
JZ WAIT_KEY ;没有按键
; 检测到新按键则先左移显示再显示键值
MOV A,#00H ;左移一位
MOV B,#03H ;移位命令
CALL CH451_WRITE ;发出命令
MOV A,#00H ;左移一位
MOV B,#03H ;移位命令
CALL CH451_WRITE ;发出命令
MOV A,R2
ANL A,#3FH ;键值0-63
MOV B,#0AH
DIV AB ;A为键值的十位数
MOV B,#09H ;向第7个数码管加载数据
CALL CH451_WRITE ;发出命令
MOV A,R2
ANL A,#3FH ;键值0-63
MOV B,#0AH
DIV AB
MOV A,B ;A为键值的个位数
MOV B,#08H ;向第8个数码管加载数据
CALL CH451_WRITE ;发出命令
SJMP WAIT_KEY
;
; 以下指令开始工作循环,等待PC机命令进行操作
WAIT_USB_REQ: NOP
NOP
NOP ;其它事务
NOP
MOV A,CH451_CMD_H ;高4位命令
CJNE A,#0FFH,IS_CH451_CMD ;在CH375中断服务程序中接收到PC机发给CH451的命令
; 没有CH451的命令, 以下检测按键状态
; LAST_KEY和CH451_KEY两个变量,都是0FFH则没有键按下
; 仅CH451_KEY为有效键值则是键刚按下, 两者都是有效键值并且相同则已经通知过计算机
MOV A,LAST_KEY
XRL A,#0FFH
JNZ IS_KEY_RELEASE ;按键已经按下并且已经通知过PC机,所以去检测按键释放
MOV A,CH451_KEY
XRL A,#0FFH
JZ WAIT_USB_REQ ;没有键按下,主循环
MOV A,CH451_KEY
CLR C
SUBB A,#40H
JC WAIT_USB_REQ ;键码无效
; 检测到新的键键,则置入有效的中断特征数据,以通知PC机应用层
MOV A,CH451_KEY
MOV LAST_KEY,A
MOV R0,#01H ;设定中断特征数据01H,通知PC机的应用层,按键已按下
MOV R7,LAST_KEY ;中断数据的次字节就是键码,所以PC机应用层直接获取键值,不必再读取
CALL CH375_UP_INT2 ;上传中断数据,本程序用于键盘中断,所以每次只需要传输两字节
LJMP WAIT_USB_REQ ;主循环
IS_KEY_RELEASE: NOP
CALL CH451_READ ;重新读取最近一次有效按键的键值
MOV CH451_KEY,A ;保存键值
XRL A,LAST_KEY
JZ WAIT_USB_REQ ;键码相同,按键仍然没有释放
MOV R0,#02H ;设定中断特征数据02H,通知PC机的应用层,按键已释放
MOV R7,LAST_KEY ;中断数据的次字节就是键码,所以PC机应用层直接获取键值
MOV LAST_KEY,#0FFH ;将要发送释放信号给PC
CALL CH375_UP_INT2 ;上传中断数据
LJMP WAIT_USB_REQ ;主循环
; PC发送命令给CH451,由于主程序中的CH451_READ可能会被CH375的高优先级中断,所以不宜在CH375中断服务程序中执行
IS_CH451_CMD: NOP
MOV B,CH451_CMD_H ;高4位命令
MOV A,CH451_CMD_L ;低8位命令
MOV CH451_CMD_H,#0FFH ;清除原命令码,防止重发
CALL CH451_WRITE ;向CH451发送命令
LJMP WAIT_USB_REQ ;主循环
;
;****************************************************************************
;
; 初始化子程序
; USE: ACC, R7, DPTR
CH375_INIT: CLR FLAG_INT_WAIT ;清中断等待标志,1指示有中断数据正在CH375中等待发送
; 测试CH375是否正常工作,可选操作
; MOV DPTR,#CH375_CMD_PORT ;命令口地址
; MOV A,#CMD_CHECK_EXIST
; MOVX @DPTR,A ;测试CH375是否正常工作,可选操作
; NOP ;如果时钟频率低于16MHz则无需该指令延时
; MOV DPTR,#CH375_DAT_PORT ;数据口地址
; MOV A,#55H
; MOVX @DPTR,A ;写入测试数据
; CPL A
; MOV R7,A ;取反数据
; MOVX A,@DPTR ;返回数据应该是测试数据取反
; XRL A,R7
; JZ CH375_INIT_OK ;测试通过
; MOV DPTR,#CH375_CMD_PORT ;命令口地址
; MOV A,#CMD_RESET_ALL
; MOV R7,#50H ;多次重复发命令
;CH375_INIT_HR: MOVX @DPTR,A ;执行硬件复位
; DJNZ R7,CH375_INIT_HR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -