飛思卡爾 HCS12(X)系列 MCU 的 Prm 文件中的邏輯地址和全局地址的轉換

因爲在個人項目中,須要實現對 HCS12 單片機的 FLASH 進行擦寫,因此不免會遇到對全局地址的操做,由於對 FLASH 的擦寫操做是必須使用全局地址的。調試

 

下圖是擦除指令序列的說明it

飛思卡爾 HCS12(X)系列 MCU 的 Prm 文件中的邏輯地址和全局地址的轉換 - liufan2007 - 愛好電子的阿皮哥

圖 1class

其中 Global address[17:16]是須要寫入 FLASH 的 Block 值,下面的 Global address[15:0]是低 16 位地址。一共是 18Bit的全局地址,其最大的尋址的空間是  = 2^18 = 256K。sed

下圖是邏輯地址和全局地址的映射圖分頁

飛思卡爾 HCS12(X)系列 MCU 的 Prm 文件中的邏輯地址和全局地址的轉換 - liufan2007 - 愛好電子的阿皮哥

圖 2im

能夠發現低 14 位地址就是一頁的大小 2^14 = 16K, 高 4 位地址就是頁寄存器 PPAGE 的地址,由[17:14]組成。項目

 下面說明 PRM 文件和全局地址的轉換關係img

取 MC9SHY64 工程的 PRM 文件的片斷文件

 /* non-paged FLASHs */sse

      ROM_1400      = READ_ONLY     0x1400 TO   0x2FFF; //7K

      ROM_4000      = READ_ONLY     0x4000 TO   0x7FFF; //16K

      ROM_C000      = READ_ONLY     0xC000 TO   0xFEFF; //16k

/* paged FLASH:       0x8000 TO   0xBFFF; addressed through PPAGE */

      PAGE_0C       = READ_ONLY   0x0C8000 TO 0x0C93FF;  //5k

      PAGE_0C_B000  = READ_ONLY   0x0CB000 TO 0x0CBFFF;  //4k

      PAGE_0E       = READ_ONLY   0x0E8000 TO 0x0EBFFF;  //16k

 

對於分頁區

其中 PAGE_0C,PAGE_0C_B000,PAGE_0E 屬於分頁區範圍,因爲是在分頁區,因此若是須要擦寫

這個區域,則須要轉換,PAGE_0C 的 0C 就是頁號,它對應了 PPAGE。

0C = 0000 1100,其中 11 就是 Global address[17:16]這 2 位,11 後面的 00 實際是無效的。

PAGE_0C 後面的起始地址是 0x0C8000,這裏的 8000 是分頁窗口邏輯地址範圍內的起始地址,0C 就是頁號,按照圖 2進行理解,全局地址 = (0x0C<<14) | 0x8000 = 0x38000,這個理解是錯誤的。通過調試發現應該是這樣的:

 全局地址  = (0x0C<<14)  | (0x8000 – 0x8000)  =    0x30000

 則 邏輯地址

Logic address = (Global address & 0x3C000) <<2 | (Global address & 0x03FFF)  + 0x8000

則 上例的邏輯地址 = (0x30000 & 0x3C000)<<2 | 0x30000 & 0x03FFF + 0x8000 = 0xC8000

那麼

 PAGE_0C_B000  = READ_ONLY   0x0CB000 TO 0x0CBFFF;  //4k

 全局地址  = (0x0C<<14)  | (0xB000 – 0x8000)  =    0x33000

 邏輯地址 = (0x33000 & 0x3C000)<<2 | 0x33000 & 0x03FFF + 0x8000 = 0xCB000

 即,若是要擦寫 PAGE_0C_B000 這個區域,則以下設置

Global address[17:16] = 0x03

Global address[15:0] = 0x3000

 

對於非分頁區

其中 ROM_1400,ROM_4000,ROM_C000 屬於非分頁區範圍,因爲是在非分頁區,頁寄存器 PPAGE是無效的,因此若是須要擦寫這個區域,則將圖 1 中的 Global address[17:16]這 2 位寫 00 便可,

而後 Global address[15:0]直接寫地址值就行,如 Global address[15:0] = 0x1400。

 ROM_1400      = READ_ONLY     0x1400 TO   0x2FFF; //7K

 全局地址  = (0x00<<14)  | 0x1400)  =    0x01400

 這些結論是我通過實際調試得出來的,不知道理解的如何,若是有高手,但願能指點指點!謝謝!