|
|
楼主 |
发表于 2013-12-4 22:08:24
|
显示全部楼层
七、十分钟学会EEPROM读写
Atmega8单片机的片内EEPROM为512字节,其读写较为简单,最主要的几个操作函数为:
eeprom_is_ready(); 检测EEPROM是否准备好。OK返回1(返回EEWE位)
eeprom_busy_wait(); 等待EEPROM操作完成
eeprom_read_byte (const uint8_t *addr); 读取指定地址的一个字节8bit的EEPROM数据
eeprom_read_word (const uint16_t *addr); 读取指定地址的一个字16bit的EEPROM数据
eeprom_read_block (void *buf, const void *addr, size_t n); 读取由指定地址开始的指定长度的EEPROM数据
eeprom_write_byte (uint8_t *addr, uint8_t val); 向指定地址写入一个字节8bit的EEPROM数据
eeprom_write_word (uint16_t *addr, uint16_t val); 向指定地址写入一个字16bit的EEPROM数据
eeprom_write_block (const void *buf, void *addr, size_t n); 由指定地址开始写入指定长度的EEPROM数据,
要使用以上的函数,必须在程序开始的头文件定义中加入 #include <avr/eeprom.h>
在遥控器程序的编制中,我们使用EEPROM保存多个遥控模型的设置数据,由于每个遥控模型的设置数据远远超过2个字节,因此我们使用的函数主要是eeprom_read_block和eeprom_write_block。我们主要结合程序讲解这两个函数,其它的读写字和字节的函数较为简单,大家可以自己试试编编程序往EEPROM中写入一个字节,然后再读出来。注意以下几点:
1、在读出一个字前,一定要加上while(!eeprom_is_ready());语句等待eeprom准备好再读
2、在写入一个字前,一定要加上eeprom_busy_wait();等待eeprom的其它操作完成。
3、eeprom的地址是从0至511。(0至0x200)
我们看以下的程序:
void ReadModelSav(unsigned char ModelNo)
{
unsigned int i,j,k,l;
if ((ModelNo == 1 ) | (ModelNo == 2 ) | (ModelNo == 3 ))
{
k = sizeof(CurrModelSav);
l = k * (ModelNo-1)+1;
while(!eeprom_is_ready());
eeprom_read_block((void*)&CurrModelSav,(const void*)l,k);
if (CurrModelSav.PlanesNo != ModelNo ) //如果读出来的对不上模型编号,则初始化eprom中的模型数据
{
for(i=0;i<8;i++)
{
CurrModelSav.RevSw[i]= true; //初始化为正向
CurrModelSav.SubTrim[i]=0;
CurrModelSav.TrvlAdj[i]=0;
}
CurrModelSav.CpMod = 1; // 1,airplane,2,ccpm,3,vtail
j=0;
for(i=0;i<5;i++)
{
CurrModelSav.ThroCurv[i] = j;
CurrModelSav.PitCurv[i] = j;
j = j + 25;
}
CurrModelSav.GyroSens = 0;
CurrModelSav.PlanesNo = ModelNo;
eeprom_busy_wait();
eeprom_write_block((const void*)&CurrModelSav,(void*)l,k);
}
//用读出或默认的数据初始化CurrPluseTime
for(i=0;i<6;i++)
{
CurrPluseTime.ChannelHigh[i] = OriChannelHigh; //高电平统一为400ms
CurrPluseTime.ChannelLow[i] = OriChannelCenter; //低电平先取中值
CurrPluseTime.ChannelStart[i] = OriChannelStart + ((CurrModelSav.SubTrim[i]*OriChannelLength)/100) - ((CurrModelSav.TrvlAdj[i]*OriChannelLength)/200);
CurrPluseTime.ChannelLength[i] = OriChannelLength + ((OriChannelLength * CurrModelSav.TrvlAdj[i])/100);
}
}
}
这个程序是遥控器中用来读取保存的模型数据的,它支持3个不同模型的数据。它的输入值为要读取的模型编号,运行结束后,它把读出的数据保存在CurrModelSav这个预先定义的模型数据结构体里。
这个程序先是计算要读取的模型数据的起始地址,然后读出模型数据。用读出的模型数据中的模型编号对比,如果读出的编号与要读的编号一致,则读出的数据正确,则用读出的数据来初始化要控制模型的各类数据,如果读出的数据不正确,则说明EEPROM没有保存正确的模型数据,则用默认值初始化控制模型的各类数据,并把默认值保存到EEPROM中去。 |
| |