eeprom.c
1 #include "eeprom.h" 2 3 /*-----------eeprom------------*/ 4 //------------------------------- 5 //Eeprom_Unlock(解锁) 6 //Input: on 7 //Output:on 8 //------------------------------- 9 void Eeprom_Unlock(void) 10 { 11 IAP_CONTR = ENABLE_EEPROM; //打开IAP功能,并设置等待时间 12 } 13 //------------------------------- 14 //Eeprom_Locked(上锁) 15 //Input: on 16 //Output:on 17 //------------------------------- 18 void Eeprom_Locked(void) 19 { 20 IAP_CONTR = 0; //关闭IAP功能 21 IAP_CMD = 0; //清除命令到待机状态 22 IAP_TRIG = 0; //清除触发寄存器 23 IAP_ADDRH = 0x80; //数据ptr指向非EEPROM区域 24 IAP_ADDRL = 0; //清除IAP地址以防止滥用 25 } 26 //------------------------------- 27 //Eeprom_Effective(配置生效) 28 //Input: on 29 //Output:on 30 //------------------------------- 31 void Eeprom_Effective(void) 32 { 33 IAP_TRIG = 0x46; //发送触发器命令1(0x46) 34 IAP_TRIG = 0xb9; //发送触发器命令2(0xb9) 35 _nop_(); //MCU将保持在此处,直到ISP / IAP / EEPROM操作完成 36 } 37 //------------------------------- 38 //EEPROM区域读取一个字节 39 //Input: addr 16位EEPROM地址 40 //Output:on 41 //------------------------------- 42 unsigned char EEPROM_Read_Byte(unsigned int addr) 43 { 44 unsigned char dat; //数据缓冲区 45 Eeprom_Unlock(); 46 IAP_CMD = EEPROM_CMD_READ; //设置ISP / IAP / EEPROM READ命令 47 IAP_ADDRL = addr; //将ISP / IAP / EEPROM地址低8位设置 48 IAP_ADDRH = addr >> 8; //将ISP / IAP / EEPROM地址高8位设置 49 Eeprom_Effective(); //生效 50 dat = IAP_DATA; //读取ISP / IAP / EEPROM数据 51 Eeprom_Locked(); //关闭ISP / IAP / EEPROM功能 52 return dat; //返回Flash数据 53 } 54 //------------------------------- 55 //将一个字节编程到EEPROM区域 56 //Input: addr 16位EEPROM地址 57 // value 8位数据 58 //Output:on 59 //------------------------------- 60 void EEPROM_Write_Byte(unsigned int addr, unsigned char value) 61 { 62 Eeprom_Unlock(); 63 IAP_CMD = EEPROM_CMD_PROGRAM; //设置EEPROM PROGRAM命令 64 IAP_ADDRL = addr; //将EEPROM地址低8位设置 65 IAP_ADDRH = addr >> 8; //将EEPROM地址高8位设置 66 IAP_DATA = value; //数据写入寄存器 67 Eeprom_Effective(); //生效 68 Eeprom_Locked(); 69 } 70 //------------------------------- 71 //擦除EEPROM一个扇区 72 //Input: addr 16位EEPROM地址 73 //Output:on 74 //------------------------------- 75 void EEPROM_Erase_sector(unsigned int addr) 76 { 77 Eeprom_Unlock(); 78 IAP_CMD = EEPROM_CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command 79 IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low 80 IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high 81 Eeprom_Effective(); //生效 82 Eeprom_Locked(); 83 } 84 //------------------------------- 85 //读取指定地址数据 86 //Input: Sector 扇区编号 87 // position 扇区内相对地址 88 //Output:指定位置的数据 89 //------------------------------- 90 unsigned char EEPROM_assign_Read(unsigned char Sector,unsigned int position){ 91 return EEPROM_Read_Byte(EEPROM_Start_ADDRESS + Sector*Sector_size + position); 92 } 93 //------------------------------- 94 //写入指定地址数据 95 //Input: Sector 扇区编号 96 // position 扇区内相对地址 97 // value 写入指定位置的数据 98 //Output:on 99 //------------------------------- 100 void EEPROM_assign_Write(unsigned char Sector,unsigned int position,unsigned char value){ 101 EEPROM_Write_Byte(EEPROM_Start_ADDRESS + Sector*Sector_size + position,value); //鉴定是否需要擦除 102 } 103 /*--------------------------------------------------------------------*/ 104 //------------------------------- 105 //写入指定地址数据 106 //Input: Evalue EEPROM读取的数据 107 // value 新的数据 108 //Output:0 符合,直接写入 109 // 1要进行数据处理 110 //------------------------------- 111 bit Compared(unsigned char Evalue,unsigned char value){ 112 unsigned char i; 113 unsigned char date = 0; 114 bit Ev; 115 bit V; 116 for(i = 0; i < 8; i++){ 117 Ev = (Evalue & (0x01 << i)); 118 V = (value & (0x01 << i)); 119 if((Ev == 0)&&(V == 1))return 1; 120 } 121 return 0; 122 } 123 //------------------------------- 124 //stc 读取指定地址数据 125 //Input: Sector 扇区编号 126 // position 扇区内相对地址 127 //Output:指定位置的数据 128 //------------------------------- 129 unsigned char STC_EEPROM_assign_Read(unsigned char Sector,unsigned int position){ 130 return EEPROM_assign_Read(Sector,position); 131 } 132 //stc 写入指定地址数据(根据STC单片机特点,对EEPROM写入进行特别的处理) 133 void SCT_EEPROM_assign_Write(unsigned char Sector,unsigned int position,unsigned char value){ 134 int count; 135 if(0 == Compared(STC_EEPROM_assign_Read(Sector,position),value))EEPROM_assign_Write(Sector,position,value); //鉴定是否需要擦除 136 else { 137 EEPROM_Erase_sector(EEPROM_buf_ADDRESS); //清洗EEPROM缓存区 138 for(count = 0; count < Sector_size;count++){ 139 if(position == count)EEPROM_Write_Byte( EEPROM_buf_ADDRESS+position,value); //替换数据 140 else EEPROM_Write_Byte(EEPROM_buf_ADDRESS + count,EEPROM_assign_Read(Sector,count)); //复制数据 141 } 142 EEPROM_Erase_sector(EEPROM_Start_ADDRESS + Sector*Sector_size); //擦除一个扇区(起始地址) 143 for(count = 0; count < Sector_size;count++)EEPROM_assign_Write(Sector,count,EEPROM_Read_Byte(EEPROM_buf_ADDRESS + count)); 144 } 145 }
eeprom.h
1 /*-------------------------------------------------------------------------- 2 eeprom.h 3 4 --------------------------------------------------------------------------*/ 5 6 #ifndef __EEPROM_H__ 7 #define __EEPROM_H__ 8 #include "intrins.h" 9 10 /*声明与IAP相关的SFR寄存器 */ 11 sfr IAP_DATA = 0xE2; //闪存数据寄存器 12 sfr IAP_ADDRH = 0xE3; //Flash地址为HIGH 13 sfr IAP_ADDRL = 0xE4; //Flash地址为LOW 14 sfr IAP_CMD = 0xE5; //Flash命令寄存器 15 sfr IAP_TRIG = 0xE6; //Flash命令触发器 16 sfr IAP_CONTR = 0xE7; //闪存控制寄存器 17 /*宏定义 ISP/IAP/EEPROM 命令*/ 18 #define EEPROM_CMD_IDLE 0 //支持 19 #define EEPROM_CMD_READ 1 //字节读 20 #define EEPROM_CMD_PROGRAM 2 //字节编程 21 #define EEPROM_CMD_ERASE 3 //扇区擦除 22 /*IAP_CONTR定义ISP / IAP / EEPROM 时钟操作常量*/ 23 #define EEPROM_ENABLE_IAP 0x80 //开启IAP功能 24 //Clock 时钟配置 25 #define Clock_20M_40M 0x00 //if SYSCLK<40MHz 26 #define Clock_10M_20M 0x01 //if SYSCLK<20MHz 27 #define Clock_5M_10M 0x02 //if SYSCLK<10MHz 28 #define Clock_0M_5M 0x03 //if SYSCLK<5MHz 29 //EEPROM的起始地址 30 #define EEPROM_BASE_ADDRESS 0x0000 31 #define STC89x51_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x01000 //STC89C/LE51 32 #define STC89x52_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x02000 //STC89C/LE52 33 #define STC89x53_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x03000 //STC89C/LE53 34 #define STC89x54_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x04000 //STC89C/LE54 35 #define STC89x58_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x08000 //STC89C/LE58 36 #define STC89x510_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x0A000 //STC89C/LE510 37 #define STC89x512_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x0C000 //STC89C/LE512 38 #define STC89x514_EEPROM_Start_ADDRESS EEPROM_BASE_ADDRESS+0x0E000 //STC89C/LE514 39 //EEPROM SIZE 40 #define Sector_size 0x0200 41 #define STC89x51_EEPROM_Sector_Number 18 42 #define STC89x52_EEPROM_Sector_Number 10 43 #define STC89x53_EEPROM_Sector_Number 4 44 #define STC89x54_EEPROM_Sector_Number 90 45 #define STC89x58_EEPROM_Sector_Number 58 46 #define STC89x510_EEPROM_Sector_Number 44 47 #define STC89x512_EEPROM_Sector_Number 28 48 #define STC89x514_EEPROM_Sector_Number 12 49 //EEPROM end 50 #define STC89x51_EEPROM_End_ADDRESS STC89x51_EEPROM_Start_ADDRESS+Sector_size*(STC89x51_EEPROM_Sector_Number)-1 51 #define STC89x52_EEPROM_End_ADDRESS STC89x52_EEPROM_Start_ADDRESS+Sector_size*(STC89x52_EEPROM_Sector_Number)-1 52 #define STC89x53_EEPROM_End_ADDRESS STC89x53_EEPROM_Start_ADDRESS+Sector_size*(STC89x53_EEPROM_Sector_Number)-1 53 #define STC89x54_EEPROM_End_ADDRESS STC89x54_EEPROM_Start_ADDRESS+Sector_size*(STC89x54_EEPROM_Sector_Number)-1 54 #define STC89x58_EEPROM_End_ADDRESS STC89x58_EEPROM_Start_ADDRESS+Sector_size*(STC89x58_EEPROM_Sector_Number)-1 55 #define STC89x510_EEPROM_End_ADDRESS STC89x510_EEPROM_Start_ADDRESS+Sector_size*(STC89x510_EEPROM_Sector_Number)-1 56 #define STC89x512_EEPROM_End_ADDRESS STC89x512_EEPROM_Start_ADDRESS+Sector_size*(STC89x512_EEPROM_Sector_Number)-1 57 #define STC89x514_EEPROM_End_ADDRESS STC89x514_EEPROM_Start_ADDRESS+Sector_size*(STC89x514_EEPROM_Sector_Number)-1 58 59 /*-----------set eeprom parameter-----------*/ 60 #define ENABLE_EEPROM EEPROM_ENABLE_IAP+Clock_10M_20M //开启IAP,配置时钟 61 #define EEPROM_Start_ADDRESS STC89x52_EEPROM_Start_ADDRESS //eeprom起始地址 62 #define EEPROM_buf_ADDRESS STC89x52_EEPROM_Start_ADDRESS + Sector_size*(STC89x52_EEPROM_Sector_Number -1) //eeprom起始地址 63 #define EEPROM_end_ADDRESS STC89x52_EEPROM_End_ADDRESS //eeprom结束地址 64 /*----------------函数-----------------*/ 65 /*-----------eeprom------------*/ 66 //Eeprom_Unlock(解锁) 67 void Eeprom_Unlock(void); 68 //Eeprom_Locked(上锁) 69 void Eeprom_Locked(void); 70 //Eeprom_Effective(配置生效) 71 void Eeprom_Effective(void); 72 //EEPROM区域读取一个字节 73 unsigned char EEPROM_Read_Byte(unsigned int addr); 74 //将一个字节编程到EEPROM区域 75 void EEPROM_Write_Byte(unsigned int addr, unsigned char dat); 76 //擦除一个扇区 77 void EEPROM_Erase_sector(unsigned int addr); 78 //读取指定地址数据 79 unsigned char EEPROM_assign_Read(unsigned char Sector,unsigned int position); 80 //写入指定地址数据 81 void EEPROM_assign_Write(unsigned char Sector,unsigned int position,unsigned char value); 82 /************************************************************/ 83 //字节对比 84 bit Compared(unsigned char Evalue,unsigned char value); 85 //stc 读取指定地址数据 86 unsigned char STC_EEPROM_assign_Read(unsigned char Sector,unsigned int position); 87 //stc 写入指定地址数据 88 void SCT_EEPROM_assign_Write(unsigned char Sector,unsigned int position,unsigned char value); 89 90 91 #endif
main.c
1 #include <STC89C5xRC.H> 2 #include "eeprom.h" 3 4 # define LEDALL P1 5 6 void Delay(int n){ 7 unsigned int x; 8 while (n--) { 9 x = 0; 10 while (++x); 11 } 12 } 13 14 void main(){ 15 char i; 16 unsigned char temp,temp0,temp1; 17 while (1){ 18 for(i=0; i<4; i++){ 19 temp0 = STC_EEPROM_assign_Read(0,0); 20 temp1 = STC_EEPROM_assign_Read(0,1); 21 temp = (temp0 %16)+((temp1/16)*16); 22 LEDALL = ~temp; 23 Delay(1); 24 temp = 0x11<<i; 25 temp0 = temp %16; 26 temp1 = (temp / 16)*16; 27 SCT_EEPROM_assign_Write(0,0,temp0); 28 SCT_EEPROM_assign_Write(0,1,temp1); 29 temp = 0; 30 } 31 } 32 }