打印

PIC学习贴之-PIC24 操作内部EEPROM!

[复制链接]
7134|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Ryanhsiung 于 2012-3-28 19:06 编辑

看了一上午文档,都要先定义EEPROM变量后才能进行相应操作。24系列与18系列不一样,我看了看DATASHEET,EEPROM应该是用FLASH来实现的,只是将FLASH擦出实现了单个字,双字、4字擦出了!
看了一上午文档,都要先定义EEPROM变量后才能进行相应操作。

// 必须定义EEPROM 数据变量
int __attribute__ ( (space(eedata))) eeData = 0x9632;
// 再用下面的函数进行操作_write_eedata_word  
__builtin_tblpage
__builtin_tblwtl     

我不想定义,我就想你PIC18直接按地址操作!
  后面继续看文档,要操作TBLPAG,W才能实现地址操作,但在C中操作W是一个不安全的动作。(编译器一直提示这个问题),我也想了想,我也不知道其它函数会不会操作到特定的W,若要操作到不就挂了。
  后就找到一个间接的方法,

        uint16_t offset;               
        NVMCON = 0x4058;
        TBLPAG = 0x007f;
        offset = 0xfe00+ee_addr;
        __builtin_tblwtl(offset, 0);   

再分享一个DSPIC30的EEPROM文档及源码。

QQ截图未命名.jpg (101.01 KB )

QQ截图未命名.jpg

dsPIC EEPROM Module.pdf

342.22 KB

dsPIC EEPROM Module.rar

113.74 KB

沙发
yewuyi| | 2012-3-27 11:20 | 只看该作者
用的库函数?

呵呵,俺都是自己写的EEPROM读写函数,库函数容易导致独占CPU连续操作EEPROM,如果不了解这个,则你的其它任务就安排不下去了。

使用特权

评论回复
板凳
Ryanhsiung|  楼主 | 2012-3-27 14:10 | 只看该作者
用的库函数?

呵呵,俺都是自己写的EEPROM读写函数,库函数容易导致独占CPU连续操作EEPROM,如果不了解这个,则你的其它任务就安排不下去了。
yewuyi 发表于 2012-3-27 11:20

自己怎么写,贴段段代码看看!
  可以说是第一次使用24系列单片机,有些和18 16的不一样,还不知道怎么下手!!

使用特权

评论回复
地板
yewuyi| | 2012-3-27 14:21 | 只看该作者
俺没有24系列的代码。

基本道理不管是啥系列的,还不都是一样的吗!!!?

自己对着DATASHEET看一下就应该很容易写出来了,连个内部模块都搞不定,很容易让人鄙视的。

使用特权

评论回复
5
Ryanhsiung|  楼主 | 2012-3-28 19:07 | 只看该作者
先前为求例程,现更新为实现方法及分享资料

使用特权

评论回复
6
ailingg| | 2016-9-4 21:29 | 只看该作者
本帖最后由 ailingg 于 2016-9-5 12:04 编辑

根据楼主的资料终于弄懂了eeprom的操作,原来用c30内建函数 _builtin tblwtl 一直迷迷糊糊,原因是不懂汇编,汇编挺妙但难懂啊。根据楼主资料把我原来的eeprom操作函数给改了,如下:

/************************************************************************************
* 模 块:EEPROM字数据串写入
* 输 入:pSource源数组,ee_addr数据在eeprom中的偏移地址
* 输 出:一次字数据串连续写完成返回1
* 说 明:
*************************************************************************************/
UINT8 eepromStrWrite( UINT16 *pSource, UINT16 ee_addr, UINT8 len)
{
    static UINT16 offset;
    static UINT8 Length = 0;
    static UINT8 Index = 0;
    static UINT8 StrWriteInit = NEVER;
   
    if( StrWriteInit == NEVER )                  // 字数据串连续写入时EEPROM地址的初始化
    {
        StrWriteInit = ALREADY;
        EEbits.WritePermit = YES;
        Length = len;        
        NVMCONbits.NVMOP = 0b00100;              // 非易失性存储器编程控制寄存器,一次写入一个字
        NVMCONbits.WREN = 1;                     // 写使能
        IEC0bits.NVMIE = 1;
        TBLPAG = EEADDR_PAGE;                    // 根据器件数据手册定义EEPROM页地址,通常是固定的0x007F
        offset = EEADDR_BASE + ee_addr;          // 根据器件数据手册定义EEPROM 24位地址的低16位,p24F16KLxx 256字EEPROM的低16位地址从0xFE00开始   
    }
    if(  EEbits.WritePermit == YES )
    {
        EEbits.WritePermit = NO;
        if( Length > 0 )
        {
            Length--;
            PUSH_WREG6_WREG7;                   // 寄存器入栈保护
            WREG6 = pSource[Index++];           // set the source register W6 to the desired word to write
            WREG7 = offset;                     // set the destination pointer W7 for programming
            offset += 2;
            asm( "tblwtl.w w6,[w7]" );          // tblwtl load the one write latch
            asm volatile ("disi #10" );         // Disable Interrupt 10 Tcy
            UNLOCK_NVM_AND_PROGRAM;             // now do the programming operation
            POP_WREG7_WREG6;                    // 寄存器出栈,后入先出
        }
        else  // 数据串写完返回1            
        {
            Index = 0;
            StrWriteInit = NEVER;
            IEC0bits.NVMIE = 0;
            return 1;
        }
    }
    return 0;
}

/*******************************************************************************************
* 模 块:eeprom写入中断
* ****************************************************************************************/
void __attribute__((interrupt, shadow, no_auto_psv)) _NVMWriteInterrupt(void)
{
    IFS0bits.NVMIF = 0;
    EEbits.WritePermit = YES;
}

楼主的资料里的出栈顺序反了,烧写后不停复位

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:道阻且长,行则将至!

64

主题

4653

帖子

14

粉丝