1.問(wèn)題:筆者在前期工作中,常常遇到在做測(cè)試時(shí),只要修改一些簡(jiǎn)短的指令或數(shù)據(jù)時(shí),就要再換一個(gè)全新的芯片重新燒錄一下,再測(cè)試。這樣即浪費(fèi)時(shí)間,又消費(fèi)芯片,還消費(fèi)金錢呢。 2.解決:其實(shí)OTP不是你想象的那么“頑固”,只要你對(duì)它好一些,還是有些回報(bào)的。在燒錄前,芯片的內(nèi)部全是由2進(jìn)制的1組成,燒錄后,是對(duì)里面的1進(jìn)行切斷成0,如此,燒錄過(guò)的不能再燒錄,是對(duì)已經(jīng)把1燒錄成0的不可再燒,而是沒(méi)有把1燒成0的,還是可以再燒的。也就是說(shuō),1可以變成0,而0不可再變?yōu)?,就象保險(xiǎn)絲一樣,燒斷了就不可再燒,而沒(méi)燒斷的,你還可以把它燒斷。要想實(shí)現(xiàn)重?zé)倪^(guò)程,還是要有些技巧的。哎,廢話這么多,來(lái)些實(shí)例的講吧。
你可以在你想要的地方預(yù)留些空間,等你想要在這修改時(shí),再?gòu)睦锩嫣崛〕鰜?lái)。
;-----------------------------------------------------------------------------;
3.實(shí)例1:在已經(jīng)燒過(guò)程序的IC上修改數(shù)據(jù):
incms t_enter_io ;500ms 進(jìn)入一次
nop ;
mov a,#0xFF ;1 預(yù)留數(shù)據(jù)修改(二進(jìn)制為:11111111b)
mov a,#0xFF ;2 預(yù)留數(shù)據(jù)修改
mov a,#0xFF ;3 預(yù)留數(shù)據(jù)修改
mov a,#0xFF ;4 預(yù)留數(shù)據(jù)修改
mov a,#0xFF ;5 預(yù)留數(shù)據(jù)修改
mov a,#0xF3 ;等待被修改的數(shù)據(jù)
cjb t_enter_io,a,e_tele_io ;249次進(jìn)入一下
clr t_enter_io ;
;-----------------------------------------------------------------------------;
3.1.1 (直接修改)比如我想在已經(jīng)燒有上面程序的IC的基礎(chǔ)上,修改a=0xF3(2二進(jìn)制:11110011B)為a=0xF1,此時(shí),你就不要再浪費(fèi)IC了,直接在上面修改就可以。你可以看到,0xF3與0xF1的區(qū)別只在于3和1,二進(jìn)制為:0011B和0001B,所以你可以把0011B(十進(jìn)制3)中第2位的1修改為0,即從0011B成為0001B,所以可以直接修改,當(dāng)然你也要以把它修改成為你想要的數(shù)據(jù),但前提是:你只能從二進(jìn)制中的1燒成0,不可從0變?yōu)?. 比如我可以把0xF1再燒成0xA1或0xA0或0x01或0x00等等。
;-----------------------------------------------------------------------------;
3.1.2 (覆蓋修改)是否有一種可以在上面的程序中任意修改數(shù)據(jù)呢?這是有的!讀者可以看到,我上面的程序?yàn)榱朔乐剐薷牟煌臄?shù)據(jù)而所預(yù)留的5條 :mov a,0xFF ,這是為了修改各種數(shù)據(jù)而預(yù)留的。你可以把 0xFF(二進(jìn)制:11111111B)修改成0~255范圍的任意一個(gè)數(shù)據(jù)。修改過(guò)程為:先把在最下面的不想要的數(shù)據(jù)(直接送數(shù)指令:mov a,0xF3 ;此指令生成的機(jī)器指令為:2DF3),用 NOP(機(jī)器指令為:0000 )給填充掉。然后第5條的0xFF修改為你想要的數(shù)據(jù)),比如修改為:0x45,修改后的程序如下:
incms t_enter_io ;500ms 進(jìn)入一次
nop ;
mov a,#0xFF ;1 預(yù)留數(shù)據(jù)修改(二進(jìn)制為:11111111b)
mov a,#0xFF ;2 預(yù)留數(shù)據(jù)修改
mov a,#0xFF ;3 預(yù)留數(shù)據(jù)修改
mov a,#0xFF ;4 預(yù)留數(shù)據(jù)修改
mov a,#0x45;0xFF ;5 預(yù)留數(shù)據(jù)修改 已經(jīng)修改為0x45
;;;mov a,#0xF3 ;此條指令用 NOP 取代 等待被修改的數(shù)據(jù)
NOP
cjb t_enter_io,a,e_tele_io ;249次進(jìn)入一下
clr t_enter_io ;
;-----------------------------------------------------------------------------;
實(shí)例2:只修改數(shù)據(jù)而已,有時(shí)還是不能達(dá)到我們想要的結(jié)果,有沒(méi)有一種可以寫任意的命令的呢?筆者給你的回答是:有!
在下面的一個(gè)實(shí)例中,給大伙分享下,預(yù)留空間的事。
3.2.1.(增加或修改部分指令)在已經(jīng)存在的程序里,修改或增加部分指令。我們注意到,在已經(jīng)燒過(guò)的IC中,里面有dw 0ffffh ,就相當(dāng)于在里面全 部用1去填充,當(dāng)然還可以再燒了。如下面的程序,我想在下面的 b0bset fp00 后面再加幾條不一樣的指令,如:我想讓系統(tǒng)在執(zhí)行到置FP00為1時(shí)后,進(jìn)入睡眠狀態(tài)。
incms t_enter_io ;500ms 進(jìn)入一次
nop ;
mov a,#0xF3 ;此條指令用 NOP 取代 等待被修改的數(shù)據(jù)
cjb t_enter_io,a,e_tele_io ;249次進(jìn)入一下
clr t_enter_io ;
;
b0bset fp00 ;
;
jmp @F ;預(yù)留空間30個(gè)
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh
@@: ;
修改完后,程序如下:
incms t_enter_io ;500ms 進(jìn)入一次
nop ;
mov a,#0xF3 ;此條指令用 NOP 取代 等待被修改的數(shù)據(jù)
cjb t_enter_io,a,e_tele_io ;249次進(jìn)入一下
clr t_enter_io ;
;
b0bset fp00 ;
;
;;;;;jmp @F ;預(yù)留空間30個(gè)將此條屏蔽,用NOP取代
NOP ;
b0bclr fcpum1 ;睡吧@@@!
b0bset fcpum0 ;
jmp @F ;用去了3條,只剩下27條指令空間了!
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh ;;;;;;0ffffh 0ffffh 0ffffh ;從這里釋放3條指令出來(lái)
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh
@@:
;-----------------------------------------------------------------------------;
3.2.2 (大量增加指令),筆者有個(gè)習(xí)慣,就是在寫完程序后,會(huì)把剩下的空間,全部預(yù)留起來(lái),以防止不測(cè)(呵呵)。也為增加大量的指令做些工作,這是必要的,筆者在開(kāi)發(fā)產(chǎn)品過(guò)程中,就碰到過(guò)這樣的情況,確定好了功能的產(chǎn)品,已經(jīng)在生產(chǎn)中,卻發(fā)現(xiàn)了隱藏很深的漏洞,由于之前做了些準(zhǔn)備,所以可以讓客戶再把燒過(guò)的IC發(fā)回來(lái),修改一下,重新燒給他,這把雙方的損失降到最低點(diǎn)。
例如程序如下:
當(dāng)要再加功能時(shí),就可以在save_ROM 中繼續(xù)添加,方法類似于上一個(gè)例子,在此不多做描述(若看不懂,可直接與筆者聯(lián)系)。
;;**************************************;*********
main: ;
@rst_wdt ;清看門狗
b0bts0 f_int_tc1 ;
call time_treat ;
; ;
b0bts0 f_check_buzzer ;
call buzzer ;
; ;
call save_ROM ; 把剩下的空間預(yù)留下來(lái)
jmp main ;
;;**************************************;*********
;;***********************************************;*********
;此文件為預(yù)留空間所用!
;;***********************************************;*********
save_ROM: ;預(yù)留空間
e_save_ROM: ;
ret ;
;;***********************************************;*********
;100
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh;
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
;100
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh;
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
dw 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh 0ffffh0ffffh 0ffffh
;………
評(píng)論