单片机读写EEPROM例子

eeprom.c

#ifndef _EEPROM_H_
#define _EEPROM_H_
 
#include <intrins.h>
#include <reg52.h>

 
typedef  unsigned int uint;
typedef  unsigned char uchar;
 
/********STC89C52扇区分布*******
第一扇区:2000H--21FF
第二扇区:2200H--23FF
第三扇区:2400H--25FF
第四扇区:2600H--27FF
第五扇区:2800H--29FF
第六扇区:2A00H--2BFF
第七扇区:2C00H--2DFF
第八扇区:2E00H--2FFF
*******************************/
 
#define RdCommand 0x01     //字节编程数据命令   
#define PrgCommand 0x02    //字节读数据命令   
#define EraseCommand 0x03  //扇区擦除数据命令
 
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定义CPU的等待时间,40M以下为0,20M以下为1,10M以下为2,5M以下为3
 
/*****ISP/IAP特殊功能寄存器声明********/    
sfr ISP_DATA = 0xE2;
sfr ISP_ADDRH = 0xE3;
sfr ISP_ADDRL = 0xE4;
sfr ISP_CMD = 0xE5;
sfr ISP_TRIG = 0xE6;
sfr ISP_CONTR = 0xE7;
 
 
unsigned char byte_read(unsigned int byte_addr);
void byte_write(unsigned int byte_addr,unsigned char Orig_data);
void SectorErase(unsigned int sector_addr);
 
#endif

eeprom.c

#include "eeprom.h"
 
/**********打开ISP/IAP功能**************/   
void ISP_IAP_Enable(void)
{
    EA = 0;  //关中断  
    ISP_CONTR = ISP_CONTR & 0x18;  
    ISP_CONTR = ISP_CONTR | WaitTime; // 设置等待时间
    ISP_CONTR = ISP_CONTR | 0x80;   //允许ISP/IAP操作
}
 
/**********关闭ISP/IAP功能**************/   
void ISP_IAP_Disable(void)
{
     ISP_CONTR = ISP_CONTR & 0x7f; //禁止ISP/IAP操作
     ISP_CMD = 0x00;    //去除ISP/IAP命令
     ISP_TRIG = 0x00;   //防止ISP/IAP命令无触发
     EA   =   1;        // 开中断 
}
 
/**********触发ISP/IAP**************/  
void ISPTrig(void)
{
     ISP_TRIG = 0x46;  //先送46h,再送B9h到ISP/IAP触发寄存器,每次都需如此
     ISP_TRIG = 0xb9;  //送完B9h后,ISP/IAP命令立即被触发启动
     _nop_();
}
 
/**********字节读**************/
unsigned char byte_read(unsigned int byte_addr)
{
     unsigned char  dat = 0;    //读EEPROM数据缓存
 
     EA = 0;     //关中断
     ISP_ADDRH = (unsigned char)(byte_addr >> 8);     //送地址高字节
     ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff); //送地址低字节
     ISP_IAP_Enable();             //打开ISP/IAP功能
     ISP_CMD   = ISP_CMD & 0xf8;   //清除ISP_CMD寄存器低3位
     ISP_CMD   = ISP_CMD | RdCommand; //写入读数据命令 
     ISPTrig();                //触发ISP/IAP
     dat = ISP_DATA;           //将ISP_DATA寄存器中的数据保存起来
     ISP_IAP_Disable();        //关闭ISP/IAP功能 
     EA  = 1;           //使能中断
     return dat;        //返回读到的数据
}
 
/**********字节写**************/
void byte_write(unsigned int byte_addr,unsigned char Orig_data)
{
     EA  = 0;  //关中断
     ISP_ADDRH = (unsigned char)(byte_addr >> 8);       //送地址高字节
     ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);   //送地址低字节
     ISP_IAP_Enable();                   //打开ISP/IAP功能
     ISP_CMD  = ISP_CMD & 0xf8;         //清除ISP_CMD寄存器低3位
     ISP_CMD  = ISP_CMD | PrgCommand;   //写入写数据命令 
     ISP_DATA = Orig_data;      //写入数据到ISP_DATA寄存器
     ISPTrig();                //触发ISP/IAP
     ISP_IAP_Disable();        //关闭ISP/IAP功能 
     EA =1;            //使能中断
}
/**********扇区擦除**************/
void SectorErase(unsigned int sector_addr)
{
     EA = 0;   
     ISP_ADDRH = (unsigned char)(sector_addr >> 8);        //送擦除地址高字节
     ISP_ADDRL = (unsigned char)(sector_addr & 0x00ff);    //送擦除地址低字节
     ISP_IAP_Enable(); 
     ISP_CMD = ISP_CMD & 0xf8;           //清除ISP_CMD寄存器低3位
     ISP_CMD = ISP_CMD | EraseCommand;   //写入擦除数据命令
     ISPTrig();       //触发ISP/IAP
     ISP_IAP_Disable();    //关闭ISP/IAP功能 
 
}

ISP2.C

/**
  ******************************************************************************
  * @file    main.c
  * @author  waitstory
  * @version V1.0
  * @date    2018-4-11
  * @brief   STC89C52RC内部EEPROM的读写
  ******************************************************************************
  * @attention  
  *
  * 实验平台:STC89C52RC芯片,晶振11.0592MHz
  *
  ******************************************************************************
**/
 
#include <eeprom.h>
#include <absacc.h>
void InitUART(uint baud);       //串口初始化函数
void UartTXData(uchar str[]);   //串口发送函数
void Delay_ms(uint z);     //延时函数
 
uchar TxStr[3] = {1};
uchar dat[2] ={0x33,0x35};
uint ma,mb;
char id;
char *MCUID;
/********STC89C52扇区分布*******
第一扇区:2000H--21FF
第二扇区:2200H--23FF
第三扇区:2400H--25FF
第四扇区:2600H--27FF
第五扇区:2800H--29FF
第六扇区:2A00H--2BFF
第七扇区:2C00H--2DFF
第八扇区:2E00H--2FFF
*******************************/ 
 void main()
{
    
        //ma=0x2000;
    SectorErase(0x2000);    //擦除第一扇区
    byte_write(0x2001,dat[0]);   //在地址为0x2001的内存写入一个字节
    byte_write(0x2002,dat[1]);   //在地址为0x2002的内存写入一个字节
    //byte_write(0x2001,'1');   //在地址为0x2001的内存写入一个字节
    //byte_write(0x2002,'2');   //在地址为0x2002的内存写入一个字节
    Delay_ms(1000);       //延时1s
 
    InitUART(9600);         //串口初始化函数
        ma=0x2e00;
    while(1)
    { 
        TxStr[0] = byte_read(0X2001);     //从地址0x2001读取一个字节
        TxStr[1] = byte_read(0X2002);     //从地址0x2002读取一个字节
                ma=ma+2;
        UartTXData(TxStr);     //将读取的字节发送至串口
         
        Delay_ms(1000);        //延时2s
    }
 
}
 
 
/* 串口配置函数,baud-通信波特率 */
void InitUART(uint baud)
{
    EA = 1;        //使能中断总开关
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}                                 
 
/*串口发送字符串函数*/    
void UartTXData(uchar str[])
{   
    uchar i = 0;
    
    while(str[i] != '\0')
    {
        SBUF= str[i];
        i++;
        while(!TI);
        TI=0;
    }
}
 
/*延时函数*/
void Delay_ms(uint z)
{
   uint i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}

结果:

打开STC-ISP中的串口助手-打开串口,9600,单片机发送33 35,串口接收到33 35

posted @ 2021-08-19 14:59  myrj  阅读(692)  评论(0编辑  收藏  举报