数据没有得到存储在EEPROM中

数据没有得到存储在EEPROM中

问题描述:

我已经使用以下代码,用于访问EEPROM:数据没有得到存储在EEPROM中

void EEPROM_write(unsigned int uiAddress,unsigned char ucData) 
{ 
  while(EECR & (1<<EEWE)) 
   { 
       //do nothing 
   } 

   while(SPMCR & (1<<SPMEN)); 
  EEAR = uiAddress; 
   EEDR = ucData; 
   EECR |= (1<<EEMWE); 
   EECR |= (1<<EEWE); 
} 

char EEPROM_read(unsigned int uiAddress) 
{ 
    while(EECR & (1<<EEWE)) 
   { 
       //do nothing 
   } 

  EEAR = uiAddress; 
   EECR |=(1<<EERE); 
   return EEDR; 
} 

void EEPROM_write_str(unsigned int uiAddress,unsigned char* string,unsigned int size) 
{ 
    int i; 
   for(i=0;i<size;i++) 
  { 
       EEPROM_write(uiAddress+i,string[i]); 
   } 
} 

void EEPROM_read_str(unsigned int uiAddress,unsigned char* string,unsigned int size) 
{ 
    int i; 
  for(i=0;i<size;i++) 
   { 
       string[i] = EEPROM_read(uiAddress+i); 
   } 
} 

char str[]="hello "; 
char str2[20]; 

int main() 
{ 
    usart_init(12); 
  //EEPROM_write_str(0,str,6); 
   EEPROM_read_str(0,str2,6); 
   usart_puts(str2,6); 
} 

在上面的代码中,我第一评论的EEPROM_read_str和usart_puts,...闪蒸它然后评论的EEPROM_write_str功能和删除了另外两个人的评论,然后再次闪现。尽管如此,数据并未被存储,并且终端中显示的输出为yyyyy(十六进制FF)。 这里有什么问题? (这里USART_puts以第二个参数作为字符数发送字符串)

+0

在地址0有eeprom吗?在写入之前在哪里擦除eeprom? – Lundin

+0

@Lundin它是在地址为0到1023的EEPROM我猜 – user102958

+0

@Lundin AVR-s是Hardvare架构,所有存储器都有独立的地址空间。 AVR可以在写入期间选择它。单元格被擦除并一次写入。它被atmel称为“原子eeprom写” –

我的旧avr项目的工作代码。我不使用他们多年来如此规定的,正如我不记得位的确切含义,现在

void EEPROM_write(uint8_t addr, uint8_t value) { 
    while(EECR & (1 << EEPE)) ;    //wait for write enable bit to clear 
    EECR &= ~((1 << EEPM1) | (1 << EEPM0)); // (erase & write in one operation) 
    EEARL = addr;       // set the address 
    EEDR = value;       // set value to be written 
    EECR |= (1 << EEMPE);      // set EEPROM Master Write Enable 
    EECR |= (1 << EEPE);      // set EEPROM Master Write Enable 
} 

uint8_t EEPROM_read(uint8_t addr) { 
    while(EECR & (1 << EEPE)) ;    
    EEARL = addr;       // set the address 
    EECR |= (1 << EERE); 
    return EEDR; 
} 
+0

问题不存在....当我一次执行写操作和读操作时,数据返回相同,但是,重置控制器会导致擦除数据... – user102958

+0

此代码用于售出十万台设备 - 并始终保持其价值。第一个字节非常复杂 - 有时在某些系列的uC上被破坏(不同的批次可以不行),所以要避免第一个字节,并记住关于功耗的问题。 –

+0

尝试我的一个奇怪的话然后 –

这是从源代码配套文件为AVR103 AVR EEPROM Application Note,从设备制造商的权威刊物。

char EEPROM_GetChar(unsigned int addr) 
{ 
    do {} while(EECR & (1<<EEPE)); // Wait for completion of previous write. 
    EEAR = addr; // Set EEPROM address register. 
    EECR = (1<<EERE); // Start EEPROM read operation. 
    return EEDR; // Return the byte read from EEPROM. 
} 


void EEPROM_PutChar(unsigned int addr, char new_value) 
{ 
    char old_value; // Old EEPROM value. 
    char diff_mask; // Difference mask, i.e. old value XOR new value. 

    unsigned char old_interrupt; // Stores interrupt flag while programming. 
    old_interrupt = __save_interrupt(); // Save interrupt flag state. 
    __disable_interrupt(); // Ensure atomic operation for the write operation. 

    do {} while(EECR & (1<<EEPE)); // Wait for completion of previous write. 
    #ifndef EEPROM_IGNORE_SELFPROG 
    do {} while(SPMCSR & (1<<SELFPRGEN)); // Wait for completion of SPM. 
    #endif 

    EEAR = addr; // Set EEPROM address register. 
    EECR = (1<<EERE); // Start EEPROM read operation. 
    old_value = EEDR; // Get old EEPROM value. 
    diff_mask = old_value^new_value; // Get bit differences. 

    // Check if any bits are changed to '1' in the new value. 
    if(diff_mask & new_value) { 
     // Now we know that _some_ bits need to be erased to '1'. 

     // Check if any bits in the new value are '0'. 
     if(new_value != 0xff) { 
      // Now we know that some bits need to be programmed to '0' also. 

      EEDR = new_value; // Set EEPROM data register. 
      EECR = (1<<EEMPE) | // Set Master Write Enable bit... 
        (0<<EEPM1) | (0<<EEPM0); // ...and Erase+Write mode. 
      EECR |= (1<<EEPE); // Start Erase+Write operation. 
     } else { 
      // Now we know that all bits should be erased. 

      EECR = (1<<EEMPE) | // Set Master Write Enable bit... 
        (1<<EEPM0); // ...and Erase-only mode. 
      EECR |= (1<<EEPE); // Start Erase-only operation. 
     } 
    } else { 
     // Now we know that _no_ bits need to be erased to '1'. 

     // Check if any bits are changed from '1' in the old value. 
     if(diff_mask) { 
      // Now we know that _some_ bits need to the programmed to '0'. 

      EEDR = new_value; // Set EEPROM data register. 
      EECR = (1<<EEMPE) | // Set Master Write Enable bit... 
        (1<<EEPM1); // ...and Write-only mode. 
      EECR |= (1<<EEPE); // Start Write-only operation. 
     } 
    } 

    __restore_interrupt(old_interrupt); // Restore interrupt flag state. 
} 


void main() 
{ 
    char t; // Temporary byte. 
    unsigned int addr = 0x10; // EEPROM address to use. 

    // Test the EEPROM_GetChar() function. 
    t = EEPROM_GetChar(addr); 

    // Try erasing the whole byte. 
    EEPROM_PutChar(addr, 0xff); 

    // Try changing a few bits to '0'. 
    EEPROM_PutChar(addr, 0x0f); 

    // Try changing bits both ways. 
    EEPROM_PutChar(addr, 0xf0); 

    // Try changing nothing. 
    EEPROM_PutChar(addr, 0xf0); 

    // Restore old value. 
    EEPROM_PutChar(addr, t); 

    for(;;); // Loop forever. 
} 
+0

我的编译器(atmel studio 7)将EEMPE显示为错误....它理解较早的命令(EEMWE) – user102958

+0

该文档很早以前就已经写入,并且一些寄存器名称在较新的AVR部分中可能略有更改。请检查您的零件数据表以了解当前的注册名称。但请放心,算法保持不变。 – TomServo