EEPROM 控制寄存器- EECR | • Bits 7..4 – Res: 保留 保留位,读操作返回值为零。 • Bit 3 – EERIE: EEPROM 就绪中断使能 若SREG 的I 为"1“,则置位EERIE 使能EEPROM 就绪中断。清零EERIE 则禁止此中断。当EEWE 清零时EEPROM 就绪中断即可发生。 • Bit 2 – EEMWE: EEPROM 主机写使能 EEMWE决定设置EEWE为"1“是否可以启动EEPROM写操作。。当EEMWE为"1“时,在4个时钟周期内置位EEWE 将把数据写入EEPROM 的指定地址;若EEMWE 为"0“,则EEWE 不起作用。EEMWE 置位后4 个周期,硬件对其清零。 • Bit 1 – EEWE: EEPROM 写使能 当EEPROM 数据和地址设置好之后,需置位EEWE 以便将数据写入EEPROM。此时EEMWE必须置位,否则EEPROM写操作将不会发生。写时序如下(第3和第4步不是必须的): 1. 等待EEWE 为0。 2. 等待SPMCSR 寄存器的SPMEN 为零。 3. 将新的EEPROM 地址写入EEAR。 4. 将新的EEPROM 数据写入EEDR。 5. 对EECR 寄存器的EEMWE 写"1“,同时清零EEWE。 6. 在置位EEMWE 的4 个周期内,置位EEWE。 在CPU 写Flash 存储器的时候不能对EEPROM 进行编程。在启动EEPROM 写操作之 前软件必须要检查 Flash 写操作是否已经完成。第二步仅在软件包含引导程序,允许CPU 对Flash 进行编程时才有用。如果CPU 永远都不会写Flash,则第二步可以忽略。请参 考P 255“ 支持引导装入程序 – 在写的同时可以读(RWW, Read-While-Write) 的自我编程 能力” 。 注意: 如有中断发生于步骤5 和6 之间将导致写操作失败。因为此时EEPROM 写使能操 作将超时。如果一个操作EEPROM的中断打断了另一个EEPROM操作,EEAR 或EEDR 寄存器可能被修改,引起EEPROM 操作失败。建议此时关闭全局中断标志I。 经过写访问时间之后, EEWE 硬件清零。用户可以凭此位判断写时序是否已经完成。 EEWE 置位后, CPU 要停止两个时钟周期才会运行下一条指令。 • Bit 0 – EERE: EEPROM 读使能 当EEPROM 地址设置好之后,需置位EERE 以便将数据读入EEAR。EEPROM 数据的读取只需要一条指令,且无需等待。读取EEPROM 时CPU 要停止4 个时钟周期。 用户在读取EEPROM 时应该检测EEWE。如果一个写操作正在进行,就无法读取 EEPROM,也无法改变寄存器EEAR。 标定振荡器用于EEPROM 访问定时。Table 2 为CPU 访问EEPROM 的典型时间。 Note: 1. 使用的是1 MHz 的时钟。与熔丝位CKSEL 的设置无关。下面的代码分别用汇编和C 函数说明如何实现EEPROM 的写操作。在此假设中断不会在 执行这些函数的过程当中发生。例子同时还假设软件没有引导程序。若引导程序存在,则 EEPROM 写函数还需要等待正在进行的SPM 命令的结束。 汇编代码例程 | EEPROM_write: ; 等待上一次写操作结束 sbic EECR,EEWE rjmp EEPROM_write ; 设置地址寄存器 (r18:r17) out EEARH, r18 out EEARL, r17 ; 写数据到数据寄存器(r16) out EEDR,r16 ; 置位EEMWE sbi EECR,EEMWE ; 置位EEWE 以启动写操作 sbi EECR,EEWE ret | C 代码例程 | void EEPROM_write(unsigned int uiAddress, unsigned char ucData) { /* 等待上一次写操作结束 */ while(EECR & (1<<EEWE)) ; /* 设置地址和数据寄存器 */ EEAR = uiAddress; EEDR = ucData; /* 置位EEMWE */ EECR |= (1<<EEMWE); /* 置位EEWE 以启动写操作E */ EECR |= (1<<EEWE); } |
下一个代码例子说明如何用汇编和C来读取EEPROM在此假设中断不会在执行这些函数 的过程当中发生。 汇编代码例程 | EEPROM_read: ; 等待上一次写操作结束 sbic EECR,EEWE rjmp EEPROM_read ; 设置地址寄存器 (r18:r17) out EEARH, r18 out EEARL, r17 ; 设置EERE 以启动读操作 sbi EECR,EERE ; 自数据寄存器读取数据 in r16,EEDR ret | C 代码例程 | unsigned char EEPROM_read(unsigned int uiAddress) { /* 等待上一次写操作结束 */ while(EECR & (1<<EEWE)) ; /* 设置地址寄存器 */ EEAR = uiAddress; /* 设置EERE 以启动读操作 */ EECR |= (1<<EERE); /* 自数据寄存器返回数据 */ return EEDR; } |
|