![]() |
發布時間: 2021-5-25 14:58
正文摘要:據手冊說明 ,該單片機芯片內部無EEPROM,用戶可將用戶程序區的FLASH當做EEPROM用,試了好多扇區地址的讀寫和擦除,都是把程序直接干掉了,下次開機啥也沒有了。是這個芯片就無法存儲掉電保 ... |
jackliuwenli 發表于 2021-5-26 08:38 嗯 今天再倒騰倒騰,不行明天就換STC15F2K32S2了,我們以前的芯片是STM,現在太貴了。換芯從來了! |
![]() 建議先把例程跑通,多看官方操作 |
paladina 發表于 2021-5-25 21:26 我昨天折騰了一下午還是沒整明白,地址從F000H開始也不成,不過仿真整出來了。一會兒發出來! |
IAP15沒有EEPROM專用區,但可以把用戶程序區的多余FLASH當做EEPROM用。下載程序前根據代碼長度的下一個扇區,確定用作EEPROM的地址,以下圖為例,EEPROM的首地址選0x0800,就不會發生擦除用戶程序。![]() ![]() |
本帖最后由 bj1024 于 2021-5-25 16:50 編輯 #include "pbdata.h" #define CMD_IDLE 0 //空閑模式 #define CMD_READ 1 //IAP字節讀命令 #define CMD_PROGRAM 2 //IAP字節編程命令 #define CMD_ERASE 3 //IAP扇區擦除命令 //extern uchar ADDR; //uint addr_s; //sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字節 sTC15f內有定義 //sfr IAP_ADDRL = 0xC4; //IAP地址寄存器低字節 //sfr IAP_CMD = 0xC5; //IAP命令寄存器 //sfr IAP_TRIG = 0xC6; //IAP命令觸發寄存器 //sfr IAP_CONTR = 0xC7; //IAP控制寄存器 //根據不同的頻率選擇不同的等待時間 //#define ENABLE_IAP 0x80 //if SYSCLK<30MHz //#define ENABLE_IAP 0x81 //if SYSCLK<24MHz //#define ENABLE_IAP 0x82 //if SYSCLK<20MHz #define ENABLE_IAP 0x83 //if SYSCLK<12MHz //#define ENABLE_IAP 0x84 //if SYSCLK<6MHz //#define ENABLE_IAP 0x85 //if SYSCLK<3MHz //#define ENABLE_IAP 0x86 //if SYSCLK<2MHz //#define ENABLE_IAP 0x87 //if SYSCLK<1MHz /*---------------------------- IAP扇區擦除命令 ----------------------------*/ void eeprom_init(uint addr) //IAP扇區擦除命令 { IAP_CONTR= ENABLE_IAP; //使能IAP IAP_CMD= CMD_ERASE; //使能IAP命令 IAP_ADDRL= addr; //設置IAP低地址 IAP_ADDRH= addr >> 8; //設置IAP高地址 IAP_TRIG= 0x5a; //寫觸發命令0x5a IAP_TRIG= 0xa5; //寫觸發命令0xa5 _nop_(); //等待寫ISP/IAP/EEPROM數據完成 eeprom_offiap(); //關閉IAP功能 } /*---------------------------- 關閉IAP ----------------------------*/ void eeprom_offiap(void) { IAP_CONTR = 0; //關閉IAP功能 IAP_CMD = 0; //清除命令寄存器 IAP_TRIG = 0; //清除觸發寄存器 IAP_ADDRH = 0x80; //將地址設置到非IAP區域 IAP_ADDRL = 0; } /*---------------------------- 從ISP/IAP/EEPROM區域讀取一字節 ----------------------------*/ uchar eeprom_read(uint addr) { uchar dat; //數據緩沖區 IAP_CONTR = ENABLE_IAP; //使能IAP IAP_CMD = CMD_READ; //設置IAP命令 IAP_ADDRL = addr; //設置IAP低地址 IAP_ADDRH = addr >> 8; //設置IAP高地址 IAP_TRIG = 0x5a; //寫觸發命令(0x5a) IAP_TRIG = 0xa5; //寫觸發命令(0xa5) _nop_(); //等待ISP/IAP/EEPROM操作完成 dat = IAP_DATA; //讀ISP/IAP/EEPROM數據 eeprom_offiap(); //關閉IAP功能 return dat; //返回 } /*---------------------------- 從ISP/IAP/EEPROM區域寫一字節 ----------------------------*/ void eeprom_writ(uchar addr,uchar dat) { IAP_CONTR= ENABLE_IAP; //使能IAP IAP_CMD= CMD_PROGRAM; //設置IAP命令 IAP_ADDRL= addr; //設置IAP低地址 IAP_ADDRH= addr >> 8; //設置IPA高地址 IAP_DATA= dat; //寫ISP/IAP/EEPROM數據 IAP_TRIG= 0x5a; //寫觸發命令0x5a IAP_TRIG= 0xa5; //寫觸發命令0xa5 _nop_(); //等待寫ISP/IAP/EEPROM數據完成 eeprom_offiap(); //關閉IAP功能 } |