打印

关于MSP430F5529 通过SPI 对SST25VF016B 进行读写操作

[复制链接]
920|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
米尔豪斯|  楼主 | 2016-12-27 20:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通MSP430F5529的SPI 对SST25VF016B进行操作,参考的网友的程序。目前测试读 ID 是正确的,但是往里读写数据有问题。请大家帮忙看下还有什么问题。
上代码

/***************************************************************************//**
* @brief Init 3 wire SPI for flash sst25vf016
* @return None
******************************************************************************/
void SPI_init(void)
{

UCB1CTL1 |= UCSWRST; // soft reset spi
UCB1CTL0 |= UCSYNC + UCMODE_0 + UCMST + UCMSB + UCCKPL ; // spi-3-wire, master, 8 bit, MSB, CLK=0 when inactive spi mode3
UCB1CTL1 |= UCSSEL_2; //clock source: SMCLK
UCB1BR0 = 0x02; //freq div =2
UCB1BR1 = 0;
//Init UCB1 for spi, clk, mosi and miso
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4,GPIO_PIN1 + GPIO_PIN3);
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,GPIO_PIN2);

// GPIO_setDriveStrength(GPIO_PORT_P4,GPIO_PIN1 + GPIO_PIN3,GPIO_FULL_OUTPUT_DRIVE_STRENGTH);
// Set P4.0 as spi slave cs
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0);
// GPIO_setDriveStrength(GPIO_PORT_P4,GPIO_PIN0,GPIO_FULL_OUTPUT_DRIVE_STRENGTH);
// Set P4.0 spi cs high
GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN0);

UCB1CTL1 &= ~UCSWRST; // end of spi register set

//Enable Receive interrupt
/* USCI_B_SPI_clearInterruptFlag(USCI_B1_BASE, USCI_B_SPI_RECEIVE_INTERRUPT); ////////////// attention test
USCI_B_SPI_enableInterrupt(USCI_B1_BASE, USCI_B_SPI_RECEIVE_INTERRUPT);
USCI_B_SPI_clearInterruptFlag(USCI_B1_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT);
USCI_B_SPI_enableInterrupt(USCI_B1_BASE, USCI_B_SPI_TRANSMIT_INTERRUPT);

*/


}
//////////////
void main(void)
{
unsigned char i;
unsigned char a1[10]={0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a};
unsigned char a2[10]={0};
Power_On();

test= SST25_ReadID();         //-------------
test =SST25_ReadJecID();  //---------- 可以正确读出
SST25_ChipErase();
//SST25_SectorErase4K(0x0000);
SST25_WriteByte(0x100000, 0xa5);
test =SST25_ReadByte(0x100000);
SST25_WriteByte(0x000000, 0xa5);
test =SST25_ReadByte(0x000000);
SST25_AddrIncWrite(0x100000,a1,10);
SST25_AddrIncRead(0x100000, a2,10);
_NOP();
}


/////////
/*********************************************************************
* 函 数 名: SST25_Init
* 功能描述: SST25VF016B初始化
* 函数说明: 无
* 调用函数: SST25_WriteFlashStatus()
* 全局变量: 无
* 输  入: 无
* 返  回: 初始化状态
**********************************************************************/
unsigned char SST25_Erase_All_Data(void)
{
unsigned char id;
id = SST25_ReadID(); //读Flash内部ID
if (id == 0xBF)
{
SST25_WriteFlashStatus(0x00); //disable write protect
SST25_ChipEraseAll(); //擦除全片
// SST25_WriteFlashStatus(0x9C); // enable write protect
return FLASH_NO_ERR;
}
else
{
return FLASH_ERR; //初始化错误代码
}
}


/*********************************************************************
* 函 数 名: UCB1SPI_SendByte
* 功能描述: SPI发送一字节
* 函数说明:
* 调用函数:
* 全局变量:
* 输  入: unsigned char ch
* 返  回:
**********************************************************************/
void UCB1SPI_SendByte(unsigned char ch)
{
while (!(UCB1IFG&UCTXIFG) ); //判断是否发送完毕
UCB1TXBUF = ch;
__delay_cycles(40);
}
/*********************************************************************
* 函 数 名: UCB1SPI_RecByte
* 功能描述: SPI接收一字节
* 函数说明:
* 调用函数:
* 全局变量:
* 输  入:
* 返  回: SPI0DAT
**********************************************************************/
unsigned char UCB1SPI_RecByte(void)
{
// while((UCB1IFG & UCTXIFG) == 0);
// UCB1IFG &= ~UCRXIFG; //接收一个数据必须同步发送一个数据
// UCB1TXBUF = 0xff;
while(!(UCB1IFG & UCRXIFG)); //Wait for the byte to be received
return (UCB1RXBUF);
}

/*********************************************************************
* 函 数 名: SST25_ReadID
* 功能描述: 读SST25VF016B内部ID
* 函数说明: 无
* 调用函数: UCB1SPI_SendByte() ,UCB1SPI_RecByte()
* 全局变量: 无
* 输  入: 无
* 返  回: 无
**********************************************************************/
unsigned char SST25_ReadID(void)
{
unsigned char byte;
SPI_CS_LOW(); /* enable device */
UCB1SPI_SendByte(SST_RDID); /* send read ID command (90h or ABh) */
UCB1SPI_SendByte(0x00); /* send address */
UCB1SPI_SendByte(0x00); /* send address */
UCB1SPI_SendByte(0x01); /* send address - either 00H or 01H */
UCB1SPI_SendByte(0xFF);
byte = UCB1SPI_RecByte();

/* receive byte */
// byte = UCB1SPI_RecByte();
// Wait until USCI_A0 state machine is no longer busy
while (UCB1STAT & UCBUSY);
SPI_CS_HIGH(); /* disable device */
return byte;
}
/*********************************************************************
* 函 数 名: SST25_ReadJecID
* 功能描述: 读SST25VF016B内部ID
* 函数说明: 无
* 调用函数: UCB1SPI_SendByte() ,UCB1SPI_RecByte()
* 全局变量: 无
* 输  入: 无
* 返  回: 无
**********************************************************************/
unsigned char SST25_ReadJecID(void)
{
unsigned char byte;
SPI_CS_LOW(); // enable the sst flash
UCB1SPI_SendByte(SST_JEDEC_ID); //
UCB1SPI_SendByte(0xFF);
byte = UCB1SPI_RecByte();
SPI_CS_HIGH();
return byte;
}

/*********************************************************************
* 函 数 名: SST25_WriteEnable
* 功能描述: FLASH写使能
* 函数说明: 写操作,擦除操作之前都需要写使能
* 调用函数: UCB1SPI_SendByte()
* 全局变量:
* 输  入: 无
* 返  回: 无
**********************************************************************/
void SST25_WriteEnable(void)
{
SPI_CS_LOW(); // enable the sst flash
UCB1SPI_SendByte(SST_WREN);
SPI_CS_HIGH();
}
/*********************************************************************
* 函 数 名: SST25_WriteDisable
* 功能描述: FLASH写禁能
* 函数说明:
* 调用函数: UCB1SPI_SendByte()
* 全局变量:
* 输  入: 无
* 返  回: 无
**********************************************************************/
void SST25_WriteDisable(void)
{
SPI_CS_LOW();
UCB1SPI_SendByte(SST_WRDI);
SPI_CS_HIGH();
}
/*********************************************************************
* 函 数 名: SST25_ReadFlashStatus
* 功能描述: 读取FLASH内部状态
* 函数说明: 读写FLASH内部状态
BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
BPL AAI BP3 BP2 BP1 BP0 WEL BUSY
* 调用函数: UCB1SPI_SendByte(),UCB1SPI_RecByte()
* 全局变量: 无
* 输  入: 无
* 返  回: Status
**********************************************************************/
unsigned char SST25_ReadFlashStatus(void)
{
unsigned char byte;
SPI_CS_LOW();
UCB1SPI_SendByte(SST_RDSR);
UCB1SPI_SendByte(0xFF);
byte = UCB1SPI_RecByte();
SPI_CS_HIGH();
return byte;
}

/*********************************************************************
* 函 数 名: SST25_EnableWriteStatus
* 功能描述: 使能写FLASH内部状态寄存器
* 函数说明: 使能写FLASH内部状态寄存器
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: 无
* 返  回: 无
**********************************************************************/
void SST25_EnableWriteStatus(void)
{
SPI_CS_LOW();
UCB1SPI_SendByte(SST_EWSR);
SPI_CS_HIGH();
}

/*********************************************************************
* 函 数 名: SST25_WaitBusy
* 功能描述: 普通模式判忙
* 函数说明: 普通模式判忙
* 调用函数: SST25_ReadFlashStatus()
* 全局变量: 无
* 输  入: 无
* 返  回: 无
**********************************************************************/
void SST25_WaitBusy()
{
while ((SST25_ReadFlashStatus()&STATUS_BUSY));
}
/*********************************************************************
* 函 数 名: SST25_WriteFlashStatus
* 功能描述: 写FLASH内部状态寄存器
* 函数说明: 写FLASH内部状态寄存器
BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
BPL AAI BP3 BP2 BP1 BP0 WEL BUSY
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: status:状态
* 返  回: 无
**********************************************************************/
void SST25_WriteFlashStatus(unsigned char status)
{
SPI_CS_LOW();
__delay_cycles(50);
UCB1SPI_SendByte(SST_WREN);
__delay_cycles(50);
SPI_CS_HIGH();
__delay_cycles(50);
SPI_CS_LOW();
__delay_cycles(50);
UCB1SPI_SendByte(SST_WRSR);
UCB1SPI_SendByte(status);
__delay_cycles(50);
SPI_CS_HIGH();
SST25_WaitBusy();
}

/*********************************************************************
* 函 数 名: SST25_ReadByte
* 功能描述: FLASH对目标地址单字节读取
* 函数说明: FLASH对目标地址单字节读取
* 调用函数: UCB1SPI_SendByte() UCB1SPI_RecByte()
* 全局变量: 无
* 输  入: addr:24位地址
* 返  回: data:读到的数据
**********************************************************************/
unsigned char SST25_ReadByte(unsigned long int addr)
{
unsigned char addr_h, addr_m, addr_l, data;
addr_l = addr;
addr_m = addr >> 8;
addr_h = addr >> 16;
SPI_CS_LOW();
UCB1SPI_SendByte(SST_RD);
UCB1SPI_SendByte(addr_h);
UCB1SPI_SendByte(addr_m);
UCB1SPI_SendByte(addr_l);
UCB1SPI_SendByte(0xFF);
// UCB1TXBUF = 0xff;
data = UCB1SPI_RecByte();
SPI_CS_HIGH();
return data;
}

/*********************************************************************
* 函 数 名: SST25_AddrIncRead
* 功能描述: FLASH对目标地址连续读取
* 函数说明: 目标地址自动增加
* 调用函数: UCB1SPI_SendByte() UCB1SPI_RecByte()
* 全局变量: 无
* 输  入: addr:24位地址 ,num: 连续读字节数,arry:数据数组
* 返  回: 无
**********************************************************************/
void SST25_AddrIncRead(unsigned long addr, unsigned char* arry, unsigned int num)
{
unsigned char addr_h, addr_m, addr_l;
int i;
addr_l = addr;
addr_m = addr >> 8;
addr_h = addr >> 16;
SPI_CS_LOW();
UCB1SPI_SendByte(SST_RD);
UCB1SPI_SendByte(addr_h);
UCB1SPI_SendByte(addr_m);
UCB1SPI_SendByte(addr_l);
for (i=0;i<num;i++)
{
UCB1SPI_SendByte(0xFF);
arry = UCB1SPI_RecByte();
}
SPI_CS_HIGH();
}
/*********************************************************************
* 函 数 名: SST25_WriteByte
* 功能描述: FLASH对目标地址单字节写入
* 函数说明: FLASH对目标地址单字节写入
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: addr:24位地址 data:写入的数据
* 返  回: 无
**********************************************************************/
void SST25_WriteByte(unsigned long int addr, unsigned char data)
{
unsigned char addr_h, addr_m, addr_l;
addr_l = addr;
addr_m = addr >> 8;
addr_h = addr >> 16;
SST25_WriteEnable(); // 写使能
SPI_CS_LOW();
UCB1SPI_SendByte(SST_WR);
UCB1SPI_SendByte(addr_h);
UCB1SPI_SendByte(addr_m);
UCB1SPI_SendByte(addr_l);
UCB1SPI_SendByte(data);
SPI_CS_HIGH();
SST25_WaitBusy();
}
/*********************************************************************
* 函 数 名: SST25_AddrIncWrite
* 功能描述: 连续写命令
* 函数说明: 连续写命令
* 调用函数: SST25_AddrIncWriteA(),SST25_AddrIncWriteB()
* 全局变量: 无
* 输  入: addr24byte:首地址 arry:输入数组, num:写Byte个数
* 返  回: 无
**********************************************************************/
void SST25_AddrIncWrite(unsigned long addr, unsigned char* arry, unsigned long int num)
{
int i;
unsigned char addr_h, addr_m, addr_l;
addr_l = addr;
addr_m = addr >> 8;
addr_h = addr >> 16;
SST25_WriteEnable(); // 写使能
SPI_CS_LOW();
UCB1SPI_SendByte(SST_AAI);
UCB1SPI_SendByte(addr_h);
UCB1SPI_SendByte(addr_m);
UCB1SPI_SendByte(addr_l);
UCB1SPI_SendByte(*arry++);
UCB1SPI_SendByte(*arry++);
SPI_CS_HIGH();
SST25_WaitBusy();
i = 2;
while(i < num)
{
SPI_CS_LOW();
UCB1SPI_SendByte(SST_AAI);
UCB1SPI_SendByte(*arry++);
UCB1SPI_SendByte(*arry++);
SPI_CS_HIGH();
SST25_WaitBusy();
i += 2;
}
SST25_WaitBusy();
SST25_WriteDisable();
}
/*********************************************************************
* 函 数 名: SST25_ChipErase
* 功能描述: 对整个FLASH进行擦写
* 函数说明: 对整个FLASH进行擦写
* 调用函数: UCB1SPI_SendByte(),UCB1SPI_RecByte(),SST25_WriteEnable()
* 全局变量: 无
* 输  入: 无
* 返  回: 无
**********************************************************************/
void SST25_ChipErase(void)
{
SST25_WriteEnable();
SPI_CS_LOW();
UCB1SPI_SendByte(SST_ERASE_ALL);
SPI_CS_HIGH();
SST25_WaitBusy();
}
/*********************************************************************
* 函 数 名: SST25_SectorErase4K
* 功能描述: 段擦除
* 函数说明: 段擦除
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: addr:地址
* 返  回: 无
**********************************************************************/
void SST25_SectorErase4K(unsigned long addr)
{
SST25_WriteEnable();
SPI_CS_LOW();
UCB1SPI_SendByte(SST_ERASE_4KB);
UCB1SPI_SendByte(((addr&0xFFFFFF)>>16));
UCB1SPI_SendByte(((addr&0xFFFF)>>8));
UCB1SPI_SendByte(addr&0xFF);
SPI_CS_HIGH();
SST25_WaitBusy();
}
/*********************************************************************
* 函 数 名: SST25_BlockErase32K
* 功能描述: 32K块擦写
* 函数说明: 32K块擦写
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: addr:地址
* 返  回: 无
**********************************************************************/
void SST25_BlockErase32K(unsigned long addr)
{
SST25_WriteEnable();
SPI_CS_LOW();
UCB1SPI_SendByte(SST_ERASE_32KB); // 发送32 KByte Block Erase命令
UCB1SPI_SendByte(((addr&0xFFFFFF)>>16)); // 发送3bytes地址
UCB1SPI_SendByte(((addr&0xFFFF)>>8));
UCB1SPI_SendByte(addr&0xFF);
SPI_CS_HIGH();
SST25_WaitBusy();
}
/*********************************************************************
* 函 数 名: SST25_BlockErase64K
* 功能描述: 64K块擦写
* 函数说明: 64K块擦写
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: addr:地址
* 返  回: 无
**********************************************************************/
void SST25_BlockErase64K(unsigned long addr)
{
SST25_WriteEnable();
SPI_CS_LOW();
UCB1SPI_SendByte(SST_ERASE_64KB); // 发送64KByte Block Erase 命令
UCB1SPI_SendByte(((addr&0xFFFFFF)>>16)); // 发送3 bytes地址
UCB1SPI_SendByte(((addr&0xFFFF)>>8));
UCB1SPI_SendByte(addr&0xFF);
SPI_CS_HIGH();
SST25_WaitBusy();
}
/*********************************************************************
* 函 数 名: void SST25_EraseAll()
* 功能描述: 64K块擦写
* 函数说明: 64K块擦写
* 调用函数: UCB1SPI_SendByte()
* 全局变量: 无
* 输  入: addr:地址
* 返  回: 无
**********************************************************************/
void SST25_ChipEraseAll()
{
SST25_WriteEnable();
SPI_CS_LOW();
UCB1SPI_SendByte(SST_ERASE_ALL); // 发送64KByte Block Erase 命令
SPI_CS_HIGH();
SST25_WaitBusy();
}

相关帖子

沙发
lefeng| | 2016-12-27 20:24 | 只看该作者
是不是芯片有问题,

使用特权

评论回复
板凳
lwsn| | 2016-12-27 20:44 | 只看该作者
把main函数里的片擦除改成扇区擦除试试,我用的g2553的芯片  w25q128的flash   
整片擦除之后再写数据,就读不出数据  
但是扇区擦除后,写进去的数据就可以读出(整片擦除程序肯定没错)
但出这状况  不知道为啥

使用特权

评论回复
地板
冰河w| | 2016-12-27 21:22 | 只看该作者
test =SST25_ReadJecID();  //---------- 可以正确读出
说明SPI读没有问题,
很可能是写入出了问题,可以尝试写入信息,读出来看看是否一致。

使用特权

评论回复
5
pklong| | 2016-12-28 21:26 | 只看该作者
楼主的程序不能读写?

使用特权

评论回复
6
pklong| | 2016-12-28 21:27 | 只看该作者
SPi写入的地址有问题吗?

使用特权

评论回复
7
angerbird| | 2016-12-28 21:31 | 只看该作者
SPI总线的通讯还是蛮方便的。

使用特权

评论回复
8
myidear| | 2016-12-29 19:00 | 只看该作者
读 ID 是正确的,但是往里读写数据有问题。看看写的指令和时序配置好了没

使用特权

评论回复
9
dspmana| | 2016-12-29 21:04 | 只看该作者
楼主用示波器测量过相关的波形了吗?

使用特权

评论回复
10
dspmana| | 2016-12-29 21:08 | 只看该作者
SPI的读写可以使用示波器测量出来。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

150

主题

731

帖子

1

粉丝