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

📄 ch375451.asm

📁 CH372 USB-UART Chip Specification Document,for reference only
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; 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 + -