新手上路
- 积分
- 24
- 金钱
- 24
- 注册时间
- 2015-4-8
- 在线时间
- 2 小时
|
5金钱
本人今天在调试手里的一个25LC160(mircochip的一个SPI接口的EEPROM 16字节1页)发现,连续读不能跨256的倍数地址读数据比如我想从地址0 读取257个字节,前256字节读出来是正确的,最后一个字节读出来是FF。
除非分两次调用,才能完全读出。
可是芯片手册上并没收这一块的说明。大家遇到过这类问题吗?
附上代码
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:ReadWriteByte
* 参数: _dat:写入的数据
* 返回: 读到的数据
* 描述: 读写一个字节
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static u8 ReadWriteByte(u8 _dat) {
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI3, _dat);
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI3);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:ReadRegister
* 参数: NONE
* 返回: 寄存器的值
* 描述: 读取EEPROM寄存器的值
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static u8 ReadRegister(void) {
u8 ret;
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_READ_REGISTER);
ret = ReadWriteByte(0xFF);
M25LC_CS_DISABLE();
return ret;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:WriteRegister
* 参数: _reg:寄存器的值
* 返回: NONE
* 描述: 写EEPROM寄存器的值
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static u8 WriteRegister(u8 _reg) {
u8 ret = 0;
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_WRITE_REGISTER);
ret = ReadWriteByte(_reg);
M25LC_CS_DISABLE();
return ret;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:WriteEnable
* 参数: NONE
* 返回: NONE
* 描述: 写使能
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static void WriteEnable(void) {
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_WRITE_ENABLE);
M25LC_CS_DISABLE();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:WriteDisable
* 参数: NONE
* 返回: NONE
* 描述: 写失能
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static void WriteDisable(void) {
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_WRITE_DISABLE);
M25LC_CS_DISABLE();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:IsWriteBusy
* 参数: NONE
* 返回: NONE
* 描述: 写失能
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static BOOL IsWriteBusy(void) {
BOOL isBusy = FALSE;
if ((ReadRegister() & 0x01) == 0x01)
isBusy = TRUE;
return isBusy;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:WriteData
* 参数:
* 返回:
* 描述:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static void WritePageData(u16 _addr, byte *_datbuf, u16 _size) {
u8 i = 0;
if (_size > M25LC_PAGE_SIZE)
return;
WriteEnable();
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_WRITE_DATA);
ReadWriteByte((u8) (_addr << 8));
ReadWriteByte((u8) (_addr));
for (i = 0; i < _size; i++) {
ReadWriteByte(_datbuf[i]);
}
M25LC_CS_DISABLE();
/*CS拉高后要等最少5ms*/
while (IsWriteBusy() == TRUE);
WriteDisable();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:ReadData
* 参数:
* 返回:
* 描述:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void M25LC160ReadData(u16 _addr, byte *_datbuf, u16 _size) {
u16 i;
M25LC_CS_ENABLE();
ReadWriteByte(M25LC_READ_DATA);
ReadWriteByte((u8) (_addr << 8));
ReadWriteByte((u8) (_addr));
for (i = 0; i < _size; i++) {
_datbuf[i] = ReadWriteByte(0xFF);
}
M25LC_CS_DISABLE();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:WriteData
* 参数:
* 返回:
* 描述:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void M25LC160WriteData(u16 _addr, byte *_datbuf, u16 _size) {
u16 i = 0;
u8 offset = _addr % M25LC_PAGE_SIZE; //页偏移地址
u8 conut =
((offset + _size) % M25LC_PAGE_SIZE == 0) ?
(offset + _size) / M25LC_PAGE_SIZE : (offset + _size) / M25LC_PAGE_SIZE + 1; //需要写入的次数
u16 nextaddr = _addr; //下一次写入地址
byte *nextdata = _datbuf; //下一次写入数据指针
if ((_addr + _size) > M25LC_MAX_SIZE)
return;
for (; i < conut; i++) {
if (i == 0) //第一页
{
WritePageData(nextaddr, nextdata, conut == 1 ? _size : M25LC_PAGE_SIZE - offset);
nextaddr += M25LC_PAGE_SIZE - offset;
nextdata += M25LC_PAGE_SIZE - offset;
} else if (i == conut - 1) //最后一页
{
WritePageData(nextaddr, nextdata, _size - (M25LC_PAGE_SIZE * i - offset));
} else //中间页面
{
WritePageData(nextaddr, nextdata, M25LC_PAGE_SIZE);
nextaddr += M25LC_PAGE_SIZE;
nextdata += M25LC_PAGE_SIZE;
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:RegisterConf
* 参数:
* 返回:
* 描述:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
static void RegisterConf(void) {
/*WPEN:被设置为1时,WP引脚才有效
BP1 BP0:都设置为0时表示数据存储区没有写保护区域
WEL:写使能标志位,1表示可以写,0表示不能写。写使能寄存器指令被执行时才会置1
WIP:写操作忙标志位 1为忙 0为空闲
*/
WriteRegister(0x00);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 函数名:M25LC160Init
* 参数:
* 返回:
* 描述:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void M25LC160Init(void) {
byte writeBuf[1000];
// byte writeBuf[10] = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0xAA,0xBB,0xCC,0xDD};
byte readBuf[1000];
u16 i = 0;
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能相关时钟
EEPROM_RCC_CONFIGURE();
EEPROM_IO_CONFIGURE(&GPIO_InitStructure);
//配置SPI端口
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据位8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CLK常态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一沿变化锁存数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //片选使用IO控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //分频 36M/16=2M
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //先传高位
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI3, &SPI_InitStructure);
SPI_Cmd(SPI3, ENABLE);
M25LC_WP_DISABLE();
M25LC_CS_DISABLE();
RegisterConf();
for(;i<sizeof(writeBuf);i++){
writeBuf[i] = 0x11;
readBuf[i] = 0;
}
M25LC160WriteData(0,writeBuf,sizeof(writeBuf));
M25LC160ReadData(300,readBuf,sizeof(readBuf));
// M25LC160ReadData(256,readBuf+256,256);
}
|
|