共3条
1/1 1 跳转至页
AT45DB081 求助:使用AT45DB081遇到的问题.
问
第一次使用外扩存储器,在使用AT45DB081的过程中遇到一点麻烦,从081取到的值和送去的值不符,不知
道是对081指令使用不当,还是单片机与081间通信存在问题(用spi与其它设备间通信,经验证通信正常)。
希望用过081的朋友指点一下,部分源程序附在后面。可以给我发邮件yanyaomail@163.com 谢谢!
/*************************初始化变量*****************************/
xdata uchar send_081[15]=
{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15};
xdata uchar read_081[15];
/*************************SPI通信子程序***************************/
void SenDSPIByte(unsigned char ch) //通过SPI发送一个字节数据{ SPIF = 0;
// SPIF位清零
SPI0DAT = ch; // 启动一次数据发送
while (SPIF == 0); // 等待数据发送完毕
}
unsigned char GetSPIByte() //通过SPI接收一个字节数据
{ SPIF = 0; // SPIF位清零
SPI0DAT = 0; //启动一次数据接收
while (SPIF == 0); // 等待数据接收完毕
return SPI0DAT; // 读取SPI接收的数据
}
/**************************部分主程序**************************/
P5&=0xFD; //片选081
SenDSPIByte(0x84); //发送操作码,向缓存器写入数据
SenDSPIByte(0x00); //发送8位无效位
SenDSPIByte(0x00); //发送7位无效位和第一位地址位
SenDSPIByte(0x00); //发送后8位地址
for(flag=0;flag<15;flag++) //送入数据
SenDSPIByte(send_081[flag]);
P5|=0x02; //释放081
P5&=0xFD;
SenDSPIByte(0x83); //擦写主存储器页面后并从缓存器写入
SenDSPIByte(0x00); //发送3位无效位和五位页面地址
SenDSPIByte(0x00); //发送七位页面地址位和1位无效位
SenDSPIByte(0x00); //发送8位无效位
P5|=0x02;
P5&=0xFD;
SenDSPIByte(0x53); //将主存储器页面数据传送给缓存器
SenDSPIByte(0x00); //发送3位无效位和五位页面地址
SenDSPIByte(0x00); //发送七位页面地址位和1位无效位
SenDSPIByte(0x00); //发送8位无效位
P5|=0x02; //释放与081的通信
P5&=0xFD;
SenDSPIByte(0x54); //读缓存器内某个字节SenDSPIByte
SenDSPIByte(0x00); //发送8位无效位
SenDSPIByte(0x00); //发送7位无效位和第一位地址位
SenDSPIByte(0x00); //发送后8位地址
SenDSPIByte(0x00); //发送8位无效位
for(flag=0;flag<15;flag++) //读取缓存器中数据
read_081[flag]=GetSPIByte();
P5|=0x02;//释放与081的通信
////////////////////////////////////////////////////
通信结束后得到的数据如下:
read_081[15]={0x88,0x91,0x19,0xa2,0x2a,0xb3,0x3b,0xc4,0x4c,0x88,0x08,0x89,0x09,0x8a,0x0a} 答 1: 问题解决了!! 通过大家发的邮件,终于把这个问题解决了.说起来也简单,就是每条命令发送前没有查询081的状态位,由于上条指令未执行完,导致接收不到数据。
谢谢高手指点!!不胜感激。 答 2: AT45DB041读写缓存#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit SPI_CS = P1^3;
sbit SPI_SCK = P1^2;
sbit SPI_SO = P1^0;
sbit SPI_SI = P1^1;
sbit led = P3^1;
/***************************************************/
uchar SPI_HostReadByte(void){
uchar i,rByte=0;
for(i=0;i<8;i++){
SPI_SCK=0;
SPI_SCK=1;
rByte<<=1;
rByte|=SPI_SO;
}
return rByte;
}
/**************************************************/
void SPI_HostWriteByte(uchar wByte){
uchar i;
for(i=0;i<8;i++)
{
SPI_SCK=0;
if(wByte&0x80){SPI_SI=1;}
else{SPI_SI=0;}
wByte<<=1;
SPI_SCK=1;
}
}
/******************************************************************************/
/*Status Register Format: */
/* ----------------------------------------------------------------------- */
/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
/* |--------|--------|--------|--------|--------|--------|--------|--------| */
/* |RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X | */
/* ----------------------------------------------------------------------- */
/* bit7 - 忙标记,0为忙1为不忙。 */
/* 当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续*/
/* 将最新的状态字节送出。 */
/* bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。 */
/* bit5 */
/* bit4 */
/* bit3 */
/* bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记 */
/* 16种不同密度的器件。 */
/* bit1 */
/* bit0 - 这2位暂时无效 */
/******************************************************************************/
uchar AT45DB041B_StatusRegisterRead(void){
uchar i=0;
SPI_CS=0;
SPI_HostWriteByte(0xd7);
i=SPI_HostReadByte();
SPI_CS=1;
return i;
}
/******************************************************************************/
/*描述: */
/* When the last bit in the main memory array has been read,the device will*/
/* continue reading back at the beginning of the first page of memory.As w-*/
/* ith crossing over page boundaries,no delays will be incurred when wrapp-*/
/* ing around from the end of the array to the beginning of the array. */
/*参数: */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_ContinuousArrayRead(uint PA,uint BFA,uchar *pHeader,uint len){ ///////
uint i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
SPI_HostWriteByte(0xe8);
SPI_HostWriteByte((uchar)(PA>>7));
SPI_HostWriteByte((uchar)((PA<<1)|(BFA>>8)));
SPI_HostWriteByte((uchar)BFA);
for(i=0;i<4;i++){SPI_HostWriteByte(0x00);}
for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();}
SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的BUFFER中。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* 在该指令序列中,操作码84H选择BUFFER 1,87H选择BUFFER 2 */
/* BFA - BUFFER中的起始地址,0~263 */
/* pHeader - 待存数据的头指针 */
/* len - 待存数据的长度1~264 */
/******************************************************************************/
void AT45DB041B_BufferWrite(uchar buffer,uint BFA,uchar *pHeader,uint len){
uint i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
switch(buffer){
case 1:SPI_HostWriteByte(0x84);break;
case 2:SPI_HostWriteByte(0x87);break;
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((uchar)(BFA>>8));
SPI_HostWriteByte((uchar)BFA);
for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);}
SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的页中:包含2个动作,首先将指定数据*/
/* 写入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始写入地址,此写入*/
/* 动作不影响BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指*/
/* 定页中(带预擦除)。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(uchar buffer,uint PA,uint BFA,uchar *pHeader,uint len){
uint i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
switch(buffer){
case 1:SPI_HostWriteByte(0x83);break;
case 2:SPI_HostWriteByte(0x86);break;
}
SPI_HostWriteByte((uchar)(PA>>7));
SPI_HostWriteByte((uchar)(PA<<1));
SPI_HostWriteByte(0x00);
SPI_CS=1;
}
/*************************************************************************
道是对081指令使用不当,还是单片机与081间通信存在问题(用spi与其它设备间通信,经验证通信正常)。
希望用过081的朋友指点一下,部分源程序附在后面。可以给我发邮件yanyaomail@163.com 谢谢!
/*************************初始化变量*****************************/
xdata uchar send_081[15]=
{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15};
xdata uchar read_081[15];
/*************************SPI通信子程序***************************/
void SenDSPIByte(unsigned char ch) //通过SPI发送一个字节数据{ SPIF = 0;
// SPIF位清零
SPI0DAT = ch; // 启动一次数据发送
while (SPIF == 0); // 等待数据发送完毕
}
unsigned char GetSPIByte() //通过SPI接收一个字节数据
{ SPIF = 0; // SPIF位清零
SPI0DAT = 0; //启动一次数据接收
while (SPIF == 0); // 等待数据接收完毕
return SPI0DAT; // 读取SPI接收的数据
}
/**************************部分主程序**************************/
P5&=0xFD; //片选081
SenDSPIByte(0x84); //发送操作码,向缓存器写入数据
SenDSPIByte(0x00); //发送8位无效位
SenDSPIByte(0x00); //发送7位无效位和第一位地址位
SenDSPIByte(0x00); //发送后8位地址
for(flag=0;flag<15;flag++) //送入数据
SenDSPIByte(send_081[flag]);
P5|=0x02; //释放081
P5&=0xFD;
SenDSPIByte(0x83); //擦写主存储器页面后并从缓存器写入
SenDSPIByte(0x00); //发送3位无效位和五位页面地址
SenDSPIByte(0x00); //发送七位页面地址位和1位无效位
SenDSPIByte(0x00); //发送8位无效位
P5|=0x02;
P5&=0xFD;
SenDSPIByte(0x53); //将主存储器页面数据传送给缓存器
SenDSPIByte(0x00); //发送3位无效位和五位页面地址
SenDSPIByte(0x00); //发送七位页面地址位和1位无效位
SenDSPIByte(0x00); //发送8位无效位
P5|=0x02; //释放与081的通信
P5&=0xFD;
SenDSPIByte(0x54); //读缓存器内某个字节SenDSPIByte
SenDSPIByte(0x00); //发送8位无效位
SenDSPIByte(0x00); //发送7位无效位和第一位地址位
SenDSPIByte(0x00); //发送后8位地址
SenDSPIByte(0x00); //发送8位无效位
for(flag=0;flag<15;flag++) //读取缓存器中数据
read_081[flag]=GetSPIByte();
P5|=0x02;//释放与081的通信
////////////////////////////////////////////////////
通信结束后得到的数据如下:
read_081[15]={0x88,0x91,0x19,0xa2,0x2a,0xb3,0x3b,0xc4,0x4c,0x88,0x08,0x89,0x09,0x8a,0x0a} 答 1: 问题解决了!! 通过大家发的邮件,终于把这个问题解决了.说起来也简单,就是每条命令发送前没有查询081的状态位,由于上条指令未执行完,导致接收不到数据。
谢谢高手指点!!不胜感激。 答 2: AT45DB041读写缓存#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit SPI_CS = P1^3;
sbit SPI_SCK = P1^2;
sbit SPI_SO = P1^0;
sbit SPI_SI = P1^1;
sbit led = P3^1;
/***************************************************/
uchar SPI_HostReadByte(void){
uchar i,rByte=0;
for(i=0;i<8;i++){
SPI_SCK=0;
SPI_SCK=1;
rByte<<=1;
rByte|=SPI_SO;
}
return rByte;
}
/**************************************************/
void SPI_HostWriteByte(uchar wByte){
uchar i;
for(i=0;i<8;i++)
{
SPI_SCK=0;
if(wByte&0x80){SPI_SI=1;}
else{SPI_SI=0;}
wByte<<=1;
SPI_SCK=1;
}
}
/******************************************************************************/
/*Status Register Format: */
/* ----------------------------------------------------------------------- */
/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
/* |--------|--------|--------|--------|--------|--------|--------|--------| */
/* |RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X | */
/* ----------------------------------------------------------------------- */
/* bit7 - 忙标记,0为忙1为不忙。 */
/* 当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续*/
/* 将最新的状态字节送出。 */
/* bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。 */
/* bit5 */
/* bit4 */
/* bit3 */
/* bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记 */
/* 16种不同密度的器件。 */
/* bit1 */
/* bit0 - 这2位暂时无效 */
/******************************************************************************/
uchar AT45DB041B_StatusRegisterRead(void){
uchar i=0;
SPI_CS=0;
SPI_HostWriteByte(0xd7);
i=SPI_HostReadByte();
SPI_CS=1;
return i;
}
/******************************************************************************/
/*描述: */
/* When the last bit in the main memory array has been read,the device will*/
/* continue reading back at the beginning of the first page of memory.As w-*/
/* ith crossing over page boundaries,no delays will be incurred when wrapp-*/
/* ing around from the end of the array to the beginning of the array. */
/*参数: */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_ContinuousArrayRead(uint PA,uint BFA,uchar *pHeader,uint len){ ///////
uint i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
SPI_HostWriteByte(0xe8);
SPI_HostWriteByte((uchar)(PA>>7));
SPI_HostWriteByte((uchar)((PA<<1)|(BFA>>8)));
SPI_HostWriteByte((uchar)BFA);
for(i=0;i<4;i++){SPI_HostWriteByte(0x00);}
for(i=0;i<len;i++){pHeader[i]=SPI_HostReadByte();}
SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的BUFFER中。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* 在该指令序列中,操作码84H选择BUFFER 1,87H选择BUFFER 2 */
/* BFA - BUFFER中的起始地址,0~263 */
/* pHeader - 待存数据的头指针 */
/* len - 待存数据的长度1~264 */
/******************************************************************************/
void AT45DB041B_BufferWrite(uchar buffer,uint BFA,uchar *pHeader,uint len){
uint i;
while(i++<255){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
switch(buffer){
case 1:SPI_HostWriteByte(0x84);break;
case 2:SPI_HostWriteByte(0x87);break;
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((uchar)(BFA>>8));
SPI_HostWriteByte((uchar)BFA);
for(i=0;i<len;i++){SPI_HostWriteByte(pHeader[i]);}
SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 将指定数据写入从某个地址(0~263)开始的页中:包含2个动作,首先将指定数据*/
/* 写入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始写入地址,此写入*/
/* 动作不影响BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指*/
/* 定页中(带预擦除)。 */
/*参数: */
/* buffer - 选择BUFFER,01H选择BUFFER 1,02H选择BUFFER 2 */
/* PA - 页地址,0~2047 */
/* BFA - 指定BUFFER中的起始写入地址 */
/* pHeader - 指定数据的首地址 */
/* len - 指定数据的长度 */
/******************************************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(uchar buffer,uint PA,uint BFA,uchar *pHeader,uint len){
uint i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
while(i++<1000){if(AT45DB041B_StatusRegisterRead()&0x80){break;}}
SPI_CS=0;
switch(buffer){
case 1:SPI_HostWriteByte(0x83);break;
case 2:SPI_HostWriteByte(0x86);break;
}
SPI_HostWriteByte((uchar)(PA>>7));
SPI_HostWriteByte((uchar)(PA<<1));
SPI_HostWriteByte(0x00);
SPI_CS=1;
}
/*************************************************************************
共3条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |