?? flash.c
字號:
//[Flash.c]Flash擦寫-------------------------------------------------------*
//本文件包含: *
// (1)Flash_Erase_Sector:擦除一個指定的扇區 *
// (2)Flash_Write_Nword:向一個指定的區域寫入若干個字 *
// (3)Flash_unsecured:使用后門機制解除Flash的安全狀態 *
// (4)Flash_SetKey:設置后門鑰匙 *
// (5)Flash_SetStatus:設置Flash的安全狀態 *
//-------------------------------------------------------------------------*
//頭文件
#include "Flash.h" //Flash擦寫頭文件
//內部調用函數聲明
void Erase_Write_Pretreat(INT8U page); //擦寫子函數內部調用的函數聲明
//頁所對應的塊對照表
//兩個flash塊,每塊4頁 flash0 flash1
const INT8U pagetable[2][4] = {{0x3C,0x3D,0x3E,0x3F},{0x38,0x39,0x3A,0x3B}};
//Flash_Erase_Sector:擦除指定的扇區----------------------------------------*
//功 能:對頁號為page,扇區首地址為addr的一個扇區進行擦除 *
//參 數:page--頁號(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
// addr--扇區首地址(偶數) *
//返 回:無 *
//注 意:調用該函數之前,必須確定要擦除的區域可擦除 *
//-------------------------------------------------------------------------*
void Flash_Erase_Sector(INT8U page,INT16U addr)
{
//1 判斷是否已分頻、清相關錯誤標志、根據頁號選擇相應的flash塊
Erase_Write_Pretreat(page); //擦寫子函數共同調用的內部子函數
//2 向要擦除的扇區首地址寫任意值(注意:經實驗證實,不可以寫0x0000)
*(INT16U *)addr = 0xFFFF;
//3 向命令寄存器寫扇區擦除命令
FCMD = 0x40;
//4 在加高壓期間,調用RAM區的機器碼,相當于兩條語句:
// FSTAT=0x80;
// while(!(FSTAT&0x40));
asm("JSR PrgOfRam");
}
//Flash_Write_Nword:向指定的扇區寫入若干個字-------------------------------*
//功 能:將從address_source開始的len個字,寫入頁號為 page,起始地址為 *
// address_destination的扇區 *
//參 數:page--頁映射地址(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
// address_destination--目標扇區首地址(偶數) *
// address_source--源地址 *
// len--字數(一次最多寫入一行,即128個字) *
//返 回:無 *
//注 意:調用該函數之前,必須確定要寫入的區域可寫入 *
//-------------------------------------------------------------------------*
void Flash_Write_Nword(INT8U page,INT16U address_destination,
INT16U address_source,INT8U len)
{
INT8U m;
//1 判斷是否已分頻、清相關錯誤標志、根據頁號選擇相應的flash塊
Erase_Write_Pretreat(page); //擦寫子函數共同調用的內部子函數
//2 寫入若干個字
for (m=0; m<len; m++)
{
//(1) 將源地址的一個字寫入目標地址
*(INT16U *)address_destination = *(INT16U *)address_source;
//(2) 向命令寄存器寫字寫入命令
FCMD = 0x20;
//(3) 在加高壓期間,調用RAM區的機器碼,相當于兩條語句:
// FSTAT=0x80;
// while(!(FSTAT&0x40));
asm("JSR PrgOfRam");
//(4) 源地址和目標地址同時向后移一個字
address_destination = address_destination+2;
address_source = address_source+2;
}
}
//Erase_Write_Pretreat:開始擦除或寫入前的公共操作序列子函數----------------*
//功 能:判斷是否已分頻;清相關錯誤標志;根據頁號選擇相應的flash塊;如果頁號不*
// 為0,則設置PPAGE寄存器 *
//參 數:page--頁映射地址(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
//返 回:無 *
//-------------------------------------------------------------------------*
void Erase_Write_Pretreat(INT8U page)
{
INT8U i,j;
//1 判斷是否設置時鐘分頻,若無分頻,則先分頻
if ((FCLKDIV&0x80) == 0) FCLKDIV |= 0x03;
//2 清保護錯誤和訪問錯誤標志位
FCNFG |= 0x01; //FCNFG的第0位置1,選擇BLOCK1
FSTAT |= 0x30; //清保護錯誤和訪問錯誤標志位
FCNFG &= 0xFE; //FCNFG的第0位置0,選擇BLOCK0
FSTAT |= 0x30; //清保護錯誤和訪問錯誤標志位
//3 查表、選擇塊號,如果頁號不為0就設置頁寄存器
if (page != 0)
{
for (i = 0;i < 2;i++)
{
for (j = 0;j < 4;j++)
{
if (page == pagetable[i][j])
break;
}
if (j < 4)
break;
}
if (i == 0) FCNFG &= 0xFE; //頁號3C~3F,選擇BLOCK0
if (i == 1) FCNFG |= 0x01; //頁號38~3B,選擇BLOCK1
PPAGE = page; //設置頁寄存器
}
}
//Flash_unsecured:使用后門機制解除Flash的安全狀態--------------------------*
//功 能:使用后門鑰匙解除Flash的安全狀態 *
//參 數:key[8]--8個字節的后門鑰匙 *
//返 回:無 *
//-------------------------------------------------------------------------*
void Flash_unsecured(INT8U key[8])
{
//1 判斷是否設置時鐘分頻,若無分頻,則先分頻
if ((FCLKDIV&0x80) == 0)
FCLKDIV |= 0x03;
//2 輸入密碼進行匹配
FCNFG |= 0x20;
Flash_Write_Nword(0x00,0xFF00,(INT16U)key,4);
FCNFG &= 0xCF;
}
//Flash_SetKey:設置后門鑰匙------------------------------------------------*
//功 能:設置后門鑰匙 *
//參 數:key[8]--8個字節的后門鑰匙 *
//返 回:無 *
//-------------------------------------------------------------------------*
void Flash_SetKey(INT8U key[8])
{
INT8U i;
INT8U Sbyte[2];
INT8U vec[128];
//1 判斷是否設置時鐘分頻,若無分頻,則先分頻
if ((FCLKDIV&0x80) == 0)
FCLKDIV |= 0x03;
//2 將安全字節保存到Sbyte
Sbyte[1]=*(INT8U *)0xFF0F;
//3 將向量區的字節搬到vector數組中
for(i=0;i<128;i++)
vec[i]=*(INT8U *)(0xFF80+i);
//4 擦除后門鑰匙所在的扇區
Flash_Erase_Sector(0X00,0xFF0E);
//5 將要設置的后門機制密碼寫入到0xFF00開始的8個字節中
Flash_Write_Nword(0x00,0xFF00,(INT16U)key,4);
//6 將Sbyte中的值重新寫入到Flash的安全字節中
Flash_Write_Nword(0x00,0xFF0E,(INT16U)Sbyte,1);
//7 將vector數組中的向量字節重新寫入到Flash的向量區
Flash_Write_Nword(0x00,0xFF80,(INT16U)vec,64);
}
//Flash_SetStatus:設置Flash的安全狀態--------------------------------------*
//功 能:設置Flash的安全狀態 *
//參 數:Sbyte[2]--其中Sbyte[1]中放的是安全字節,Sbyte[0]中放0xFF *
//返 回:無 *
//-------------------------------------------------------------------------*
void Flash_SetStatus(INT8U Sbyte[2])
{
INT8U i;
INT8U vec[128];
INT8U key[8];
//1判斷是否設置時鐘分頻,若無分頻,則先分頻
if ((FCLKDIV&0x80) == 0)
FCLKDIV |= 0x03;
//2 將安全字節搬到key數組中
for(i=0;i<8;i++)
key[i]=*(INT8U *)(0xFF00+i);
//3 將向量區的字節搬到vector數組中
for(i=0;i<128;i++)
vec[i]=*(INT8U *)(0xFF80+i);
//4 擦除安全字節所在的扇區
Flash_Erase_Sector(0X00,0xFF0E);
//5 設置安全字節
Flash_Write_Nword(0x00,0xFF0E,(INT16U)Sbyte,1);
//6 將key數組中的數據重新寫入Flash的0xFF00開始的8個安全字節中
Flash_Write_Nword(0x00,0xFF00,(INT16U)key,4);
//7 將vector數組中的向量字節重新寫入到Flash的向量區
Flash_Write_Nword(0x00,0xFF80,(INT16U)vec,64);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -