单片机
返回首页

PIC之内部E2PROM的读写操作

2016-11-01 来源:eefocus

//--------------------------------------------------------

//EEPROM字节写程序
//功能: 写一个字节到内部EEPROM
//入口: EEADR =地址
// EEDATA =数据
//--------------------------------------------------------
void write_eeprom ( void )
{
// while ( WR )      //等待上一次写操作结束
// {
//   asm ('clrwdt');     //喂狗
// }
EEPGD = 0 ;       //设置访问目标为EEPROM
WREN = 1 ;      //允许进行写操作
GIE = 0 ;         //禁止中断
EECON2 = 0x55 ;
EECON2 = 0xAA ;
WR = 1 ;          //启动一次写操作
GIE = 1 ;         //使能中断
WREN = 0 ;      //关闭写操作
}

//--------------------------------------------------------
//EEPROM字节读程序
//功能: 从内部EEPROM读一个字节
//入口: EEADR =地址
//出口: EEDATA =数据
//--------------------------------------------------------
void read_eeprom( void )
{
EEPGD = 0 ;       //设置访问目标为EEPROM
RD = 1 ;         //启动一次读操作
}


//--------------------------------------------------------
//FLASH字节写程序
//功能: 写一个字节到内部FLASH
//入口: EEADRH,EEADR =地址
// EEDATH,EEDATA =数据
//--------------------------------------------------------
void write_flash ( void )
{
EEPGD = 1 ;       //设置访问目标为FLASH
WREN = 1 ;      //允许进行写操作
GIE = 0 ;         //禁止中断
EECON2 = 0x55 ;
EECON2 = 0xAA ;
WR = 1 ;          //启动一次写操作
asm ('nop') ;
asm ('nop') ;
GIE = 1 ;         //使能中断
WREN = 0 ;      //关闭写操作
}

//--------------------------------------------------------
//FLASH字节读程序
//功能: 从内部FLASH读一个字节
//入口: EEADRH,EEADR =地址
//出口: EEDATH,EEDATA =数据
//--------------------------------------------------------
void read_flash( void )
{
EEPGD = 1 ;       //设置访问目标为FLASH
RD = 1 ;         //启动一次读操作
asm ('nop') ;
asm ('nop') ;

}

这是网上找来的程序:

用我写的这个吧void WriteEE(unsigned char addr,unsigned char data)         //写EEPROM
    {
     do{;}
     while(WR==1);                         //上一次写操作是否完成
     EEADR=addr;                             //EEPROM地址
     EEDATA=data;                         //准备写入EEPROM的数据
     EEPGD=0;                             //指向EEPROM数据储存器
     WREN=1;                                 //使能写操作
     EECON2=0x55;                         //设置通用参数
     EECON2=0xAA;                         //设置通用参数
     WR=1;                                 //开始写
     do{;}
     while(WR==1);                         //等待写操作完成
     WREN=0;                                 //禁止写操作
    }
//
unsigned char ReadEE(unsigned char addr)                 //读EEPROM
    {
     unsigned char num;
     do{;}
     while(RD==1);                         //上一次读操作是否完成
     EEADR=addr;                             //EEPROM地址为00H
     EEPGD=0;                             //指向EEPROM数据储存器
     RD=1;                                 //开始读
     do{;}
     while(RD==1);                         //等待读操作完成
     num=EEDATA;                             //读出
     return(num);                         //返回读出的数
    }

说明:两个程序基本步骤是一致的。个中的差别是:

1、网上找来的这个程序中更严密,其中增加了对WR和RD标志位的判别,缺点是实时性较差。

2、而匠人的程序中没有这个对WR和RD标志位的判别。那是因为匠人将该判别的动作放在了上级程序中。也就是说,匠人在调用write_eeprom 函数之前,会先行判断WR。确信上次写操作已经结束后,才去调用新一次的写操作。这样做的目的是为了系统的实时性。

其实,事后匠人才发现自己写EEPROM读写程序,这样做是没有太大的必要的。因为在PICC系统自带“ PIC.H”文件中,已经内嵌了这两个函数。倒塌!

以下是“ PIC.H”文件中的内容:

/***********************************************************************/
/****** EEPROM memory read/write macros and function definitions *******/
/***********************************************************************/
/* NOTE WELL:

   The macro EEPROM_READ() is NOT safe to use immediately after any
   write to EEPROM, as it does NOT wait for WR to clear. This is by
   design, to allow minimal code size if a sequence of reads is
   desired. To guarantee uncorrupted writes, use the function
   eeprom_read() or insert
while(WR)continue;
   before calling EEPROM_READ().
*/
#if EEPROM_SIZE > 0
#ifdef __FLASHTYPE
// macro versions of EEPROM write and read
#define EEPROM_WRITE(addr, value) \
do{ \
while(WR)continue;EEADR=(addr);EEDATA=(value); \
EECON1&=0x7F;CARRY=0;if(GIE)CARRY=1;GIE=0; \
WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \
if(CARRY)GIE=1; \
}while(0)
#define EEPROM_READ(addr) ((EEADR=(addr)),(EECON1&=0x7F),(RD=1),EEDATA)
#else // else doesn't write flash
#define EEPROM_WRITE(addr, value) \
do{ \
while(WR)continue;EEADR=(addr);EEDATA=(value); \
CARRY=0;if(GIE)CARRY=1;GIE=0; \
WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \
if(CARRY)GIE=1; \
}while(0)
#define EEPROM_READ(addr) ((EEADR=(addr)),(RD=1),EEDATA)
#endif

/* library function versions */
extern void eeprom_write(unsigned char addr, unsigned char value);
extern unsigned char eeprom_read(unsigned char addr);
#endif // end EEPROM routines

进入单片机查看更多内容>>

上一篇:TMR0定时实验

下一篇:超声波PIC程序

相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章