P89C51RD2的Boot ROM與ISP功能的實(shí)現(xiàn)
3.1.4 波特率的校驗(yàn)
在波特率確定以后,首先設(shè)定TR2=1以啟動(dòng)波特率,并對(duì)串口控制字進(jìn)行設(shè)定。然后,程序?qū)ζ溥M(jìn)行校驗(yàn)。方法是接收上位機(jī)的數(shù)據(jù)并以設(shè)定波特率回送該值,一方面通知上位機(jī)送出和接收的數(shù)據(jù)是否相同,如果相同,則上位機(jī)認(rèn)為下位機(jī)的波特率設(shè)置正確,通信成功;另一方面程序也將接收的數(shù)據(jù)?quot;U 的ASCII碼相對(duì)照,如果相等,則往下執(zhí)行,如果不等,則繼續(xù)重復(fù)上述過(guò)程,直到成功為止,否則進(jìn)入死循環(huán),只有程序復(fù)位才能退出。下面是其源程序與反匯編程序(FC37H至FC40H):
源代碼 反匯編程序
FC37 D2 CA SETB TR2
FC39 75 98 52 MOV SCON,#52H ;方式1,TI=1
FC3C 91 A0 RREV0: ACALL REV_SEND0
FC3E B4 55 FB CJNE A,#55H,RREV0 ;判斷A=U?
其中,REV_SEND0子程序的功能是接收一個(gè)數(shù)據(jù)并回傳給上位機(jī)。由上述程序可以看出,實(shí)際上要通信成功,上位機(jī)至少要向下位機(jī)發(fā)送兩個(gè)U:第一個(gè)用于確定波特率,另一個(gè)用于校驗(yàn)波特率,并且這兩個(gè)字符之間必須隔一段時(shí)間,以便于波特率計(jì)算完畢并有效。所以,有關(guān)手冊(cè)中關(guān)于ISP第一步要發(fā)送一個(gè)U來(lái)確定波特率的說(shuō)法本身沒(méi)有錯(cuò),但如果在編制上位機(jī)程序時(shí),僅僅發(fā)送一個(gè)U是不能夠通信成功的,特提醒讀者注意。
3.2 命令字的接收
在通信成功后,就可以接收ISP的命令字了。
3.2.1 ISP命令格式說(shuō)明
ISP編程由Boot ROM中的一系列引導(dǎo)子程序完成。這些子程序采用Intel-Hex記錄格式接收PC主機(jī)的命令和數(shù)據(jù)。Intel-Hex記錄格式上面已經(jīng)有所介紹,其命令格式為
:NNAAAARRDD…DDCCcrlf>
其中,:NNAAAA以及DDCC的含義皆與上面論述的相同,只需對(duì)RR作以下說(shuō)明:
RR表示記錄類型,其中
00--數(shù)據(jù)記錄,即傳編程數(shù)據(jù)并完成編程;
01--文件結(jié)束標(biāo)志;
02--指定振蕩器頻率;
03--雜項(xiàng)編程功能,和后面的數(shù)據(jù)相配合完成擦除、加密等功能;
04--顯示指定地址端FLASH的數(shù)據(jù)或做空白檢查;
05--各種讀功能。
3.2.2 命令字的處理
為了更容易看懂,將使用的通用寄存器和部分地址進(jìn)行代換如下:
DATA_ADDRL EQU 30H
DATA_ADDRH EQU 31H
DATA_SUM EQU 32H
DATA_LEN EQU 33H
DATA_FOSC EQU 34H
DATA_MODE EQU 35H
DATA_BUFFER EQU 36H
REV_DAT_ADDR EQU 80H
下面來(lái)看一下Boot ROM中的源代碼與反匯編程序。
源程序 反匯編程序
FC41 75 32 00 MAIN: MOV DATA_SUM,#00H;校驗(yàn)和
FC44 91 A0 ACALL REV_SEND0
FC46 B4 3A F8 CJNE A,#3AH,MAIN;判斷A=:?
FC49 91 79 ACALL REV_DAT1_SUM
FC4B 85 36 33 MOV DATA_LEN,DATA_BUFFER ;33H字節(jié)數(shù)
FC4E 91 79 ACALL REV_DAT1_SUM
FC50 85 36 31 MOV DATA_ADDRH,DATA_ BUFFER ;31H數(shù)據(jù)首地址高8位
FC53 91 79 ACALL REV_DAT1_SUM
FC55 85 36 30 MOV DATA_ADDRL,DATA_ BUFFER ;30H數(shù)據(jù)首地址低8位
FC58 91 79 ACALL REV_DAT1_SUM
FC5A 85 36 35 MOV DATA_MODE,DATA_ BUFFER ;35H數(shù)據(jù)操作類型
FC5D E5 33 MOV A,DATA_LEN
FC5F FA MOV R2,A ;循環(huán)接收數(shù)據(jù)指針
FC60 60 09 JZ RREV3 ;字節(jié)數(shù)=0 轉(zhuǎn)RREV3
FC62 79 80 MOV R1,#REV_DAT_ADDR
FC64 91 79 RREV2: ACALL REV_DAT1_SUM
FC66 A7 36 MOV @R1,DATA_MODE
FC68 09 INC R1
FC69 DA F9 DJNZ R2,RREV2
FC6B AC 32 RREV3: MOV R4,DATA_SUM ;校驗(yàn)和
FC6D 91 79 ACALL REV_DAT1_SUM
FC6F EC MOV A,R4
FC70 B5 36 02 CJNE A,DATA_BUFFER,RREV4
;校驗(yàn)和不等轉(zhuǎn)
FC73 81 BF AJMP RUN_MODE
FC75 74 58 RREV4:MOV A,#58H ; A=X
FC77 81 FA AJMP SEND_DT
首先,對(duì)程序中用到的子程序作如下的說(shuō)明。
REV_SEND0子程序:接收1個(gè)數(shù)據(jù)并回傳給上位機(jī);
REV_DAT1_SUM子程序:接收2個(gè)ASCII字符并回傳,將2個(gè)ASCII碼合成1字節(jié)二進(jìn)制數(shù)并計(jì)算校驗(yàn)和;
SEND_DT:該地址執(zhí)行送字符X給上位機(jī);
RUN_MODE:該地址解釋并執(zhí)行命令字。
評(píng)論