發一個M051單片機的 ISP操作程序(LDROM、FMC,相當于8位機EEPROM操作)
#include "SmartM_M0.h"
#define DEBUGMSG printf
#define PAGE_SIZE 512
#define DATAFLASH_START_ADDRESS 0x0001F000
#define DATAFLASH_SIZE 0x00001000
#define RW_SIZE 0x20
#define DATAFLASH_START_ADDRESS 0x0001F000
#define DATAFLASH_SIZE 0x00001000
#define RW_SIZE 0x20
STATIC UINT8 g_unDataFlashWRBuf[10]; //全局讀寫緩沖區
/****************************************
*函數名稱:ISPTriger
*輸 入:無
*輸 出:無
*功 能:ISP執行
******************************************/
VOID ISPTriger(VOID)
{
ISPTRG |= ISPGO;
while((ISPTRG&ISPGO) == ISPGO);
}
/****************************************
*函數名稱:ISPEnable
*輸 入:無
*輸 出:無
*功 能:ISP使能
******************************************/
VOID ISPEnable(VOID)
{
Un_Lock_Reg();
ISPCON |= ISPEN;
}
/****************************************
*函數名稱:ISPDisable
*輸 入:無
*輸 出:無
*功 能:ISP禁用
******************************************/
VOID ISPDisable(VOID)
{
Un_Lock_Reg();
ISPCON &= ~ISPEN;
}
/****************************************
*函數名稱:DataFlashRWEnable
*輸 入:無
*輸 出:無
*功 能:數據區讀寫使能
******************************************/
VOID DataFlashRWEnable(VOID)
{
Un_Lock_Reg();
ISPCON |= LDUEN;
}
/****************************************
*函數名稱:DataFlashErase
*輸 入:unPage 頁地址
*輸 出:無
*功 能:數據區擦除
******************************************/
VOID DataFlashErase(UINT32 unPage)
{
ISPEnable();
DataFlashRWEnable();
ISPCMD = PAGE_ERASE;
*函數名稱:ISPTriger
*輸 入:無
*輸 出:無
*功 能:ISP執行
******************************************/
VOID ISPTriger(VOID)
{
ISPTRG |= ISPGO;
while((ISPTRG&ISPGO) == ISPGO);
}
/****************************************
*函數名稱:ISPEnable
*輸 入:無
*輸 出:無
*功 能:ISP使能
******************************************/
VOID ISPEnable(VOID)
{
Un_Lock_Reg();
ISPCON |= ISPEN;
}
/****************************************
*函數名稱:ISPDisable
*輸 入:無
*輸 出:無
*功 能:ISP禁用
******************************************/
VOID ISPDisable(VOID)
{
Un_Lock_Reg();
ISPCON &= ~ISPEN;
}
/****************************************
*函數名稱:DataFlashRWEnable
*輸 入:無
*輸 出:無
*功 能:數據區讀寫使能
******************************************/
VOID DataFlashRWEnable(VOID)
{
Un_Lock_Reg();
ISPCON |= LDUEN;
}
/****************************************
*函數名稱:DataFlashErase
*輸 入:unPage 頁地址
*輸 出:無
*功 能:數據區擦除
******************************************/
VOID DataFlashErase(UINT32 unPage)
{
ISPEnable();
DataFlashRWEnable();
ISPCMD = PAGE_ERASE;
ISPADR = (unPage*PAGE_SIZE+DATAFLASH_START_ADDRESS);
ISPTriger();
ISPTriger();
ISPDisable();
}
/****************************************
*函數名稱:DataFlashWrite
*輸 入:pucBuf 寫數據緩沖區
unSize 寫數據大小
*輸 出:無
*功 能:數據區寫
******************************************/
VOID DataFlashWrite(UINT8 *pucBuf,UINT32 unSize)//unSize要為4的倍數
{
UINT32 i;
}
/****************************************
*函數名稱:DataFlashWrite
*輸 入:pucBuf 寫數據緩沖區
unSize 寫數據大小
*輸 出:無
*功 能:數據區寫
******************************************/
VOID DataFlashWrite(UINT8 *pucBuf,UINT32 unSize)//unSize要為4的倍數
{
UINT32 i;
ISPEnable();
DataFlashRWEnable();
ISPCMD = PROGRAM;
DataFlashRWEnable();
ISPCMD = PROGRAM;
for(i=0; i<unSize; i+=4)
{
ISPADR = (i*4+DATAFLASH_START_ADDRESS);
ISPDAT = *(UINT32 *)(pucBuf+i);
ISPTriger();
}
{
ISPADR = (i*4+DATAFLASH_START_ADDRESS);
ISPDAT = *(UINT32 *)(pucBuf+i);
ISPTriger();
}
ISPDisable();
}
/****************************************
*函數名稱:DataFlashRead
*輸 入:pucBuf 讀數據緩沖區
unSize 讀數據大小
*輸 出:無
*功 能:數據區讀
******************************************/
VOID DataFlashRead(UINT8 *pucBuf,UINT32 unSize)
{
UINT32 i;
}
/****************************************
*函數名稱:DataFlashRead
*輸 入:pucBuf 讀數據緩沖區
unSize 讀數據大小
*輸 出:無
*功 能:數據區讀
******************************************/
VOID DataFlashRead(UINT8 *pucBuf,UINT32 unSize)
{
UINT32 i;
ISPEnable();
DataFlashRWEnable();
ISPCMD = READ;
DataFlashRWEnable();
ISPCMD = READ;
for(i=0; i<unSize; i+=4)
{
ISPADR = (i*4+DATAFLASH_START_ADDRESS);
ISPTriger();
*(UINT32 *)(pucBuf+i)=ISPDAT;
}
ISPDisable();
}
/****************************************
*函數名稱:main
*輸 入:無
*輸 出:無
*功 能:函數主體
******************************************/
INT32 main(VOID)
{
UINT32 i;
PROTECT_REG //ISP下載時保護FLASH存儲器
(
PWRCON |= XTL12M_EN; //默認時鐘源為外部晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等待12MHz時鐘穩定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //設置外部晶振為系統時鐘
)
{
ISPADR = (i*4+DATAFLASH_START_ADDRESS);
ISPTriger();
*(UINT32 *)(pucBuf+i)=ISPDAT;
}
ISPDisable();
}
/****************************************
*函數名稱:main
*輸 入:無
*輸 出:無
*功 能:函數主體
******************************************/
INT32 main(VOID)
{
UINT32 i;
PROTECT_REG //ISP下載時保護FLASH存儲器
(
PWRCON |= XTL12M_EN; //默認時鐘源為外部晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等待12MHz時鐘穩定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //設置外部晶振為系統時鐘
)
UartInit(12000000,9600); //串口0波特率為9600
while(1)
{
//擦除第0頁
DataFlashErase(0);
{
//擦除第0頁
DataFlashErase(0);
DEBUGMSG("\r\nData Flash Write:\r\n");
//初始化緩沖區,所有數值全為0x11
memset(g_unDataFlashWRBuf,0x11,sizeof(g_unDataFlashWRBuf));
for(i=0; i<sizeof(g_unDataFlashWRBuf); i++)
{
DEBUGMSG("%02X ",g_unDataFlashWRBuf[i]);
}
memset(g_unDataFlashWRBuf,0x11,sizeof(g_unDataFlashWRBuf));
for(i=0; i<sizeof(g_unDataFlashWRBuf); i++)
{
DEBUGMSG("%02X ",g_unDataFlashWRBuf[i]);
}
//數據區寫
DataFlashWrite(g_unDataFlashWRBuf,sizeof(g_unDataFlashWRBuf));
DataFlashWrite(g_unDataFlashWRBuf,sizeof(g_unDataFlashWRBuf));
DEBUGMSG("\r\nData Flash Read:\r\n");
//清零緩沖區
memset(g_unDataFlashWRBuf,0,sizeof(g_unDataFlashWRBuf));
//數據區讀
DataFlashRead(g_unDataFlashWRBuf,sizeof(g_unDataFlashWRBuf));
for(i=0; i<sizeof(g_unDataFlashWRBuf); i++)
{
DEBUGMSG("%02X ",g_unDataFlashWRBuf[i]);
}
Delayms(500);
}
}
//清零緩沖區
memset(g_unDataFlashWRBuf,0,sizeof(g_unDataFlashWRBuf));
//數據區讀
DataFlashRead(g_unDataFlashWRBuf,sizeof(g_unDataFlashWRBuf));
for(i=0; i<sizeof(g_unDataFlashWRBuf); i++)
{
DEBUGMSG("%02X ",g_unDataFlashWRBuf[i]);
}
Delayms(500);
}
}