打印
[PIC®/AVR®/dsPIC®产品]

PIC18F66K80不能写入EEPROM

[复制链接]
2849|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuyanlbg|  楼主 | 2017-4-8 14:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
初次用PIC18F66K80这款单片机,写入一个简单的数进入EEPROM,然后再读出来,点亮LED灯。发现EEPROM里面的值没有变化,读出来还是0XFF的值,请高手指点,谢谢!用的晶振是16M,采用4倍频。程序如下:

void WriteEEprom(unsigned int EEaddr,unsigned char WEEdata)
{
    char GIE_BIT_VAL = 0;
    do{}
    while(EECON1bits.WR);
    EEADRH  =  ((unsigned char)(EEaddr>>8))&0X03;
    EEADR   =  (unsigned char)(EEaddr&0X00FF);
    EEDATA  =  WEEdata;
    EECON1bits.EEPGD  =  0;
    EECON1bits.CFGS   =  0;
    EECON1bits.WREN   =  1;
    GIE_BIT_VAL = INTCONbits.GIE;
    INTCONbits.GIE  =  0;
    EECON2  =  0X55;
    Nop();
    Nop();
    Nop();
    EECON2  =  0XAA;
    EECON1bits.WR     =  1;
    do{}
    while(EECON1bits.WR);
    Nop();
    Nop();
    Nop();
    INTCONbits.GIE  =  GIE_BIT_VAL;
    EECON1bits.WREN  =  0;
}
unsigned char ReadEEprom(unsigned int EEaddr)
{
    do{}
    while(EECON1bits.RD);
    EEADRH  =  ((unsigned char)(EEaddr>>8))&0X03;
    EEADR   =  (unsigned char)(EEaddr&0X00FF);
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS  = 0;
    EECON1bits.RD    = 1;
    do{}
    while(EECON1bits.RD);
    Nop();
    Nop();
    Nop();
    return (EEDATA);
}
void main(void)
{
     #pragma config CONFIG1L = 0X10;    //仅使用主时钟
     #pragma config CONFIG1H = 0X12;    //4倍频,振荡器为HS
     #pragma config CONFIG2L = 0X00;    //禁止欠压复位
     #pragma config CONFIG2H = 0X3A;    //看门狗定时65.5s
     #pragma config CONFIG3H = 0X80;    //使能/MCLR
     #pragma config CONFIG4L = 0X00;    //RB6和RB7只能用于调试
     #pragma config CONFIG5L = 0X00;    //BLOCK受代码保护
     #pragma config CONFIG5H = 0X00;    //EEPROM受代码保护
     #pragma config CONFIG6L = 0X00;    //BLOCK受写保护
     #pragma config CONFIG6H = 0X00;    //EEPROM受写保护
     #pragma config CONFIG7L = 0X00;    //禁止BLOCK读操作
     #pragma config CONFIG7H = 0X00;    //禁止引导区执行表读操作
while(1)
     {
          unsigned int i = 0;
          CLRWDT();
          WriteEEprom(0X0000,0X01);
          i = ReadEEprom(0X0000);
          if(i == 0X01)
             bLED_LOOP = 0;                   //LED灯亮
     }
}
沙发
yangzj1974| | 2018-2-13 15:34 | 只看该作者

使用特权

评论回复
板凳
QQ826220679| | 2019-1-27 12:34 | 只看该作者
对于PIC18f26K22、46K80相似芯片,内部有1024字节EEPROM,只有XC8 1.34及以前例如1.33版本能用eeprom_read(addr),及eeprom_write(addr,dat),能读写EEPROM ,并且能读写至1023地址。

其他版本XC8,如1.36,1.37,1.38,经实验不能读写!

个人经验总结!

使用特权

评论回复
地板
systemchip| | 2019-1-27 21:17 | 只看该作者
XC8版本已经是二字头了

使用特权

评论回复
5
vcvfvgvb| | 2019-1-28 13:47 | 只看该作者
没用过这个系列的EEPROM。。。

使用特权

评论回复
6
CoolSilicon| | 2019-2-13 09:51 | 只看该作者
   EECON2  =  0X55;
    Nop();
    Nop();
    Nop();
    EECON2  =  0XAA;

这个是解锁序列, 你如果仔细看datasheet,会发现, 明确有要求说解锁序列是连续的, 不能被打断, 你这里还加这么多nop...
初步看起来这个地方的问题最大...其实,可以用MCC自动生成的FLASH/E2PROM的代码, 简单又实用...

ps. 操作FLASH/E2PROM根编译器版本没多大关系, 主要是对原理理解了, 编译出来的代码都不会有问题的.

The write will not begin if this sequence is not exactly
followed (write 55h to EECON2, write 0AAh to
EECON2, then set WR bit) for each byte. It is strongly
recommended that interrupts be disabled during this
code segment.



使用特权

评论回复
7
repairamp| | 2019-7-17 20:42 | 只看该作者
有没有试过不用倍频的配置看看

使用特权

评论回复
8
sxswt| | 2019-7-18 08:57 | 只看该作者
MCC生成的。
void DATAEE_WriteByte(uint16_t bAdd, uint8_t bData)
{
    uint8_t GIEBitValue = INTCONbits.GIE;

    EEADRH = ((bAdd >> 8) & 0x03);
    EEADR = (bAdd & 0xFF);
    EEDATA = bData;
    EECON1bits.EEPGD = 0;
    EECON1bits.CFGS = 0;
    EECON1bits.WREN = 1;
    INTCONbits.GIE = 0;     // Disable interrupts
    EECON2 = 0x55;
    EECON2 = 0xAA;
    EECON1bits.WR = 1;
    // Wait for write to complete
    while (EECON1bits.WR)
    {
    }

    EECON1bits.WREN = 0;
    INTCONbits.GIE = GIEBitValue;   // restore interrupt enable
}

uint8_t DATAEE_ReadByte(uint16_t bAdd)
{
    EEADRH = ((bAdd >> 8) & 0x03);
    EEADR = (bAdd & 0xFF);
    EECON1bits.CFGS = 0;
    EECON1bits.EEPGD = 0;
    EECON1bits.RD = 1;
    NOP();  // NOPs may be required for latency at high frequencies
    NOP();

    return (EEDATA);
}

使用特权

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

本版积分规则

37

主题

59

帖子

0

粉丝