通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();
} |
|