?? ch375451.asm
字號(hào):
; CH375/CH372/CH451 EVT
; U2(AT89C51) Program
;
; Website: http://winchiphead.com
; Email: tech@winchiphead.com
; Author: W.ch 2003.12
;
;****************************************************************************
;
; 應(yīng)用層定義
CONST_CMD_LEN EQU 07H ; 命令塊的長(zhǎng)度
; 由于命令與數(shù)據(jù)都是通過(guò)數(shù)據(jù)下傳管道(USB端點(diǎn)2的OUT)下傳, 為了防止兩者混淆,
; 我們可以在計(jì)算機(jī)應(yīng)用程序與單片機(jī)程序之間約定, 命令塊的長(zhǎng)度總是7, 而數(shù)據(jù)塊的長(zhǎng)度肯定不是7, 例如64,32等
; 另外, 可以約定, 命令塊的首字節(jié)是命令碼, 等等
DEMO_CH451_CMD EQU 56H ; PC發(fā)送命令給CH451
DEMO_TEST_DATA EQU 91H ; 測(cè)試命令,將PC機(jī)發(fā)來(lái)的命令包的所有數(shù)據(jù)取反后返回
DEMO_UP_CLEAR EQU 0A0H ; 連續(xù)上傳數(shù)據(jù)塊之前進(jìn)行同步,實(shí)際是讓單片機(jī)清除上傳緩沖區(qū)的已有內(nèi)容
DEMO_UP_DATA EQU 0A1H ; 連續(xù)上傳數(shù)據(jù)塊,指定外部RAM緩沖區(qū)起始地址,不限長(zhǎng)度
DEMO_DOWN_DATA EQU 0A2H ; 連續(xù)下傳數(shù)據(jù)塊,指定外部RAM緩沖區(qū)起始地址,不限長(zhǎng)度
;
STACK EQU 0FH ;堆棧區(qū)棧頂(向上延伸)
;
; CH375的命令代碼定義
$INCLUDE (..\..\MCU_IF1\MCS51ASM\CH375INC.ASM)
;
; 需要主程序定義的參數(shù)
CH375_CMD_PORT EQU 0BDF1H ;CH375命令口的地址,地址譯碼后自動(dòng)片選
CH375_DAT_PORT EQU 0BCF0H ;CH375命令口的地址,地址譯碼后自動(dòng)片選
;
; 有關(guān)CH451的定義
CH451_DCLK BIT P1.7 ;串行數(shù)據(jù)時(shí)鐘,上升沿激活
CH451_DIN BIT P1.6 ;串行數(shù)據(jù)輸出,接CH451的數(shù)據(jù)輸入
CH451_LOAD BIT P1.5 ;串行命令加載,上升沿激活
CH451_DOUT BIT P3.3 ;INT1,鍵盤(pán)中斷和鍵值數(shù)據(jù)輸入,接CH451的數(shù)據(jù)輸出
CH451_KEY DATA 28H ;存放鍵盤(pán)中斷中讀取的鍵值
LAST_KEY DATA 29H ;保存上次的鍵值
;
; 有關(guān)CH375的定義
CH451_CMD_H DATA 30H ;PC機(jī)發(fā)給CH451的高4位命令,為0FFH則命令無(wú)效
CH451_CMD_L DATA 31H ;PC機(jī)發(fā)給CH451的低8位命令
BUF_ADDR_L DATA 32H ;保存用于傳輸?shù)耐獠縍AM或者內(nèi)部RAM緩沖區(qū)的地址,低8位
BUF_ADDR_H DATA 33H ;保存用于傳輸?shù)耐獠縍AM或者內(nèi)部RAM緩沖區(qū)的地址,高8位
BUF_LEN_L DATA 34H ;當(dāng)前剩余的要傳輸?shù)臄?shù)據(jù)長(zhǎng)度,低8位
BUF_LEN_H DATA 35H ;當(dāng)前剩余的要傳輸?shù)臄?shù)據(jù)長(zhǎng)度,高8位
CMD_BUFFER DATA 38H ;命令包緩沖區(qū),本程序約定命令包長(zhǎng)度為CONST_CMD_LEN
CMD_BUFFER_NOT DATA 39H ;命令碼的反碼,用于校驗(yàn)命令包
CMD_BUFFER_ID DATA 3AH ;命令包緩沖區(qū)次字節(jié),緩沖區(qū)識(shí)別碼,針對(duì)MCS51單片機(jī)定義: 1-專(zhuān)用功能寄存器SFR, 2-內(nèi)部RAM, 3-外部RAM, 不過(guò)本程序?qū)嶋H只演示內(nèi)部RAM
CMD_BUFFER_ADRL DATA 3BH ;命令包緩沖區(qū)第3字節(jié),緩沖區(qū)地址低8位
CMD_BUFFER_ADRH DATA 3CH ;命令包緩沖區(qū)第4字節(jié),緩沖區(qū)地址高8位
CMD_BUFFER_LENL DATA 3DH ;命令包緩沖區(qū)第5字節(jié),數(shù)據(jù)總長(zhǎng)度低8位
CMD_BUFFER_LENH DATA 3EH ;命令包緩沖區(qū)第6字節(jié),數(shù)據(jù)總長(zhǎng)度高8位
; 由于MCS-51單片機(jī)存取外部RAM的讀寫(xiě)速度低于內(nèi)部RAM, 并且需要用到DPTR, 所以讀寫(xiě)速度較慢, 其程序可以參考本程序修改
;
; 定義位標(biāo)志
FLAG_INT_WAIT BIT 2FH.2 ;中斷等待標(biāo)志,1指示有中斷數(shù)據(jù)正在CH375中等待發(fā)送
;
;
;****************************************************************************
;主程序,用于配合演示CH375和CH451功能
ORG 0000H ;復(fù)位后單片機(jī)入口
LJMP START
ORG 0003H ;CH375中斷
LJMP CH375_INTER
ORG 0013H ;CH451中斷,鍵盤(pán)中斷后將通知PC機(jī)應(yīng)用層
LJMP CH451_INTER
;
START:
; 以下初始化指令不是必要的,將單片機(jī)恢復(fù)為默認(rèn)狀態(tài)
CLR EA ;關(guān)中斷
MOV SP,#STACK ;置堆棧初值
MOV A,#0FFH
MOV P0,A
MOV P1,A ;清端口狀態(tài)
MOV P2,A
MOV P3,A
CLR A
MOV IE,A ;清中斷允許控制寄存器
MOV IP,A ;清中斷優(yōu)先級(jí)控制寄存器
MOV PSW,A ;清程序狀態(tài)字
MOV TCON,A ;清定時(shí)器/計(jì)數(shù)器控制寄存器
MOV TMOD,A ;清定時(shí)器/計(jì)數(shù)器工作方式寄存器
MOV PCON,A ;清電源控制寄存器
MOV R7,#0FFH
CALL DELAY_MS ;延時(shí)等待CH375初始化完成
; 初始化
CALL CH375_INIT ;初始化
CALL CH451_INIT ;初始化
; .....
; 啟動(dòng)CH451的顯示驅(qū)動(dòng)和鍵盤(pán)掃描
MOV B,#04H ;設(shè)置系統(tǒng)參數(shù)命令
MOV A,#03H ;禁止看門(mén)狗,使能鍵盤(pán)功能,使能顯示驅(qū)動(dòng)
CALL CH451_WRITE ;發(fā)出命令
MOV B,#05H ;設(shè)置顯示參數(shù)
MOV A,#8CH ;BCD譯碼方式,12級(jí)亮度
CALL CH451_WRITE ;發(fā)出命令
MOV CH451_KEY,#0FFH ;清除按鍵代碼,在使能鍵盤(pán)前,CH451的DOUT輸出串行數(shù)據(jù)
MOV LAST_KEY,#0FFH ;有可能被當(dāng)作鍵盤(pán)中斷請(qǐng)求INT1,所以要先清除
MOV CH451_CMD_H,#0FFH ;清除CH451的命令碼
; 由于在CH451啟動(dòng)鍵盤(pán)功能前的串行輸出數(shù)據(jù)有可能產(chǎn)生鍵盤(pán)中斷,所以需要再次取消中斷
CLR IE1
SETB EA ;允許中斷
; ...
;
; 如果P2的第5腳和第6腳之間插上短路子則由單片機(jī)控制演示,否則由PC機(jī)通過(guò)USB控制進(jìn)行演示
JB P3.5,WAIT_USB_REQ ;T1,由PC機(jī)通過(guò)USB演示
;
; 由單片機(jī)控制演示,等待按鍵,然后先左移原顯示,再加上按鍵值
MOV B,#0FH
MOV A,#17H ;向第1個(gè)數(shù)碼管加載數(shù)據(jù)'H'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#0EH
MOV A,#0EH ;向第2個(gè)數(shù)碼管加載數(shù)據(jù)'E'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#0DH
MOV A,#18H ;向第3個(gè)數(shù)碼管加載數(shù)據(jù)'L'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#0CH
MOV A,#19H ;向第4個(gè)數(shù)碼管加載數(shù)據(jù)'P'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#0BH
MOV A,#10H ;向第5個(gè)數(shù)碼管加載數(shù)據(jù)' '
CALL CH451_WRITE ;發(fā)出命令
MOV B,#0AH
MOV A,#14H ;向第6個(gè)數(shù)碼管加載數(shù)據(jù)'['
CALL CH451_WRITE ;發(fā)出命令
MOV B,#09H
MOV A,#88H ;向第7個(gè)數(shù)碼管加載數(shù)據(jù)'8.'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#08H
MOV A,#15H ;向第8個(gè)數(shù)碼管加載數(shù)據(jù)']'
CALL CH451_WRITE ;發(fā)出命令
MOV B,#06H ;閃爍控制
MOV A,#30H ;第3個(gè)和第4個(gè)數(shù)碼管閃爍
CALL CH451_WRITE ;發(fā)出命令
;
; 以下演示為顯示按鍵代碼,并且左移
WAIT_KEY: MOV A,#0FFH
XCH A,CH451_KEY ;取按鍵值并清除原值
MOV R2,A
XRL A,#0FFH
JZ WAIT_KEY ;沒(méi)有按鍵
; 檢測(cè)到新按鍵則先左移顯示再顯示鍵值
MOV A,#00H ;左移一位
MOV B,#03H ;移位命令
CALL CH451_WRITE ;發(fā)出命令
MOV A,#00H ;左移一位
MOV B,#03H ;移位命令
CALL CH451_WRITE ;發(fā)出命令
MOV A,R2
ANL A,#3FH ;鍵值0-63
MOV B,#0AH
DIV AB ;A為鍵值的十位數(shù)
MOV B,#09H ;向第7個(gè)數(shù)碼管加載數(shù)據(jù)
CALL CH451_WRITE ;發(fā)出命令
MOV A,R2
ANL A,#3FH ;鍵值0-63
MOV B,#0AH
DIV AB
MOV A,B ;A為鍵值的個(gè)位數(shù)
MOV B,#08H ;向第8個(gè)數(shù)碼管加載數(shù)據(jù)
CALL CH451_WRITE ;發(fā)出命令
SJMP WAIT_KEY
;
; 以下指令開(kāi)始工作循環(huán),等待PC機(jī)命令進(jìn)行操作
WAIT_USB_REQ: NOP
NOP
NOP ;其它事務(wù)
NOP
MOV A,CH451_CMD_H ;高4位命令
CJNE A,#0FFH,IS_CH451_CMD ;在CH375中斷服務(wù)程序中接收到PC機(jī)發(fā)給CH451的命令
; 沒(méi)有CH451的命令, 以下檢測(cè)按鍵狀態(tài)
; LAST_KEY和CH451_KEY兩個(gè)變量,都是0FFH則沒(méi)有鍵按下
; 僅CH451_KEY為有效鍵值則是鍵剛按下, 兩者都是有效鍵值并且相同則已經(jīng)通知過(guò)計(jì)算機(jī)
MOV A,LAST_KEY
XRL A,#0FFH
JNZ IS_KEY_RELEASE ;按鍵已經(jīng)按下并且已經(jīng)通知過(guò)PC機(jī),所以去檢測(cè)按鍵釋放
MOV A,CH451_KEY
XRL A,#0FFH
JZ WAIT_USB_REQ ;沒(méi)有鍵按下,主循環(huán)
MOV A,CH451_KEY
CLR C
SUBB A,#40H
JC WAIT_USB_REQ ;鍵碼無(wú)效
; 檢測(cè)到新的鍵鍵,則置入有效的中斷特征數(shù)據(jù),以通知PC機(jī)應(yīng)用層
MOV A,CH451_KEY
MOV LAST_KEY,A
MOV R0,#01H ;設(shè)定中斷特征數(shù)據(jù)01H,通知PC機(jī)的應(yīng)用層,按鍵已按下
MOV R7,LAST_KEY ;中斷數(shù)據(jù)的次字節(jié)就是鍵碼,所以PC機(jī)應(yīng)用層直接獲取鍵值,不必再讀取
CALL CH375_UP_INT2 ;上傳中斷數(shù)據(jù),本程序用于鍵盤(pán)中斷,所以每次只需要傳輸兩字節(jié)
LJMP WAIT_USB_REQ ;主循環(huán)
IS_KEY_RELEASE: NOP
CALL CH451_READ ;重新讀取最近一次有效按鍵的鍵值
MOV CH451_KEY,A ;保存鍵值
XRL A,LAST_KEY
JZ WAIT_USB_REQ ;鍵碼相同,按鍵仍然沒(méi)有釋放
MOV R0,#02H ;設(shè)定中斷特征數(shù)據(jù)02H,通知PC機(jī)的應(yīng)用層,按鍵已釋放
MOV R7,LAST_KEY ;中斷數(shù)據(jù)的次字節(jié)就是鍵碼,所以PC機(jī)應(yīng)用層直接獲取鍵值
MOV LAST_KEY,#0FFH ;將要發(fā)送釋放信號(hào)給PC
CALL CH375_UP_INT2 ;上傳中斷數(shù)據(jù)
LJMP WAIT_USB_REQ ;主循環(huán)
; PC發(fā)送命令給CH451,由于主程序中的CH451_READ可能會(huì)被CH375的高優(yōu)先級(jí)中斷,所以不宜在CH375中斷服務(wù)程序中執(zhí)行
IS_CH451_CMD: NOP
MOV B,CH451_CMD_H ;高4位命令
MOV A,CH451_CMD_L ;低8位命令
MOV CH451_CMD_H,#0FFH ;清除原命令碼,防止重發(fā)
CALL CH451_WRITE ;向CH451發(fā)送命令
LJMP WAIT_USB_REQ ;主循環(huán)
;
;****************************************************************************
;
; 初始化子程序
; USE: ACC, R7, DPTR
CH375_INIT: CLR FLAG_INT_WAIT ;清中斷等待標(biāo)志,1指示有中斷數(shù)據(jù)正在CH375中等待發(fā)送
; 測(cè)試CH375是否正常工作,可選操作
; MOV DPTR,#CH375_CMD_PORT ;命令口地址
; MOV A,#CMD_CHECK_EXIST
; MOVX @DPTR,A ;測(cè)試CH375是否正常工作,可選操作
; NOP ;如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí)
; MOV DPTR,#CH375_DAT_PORT ;數(shù)據(jù)口地址
; MOV A,#55H
; MOVX @DPTR,A ;寫(xiě)入測(cè)試數(shù)據(jù)
; CPL A
; MOV R7,A ;取反數(shù)據(jù)
; MOVX A,@DPTR ;返回?cái)?shù)據(jù)應(yīng)該是測(cè)試數(shù)據(jù)取反
; XRL A,R7
; JZ CH375_INIT_OK ;測(cè)試通過(guò)
; MOV DPTR,#CH375_CMD_PORT ;命令口地址
; MOV A,#CMD_RESET_ALL
; MOV R7,#50H ;多次重復(fù)發(fā)命令
;CH375_INIT_HR: MOVX @DPTR,A ;執(zhí)行硬件復(fù)位
; DJNZ R7,CH375_INIT_HR
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -