EDN首页   博客首页

日志档案

发表于 2008-7-9 23:35:12

1

标签: PIC  FLASH  

PIC18F系列读写FLASH的函数

网上搜了一下,关于PIC18F系列读写FLASH的函数,有很多都是有错误的或者有BUG的,集中在表指针的操作上.

 

因此走了些弯路,现在发一个我自己写的读写FLASH的函数分享给大家,已测试过,支持绝大部分PIC18F系列的芯片.

 

还有一个是写"1字节"的函数,写几个字节的时候很有用.有人一定会反驳说写操作不是按64个字节块来执行的吗?确实是,下边已经给出注释了.

 

以下是写函数的部分代码:

#define addr 0x400   //定义要写入的起始地址

//写周期
void Write_Cycle(void)
{
 EEPGD = 1;    //EEPGD:闪存程序存储器或数据EEPROM 选择位
                         //1 = 访问闪速程序存储器
                         //0 = 访问数据EEPROM
 CFGS = 0;      //CFGS:闪存程序存储器/ 数据EEPROM 或配置寄存器选择位
                         //1 = 访问配置寄存器
                         //0 = 访问闪存程序存储器或数据EEPROM
 WREN = 1;    //WREN:闪存程序/ 数据EEPROM 写使能位
                         //1 = 允许闪存程序/ 数据EEPROM 的写周期
                         //0 = 禁止闪存程序/ 数据EEPROM 的写周期
 CARRY = 0;
 if(GIE)
    CARRY = 1;
 GIE = 0;         //关全局中断
 EECON2 = 0X55;
 EECON2 = 0XAA;
 WR = 1;        //1 启动读/写周期;0 写周期完成
 NOP();
 NOP();
 while(WR) ;  //等待写周期完成
 WREN = 0;    //0 禁止向程序存储器或EEPROM写操作

 if(CARRY)
      GIE = 1;     //IPEN=1,开中断
}

//器件复位时和写操作后保持寄存器的默认
//值为FFh。向保持寄存器写入FFh 并不会
//修改寄存器中存储的字节。这意味着,假如
//不想将某个位从0 改为1,而仅修改程序存
//储器中的个别字节也是可以的。当修改个
//别字节时,在执行写操作前不必装入所有
//的64 个保持寄存器。

 

//写函数,每次写入FLASH是1个字节
void Write_One_Byte(unsigned long address,unsigned char data)
{
     TBLPTRL = ((address) & 0xFF);
     TBLPTRH = (((address) >> 8) & 0xFF);
     TBLPTRU = (((address) >> 8) >> 8);

    TABLAT = data;
    asm("\tTBLWT*");

    FREE = 0;          //只执行写操作
    Write_Cycle();
}

//写函数,每次写入FLASH只能是64字节,故要写入大量数据的话,就需要多次写入
void Flash_Write(unsigned long address,unsigned char *Pdata)
{
 unsigned char count;
 unsigned char length; 

 Flash_Erase(address);     //擦除64个字节

 for(count=0; count<8; count++)    //写8次,8*8=64
 {
      TBLPTRL = ((address+count*8) & 0xFF);  //地址载入TBLPTR
      TBLPTRH = (((address+count*8) >> 8) & 0xFF);
      TBLPTRU = (((address+count*8) >> 8) >> 8);

  for(length=0; length<8; length++)    //写8字节到RAM
  {
     TABLAT = *(Pdata+length+count*8); //数据载入TABLAT
     if(length != 0)     
    {
        asm("\tTBLWT+*");  //TBLPTR需要预先增加   
     }
     else
     {
       asm("\tTBLWT*");  //地址已经载入TBLPTR,不需要预先增加   
      }
   }

    FREE = 0;       //只执行写操作
    Write_Cycle();
 }
}

void main(void)
{   
 Write_One_Byte(addr-1, 0xaa);
 Flash_Write(addr, &data[0]);
 while(1)
 {
  temp = Flash_Read(addr-1);
 }
}

 

MPLAB SIM仿真结果,其中地址0x3ff中的数据:0xaa就是用"写1字节"函数写上去的.

 

附件内含两个工程,一个是用PICC18编译器的,一个是MCC18编译器的.

 

再送大家一个CleanUp.bat,可以用来清除编译器产生的一些链接文件之类的,很好用.

附件下载地址:点击下载

系统分类: 单片机   |   用户分类: PIC单片机   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(224)    回复(0)  

投一票您将和博主都有获奖机会!