今天看了下AVR的EEPROM,自己写了个简单的程序。
程序内容是:向EEPROM的地址从0x111开始写10个数据,然后读出来显示在数码管上。(地址范围0~511)
我用的是ICCAVR的编译器头文件有点不同。因为macros.h文件是空的并说明用AVRdef.h,所以就用啦。
写时序如下 ( 第 3 步和第 4 步的次序并不重要 ):
1. 等待 EEWE 位变为零
2. 等待 SPMCSR 中的 SPMEN 位变为零
3. 将新的 EEPROM地址写入 EEAR(可选)
4. 将新的 EEPROM数据写入 EEDR(可选)
5. 对 EECR 寄存器的 EEMWE 写 "1",同时清零 EEWE
6. 在置位 EEMWE的 4 个周期内,置位 EEWE
代码如下:(附加说明)
/*内部EEPROM的写入与读出*/
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
#include<iom16v.h>
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
#include<AVRdef.h>
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
unsigned
char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管0~9
void write_e2pr(unsigned
int addr,unsigned
char wdata);
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
unsigned
char read_e2pr(unsigned
int addr);
void delay(unsigned
int z)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
unsigned
int i,j;
for(i=0;i<z;i++)
for(j=0;j<150;j++);
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
void init_port(
void)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
DDRD=0xff;
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
PORTD=0x80;
//选通第一个数码管
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
DDRC=0xff;
//数码管段选
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
PORTC=0;
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
CLI();
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
void main()
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
unsigned
char temp,i;
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
init_port();
for(i=0;i<10;i++)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
write_e2pr(0x0111+i,tab[i]);
//向地址从0x111开始的单元写入数据
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
while(1)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
for(i=0;i<10;i++)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
PORTC=read_e2pr(0x0111+i);
//将数据读出来
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
delay(500);
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
//向EEPROM地址写一个字节的数据
void write_e2pr(unsigned
int addr,unsigned
char wdata)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
while(EECR&(1<<EEWE));
//等待上一次写操作完成
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EEAR=addr;
//写地址寄存器
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EEDR=wdata;
//写数据寄存器
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EECR=(1<<EEMWE);
//
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EECR|=(1<<EEWE);
//(两个分开写才能写进)启动写操作
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
//向EEPROM读出一个字节的数据
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
unsigned
char read_e2pr(unsigned
int addr)
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
{
while(EECR&(1<<EEWE));
//等待上一次写完成
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EEAR=addr;
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
EECR|=(1<<EERE);
//启动
return EEDR;
//返回读出的数据
![InBlock.gif](https://s1.51cto.com/images/editer/InBlock.gif)
}
注意:EECR=(1<<EEMWE);EECR|=(1<<EEWE);两个不能和在一起,我试过写不进去
转载于:https://blog.51cto.com/maoge/384380