源於一年前想自己動手給51寫個os,編譯選large模式,除錯時整個流程都跑的好好的,可是燒寫到片上後得不到預期的效果,後來查書才知道51微控制器片上只有4krom,如果沒有擴充套件片外rom,當訪問4k以外的程式空間,程式指標又會回到最開始執行。參考手冊擴充套件片外rom後,能訪問達64k的程式空間。網上能搜尋到的擴充套件方式都是將ea引腳接地,讓mcu上電後從外部rom開始執行。但檢視晶元手冊,明明說ea為高時,程式從片內rom執行,當執行到0x1000以上位址時(標準51微控制器),會跳轉到片外rom執行。按網上的做法,為了擴充套件個片外rom,片內的基本rom都不用了,有點浪費了,於是開始找資料如何從片內跳轉到片外執行。
射人先射馬,發帖先上圖,**圖如下:
此處ea腳沒有接地。如果想簡單粗暴的加電時從片外rom執行,ea引腳接地,雙擊u2(27c64)image file選hex然後就可以了,這不是本文的重點,略過,後面可能會寫到。
跳轉,最簡單的方式用ljmp,當然也可以用把跳轉位址壓入棧,然後ret過去,不過這種方式我沒嘗試成功。
考慮到彙編寫**太苦逼,寫規模大一點的**還得靠c,因此程式的效果是:main函式在片內執行,流水燈**存放在片外rom,main函式跳轉到流水燈中執行。
因為是一種嘗試,所以從寫彙編**開始(載入位址容易控制:org指定即可)
1)用彙編**跳**
at89c51中的**:
org 0000h
ljmp 1000h
end#####################
27c64中**:
org 1000h
star:
mov a,#0aah
mov p1,a
mov a,#55h
mov p1,a
sjmp star
end程式執行起來後,pc暫存器指向0x0000處的ljmp 0x1000,然後跳到27c64處執行。起初,在27c64 0x0000處搜尋編碼,沒找到,查閱手冊後知,當pc超過0fffh時,會轉向片外程式儲存空間1000h-ffffh執行程式。
[27c64處的內容]
2)用c**跳**
#include
int main()
c**中嵌入彙編,做跳轉。
這個連線中有相關的設定 如果不做設定,連線時會有警告找不到c_startup,也不會執行到**中。
除錯執行,由於keil c加了啟動**,在protues**時有一長段麻煩的初始化堆疊的過程,因為沒有原始碼,連設定斷點都不行,只能按著f11傻等著。最終當然也是能跳轉到片外rom執行的。
3)片外rom存放由keil c編寫的hex檔案
這個摸索了很久才摸索出來!**如下:
#include
int main()
}首先,由於keil c建立的新工程會新增啟動**(startup.a51),這個前面說過用來初始化c語言執行的堆疊。因為我的程式是從片內rom跳轉過來執行的,至少已經被初始化了一次,再初始化一次,原本保留的變數全沒了,因此在建立工程的時候,跳過新增startup.a51這個檔案。帶來的不便是:程式沒有c環境,想要在除錯是不可能了。
hex檔案是生成了,載入,但是從片內rom跳轉過來後,p1口的內容不是0x33/0xcc而是上一次執行時的0x55/0xaa,why?**寫錯了?
檢視27c64的記憶體印象:
0x0000h的內容是:
75 90 33和75 90 cc是往p1埠寫入0x33/0xcc---就是現在的**
再檢視0x1000h的內容:
74 aa對應mov a,#0aah,f5 90 對應mov 90,a,明顯是上次**時的結果!
好吧,現在得想辦法把**載入到0x1000的位置,org是用不上了,得用其他辦法。
:08000f007590337590cc80f868
:03000000020003f8
:0c000300787fe4f6d8fd75810702000f3d
:00000001ff
080000f007 08是這行的長度8位元組,後面的0000是這行載入位置,從0x0000開始。****,難怪載入補上。先手動修改位址,修改玩以後,protues提示hex校驗碼不對,**失敗。無奈,只能想其他辦法了。載入位址一般是由聯結器在連線階段確定的(《程式設計師的自我修養》一書中有提到),既然這樣,看看keil c在鏈結時有沒有什麼引數可以設定:
bl51是keil c的聯結器,code這個位置好像是,那就試試填入0x1000,然後再編譯連線:
:08100c007590337590cc80f85b
:03000000021000eb
:0c100000787fe4f6d8fd75810702100c23
:00000001ff
這次生成的hex檔案,鏈結位址部分已經被改為0x100c。再**一次,不過這次**前要把片內rom的跳轉位址改為ljmp 0x1003,要不然指不准執行了非法指令。
27c64 0x100c處的內容75 90 33對應彙編語句 mov 90,#33h 75 90 cc對應彙編語句mov 90,#0cch這正是c**的內容,而且p1口的內容也是cc。
至此,從片內rom跳轉到片外rom結束。另外估計isp燒寫器可能也是類似的工作原理
51微控制器資料傳送 片內到片外(組合語言實現)
把儲存在片內ram 40h開始的16個單元 位址為40h到4fh 內容依次搬移到片外ram 3000h開始的16個單元 位址為3000h到300fh 內部ram 40h 4fh 單元位址內資料搬移到片外ram 3000h 300fh mov r0,40h 內部ram開始位址 mov dptr,300...
51微控制器 外部I O口擴充套件實驗
一 實驗內容 mcs 51系列微控制器對外部裝置的訪問 即i o口輸入 輸出操作 的基本要求是 輸入緩衝 輸出鎖存 實驗中開關量k8k1的輸入經74ls244八位緩衝輸入介面實現,74ls273作為鎖存輸出介面,控制l8l1八個發光二極體的亮滅。資料匯流排連線p0埠 二 圖 三 c語言實現 incl...
基於51微控制器modbusRTU從機設計
在了解modbus協議後就是基於該協議的設計了,下面先說一下基於航太電子htm52微控制器的從機設計。設計思想如下 modbus協議是以主從的方式通訊的,也就是上位機傳送指令,下位機應答機制,發起通訊的一直是上位機,下位機只要應答就好了。modbus協議被設計出來是針對plc應用的,這裡我們可以簡單...