单片机成长之路(51基础篇) - 017 STC89C51系列单片机 内部EEPROM 驱动

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 }



猜你喜欢

转载自www.cnblogs.com/jikexianfeng/p/10672150.html