This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:TI C/C++编译器
您好!
我使用 MSP430F5328 接口和使用 SPI 通信协议的 W25X10 winbound 串行闪存。 我使用的是 SMCLK 16MHz。
我已根据从器件和源代码配置 SPI、如下所示:
#define SPICLK 32.
uint8_t SourceAddr [16];
uint8_t DestAddr[16];
void main( void )
{
uint16_t IDcode = 0;
//将 P2.6设置为从器件复位
GPIO_setAsOutputPin (GPIO_PORT_P2、GPIO_PIN6);
GPIO_setOutputHighOnPin (GPIO_PORT_P2、GPIO_PIN6);
//P3.3、4选项选择
//FLASH_SPISIMO - P3.3
//FLASH_SPISOMI - P3.4
GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P3、GPIO_PIN3 + GPIO_PIN4);
//P2.7 FLASH_SPICLK
GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P2、GPIO_PIN7);
//初始化主设备
USCI_A_SPI_initMasterParam param ={0};
param.selectClockSource = USCI_A_SPI_CLOCKSOURCE_SMCLK;
param.clockSourceFrequency = UCS_getSMCLK();
param.desiredSpiClock = SPICLK;
param.msbFirst = USCI_A_SPI_MSB_FIRST;
param.clockPhase = USCI_A_SPI_PHASE_DATA_Changed_ONFIRST_captured_on_next;
param.clockPolarity = USCI_A_SPI_CLOCKPOLARITY_INACT_LOW;
返回值= USCI_A_SPI_initMaster (USCI_A0_BASE、¶m);
如果(STATUS_FAIL =返回值)
返回0;
//启用 SPI 模块
USCI_A_SPI_ENABLE (USCI_A0_BASE);
//现在初始化 SPI 信号、复位从器件
GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN6);
/*读取制造商 ID */
IDcode =
SerialFlash_readid();
}
uint16_t SerialFlash_readid (void)
{
uint16_t IDcode;
// P2.6 --0,CS =0选择 SPI 闪存
GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN6);
//读取设备命令 0x90
SourceAddr[0]= 0x90;
//器件地址0x00的上部
SourceAddr[1]= 0x00;
//器件地址0x00的下半部分
SourceAddr[2]= 0x00;
SourceAddr[3]= 0x00;
//串行闪存发送数据
SerialFlash_SendData ((uint8_t *)&SourceAddr[0]、 4);
_DELAY_CYCLES (160000);
//串行闪存接收数据
SerialFlash_RcvData ((uint8_t *)&DestAddr[0],2);
// P2.6 - 1、CS = 1释放 SPI 闪存
GPIO_setOutputHighOnPin (GPIO_PORT_P2、GPIO_PIN6);
//获取 IDcode
IDCODE =(DestAddr[0]<< 8)|(DestAddr[1]);
返回 IDCODE;
}
void SerialFlash_SendData (uint8_t *buf、uint32_t Length)
{
uint32_t i;
对于(i = 0;i <长度;i++)
{
// USCI_A0 TX 缓冲器就绪?
while (!(UCA0IFG&UCTXIFG));
UCA0TXBUF =*缓冲;
buf++;
}
}
void SerialFlash_RcvData (uint8_t *buf、uint32_t 长度)
{
uint32_t i;
对于(i = 0;i <长度;i++)
{
// USCI_A0 RX 缓冲器准备好了吗?
while (!(UCA0IFG&UCRXIFG));
* buf = USCI_A_SPI_receiveData (USCI_A0_BASE);
buf++;
}
}
我已经检查了示波器上的 MOSI 和时钟信号并变得非常完美。
但我无法在接收器缓冲器上正确读取制造商 ID。 大多数情况下、获取0xFF、0xFF、有时获取一些随机值。
能不能有人帮我解决这个问题。
谢谢、此致、
John
您好、Ryan、
我将为制造商 ID 命令发送虚拟字节、如下所示:
uint16_t SerialFlash_readid (void)
{
uint16_t IDcode;
// P2.6 --0,CS =0选择 SPI 闪存
GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN6);
//读取设备命令 0x90
SourceAddr[0]= 0x90;
//器件地址0x00的上部
SourceAddr[1]= 0x00;
//器件地址0x00的下半部分
SourceAddr[2]= 0x00;
SourceAddr[3]= 0x00;
//串行闪存发送数据
SerialFlash_SendData ((uint8_t *)&SourceAddr[0]、 4);
_DELAY_CYCLES (160000);
//串行闪存接收数据
SerialFlash_RcvData ((uint8_t *)&DestAddr[0],2);
// P2.6 - 1、CS = 1释放 SPI 闪存
GPIO_setOutputHighOnPin (GPIO_PORT_P2、GPIO_PIN6);
//获取 IDcode
IDCODE =(DestAddr[0]<< 8)|(DestAddr[1]);
返回 IDCODE;
}
然后尝试读取2个字节的制造商 ID、但未获取任何内容。
示波器屏幕截图如下所示:
请帮我解决这个问题。
谢谢、此致、
John
您好、Ryan、
我已如上所述更改 W25X10_RcvData 函数并设置 UCCKPH 位。 现在能够成功读取制造商 ID。
非常感谢。 但我对串行闪存数据表中提到的仅支持 Mode0和 mode3有疑问。
现在我尝试读取串行闪存状态。
Recv 函数如下所示:
void
W25X10_RcvData( uint8_t *buf, uint32_t Length )
{
uint32_t i;
while
(UCA0STAT & UCBUSY)
/*EMPTY*/
;
// let last Tx byte through
(
void
)UCA0RXBUF;
// Clear RXIFG
for
( i = 0; i < Length; i++ )
{
UCA0TXBUF = 0xFF;
// Dummy byte to run the SPI
// USCI_A0 RX buffer ready?
while
(!(UCA0IFG&UCRXIFG));
*buf = USCI_A_SPI_receiveData(USCI_A0_BASE);
buf++;
}
}
uint8_t SerialFlash_ReadStatus( void )
{
// P2.6 --0,CS =0选择 SPI 闪存
SerialFlash_CS0();
//读取寄存器1命令
SourceAddr[0]= 0x05;
//发送命令
SerialFlash_SendData((uint8_t *)&SourceAddr[0],1 );
W25X10_RcvData ((uint8_t *)&DestAddr[0]、2);
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
//返回寄存器1的内容
返回 DestAddr[0];
}
但它将返回0xFF。
您好、Ryan、
我正在尝试擦除串行闪存、因此我将执行以下步骤:
1) 1)读取串行闪存状态
uint8_t SerialFlash_ReadStatus( void )
{
// P2.6 --0,CS =0选择 SPI 闪存
SerialFlash_CS0();
//读取寄存器1命令
SourceAddr[0]= 0x05;
//发送命令
SerialFlash_SendData((uint8_t *)&SourceAddr[0],1 );
//接收注册器1的内容
SerialFlash_RcvData ((uint8_t *)&DestAddr[0],2);
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
//返回寄存器1的内容
返回 DestAddr[0];
}
2) 2)写入使能命令
void SerialFlash_WEnable (void)(空)
{
// P2.6 --0,CS =0选择 SPI 闪存
SerialFlash_CS0();
//写入启用命令
SourceAddr[0]= 0x06;
SerialFlash_SendData ((uint8_t *)&SourceAddr[0]、1);
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
}
3) 3)读取上述串行闪存状态
但 WriteEnable 位未设置
下面是示波器屏幕截图。
使能位未设置是什么错误?
谢谢、此致、
John
您好、Ryan、
是的、我将05h 发送给读取状态寄存器、如上面的函数"SerialFlash_ReadStatus"中所示、它只有1个字节。 我正在重置 CS 引脚。
以下是代码:
uint8_t SerialFlash_Erase (void)
{
uint8_t 温度;
uint32_t i、j;
//检查状态寄存器
while (1)
{
//读取状态寄存器1
temp = SerialFlash_ReadStatus();
//检查忙位
温度&= 0x01;
if (温度==0x00)
中断;
for (i=0;i<10;i++);
}
//写入使能
SerialFlash_WEnable();
//检查 状态寄存器
while (1)
{
for (i=0;i<10;i++);
//读取状态寄存器1
temp = SerialFlash_ReadStatus();
//检查忙位
temp &= 0x03;
//如果写入使能 WEL = 1
if (Temp ==0x02)
中断;
}
// P2.6 - 0、CS = 0选择 SPI 闪存
SerialFlash_CS0();
SourceAddr[0]= 0xC7;
SerialFlash_SendData((uint8_t *)&SourceAddr[0],1 );
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
for (i=0;i<65000;i++);
for (j=0;j<30;j++);
返回1;
}
uint8_t SerialFlash_ReadStatus( void )
{
// P2.6 --0,CS =0选择 SPI 闪存
SerialFlash_CS0();
//读取寄存器1命令
SourceAddr[0]= 0x05;
//发送命令
SerialFlash_SendData((uint8_t *)&SourceAddr[0],1 );
//接收注册器1的内容
SerialFlash_RcvData ((uint8_t *)&DestAddr[0],2);
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
//返回寄存器1的内容
返回 DestAddr[0];
}
void SerialFlash_WEnable (void)(空)
{
// P2.6 --0,CS =0选择 SPI 闪存
SerialFlash_CS0();
//写入启用命令
SourceAddr[0]= 0x06;
SerialFlash_SendData ((uint8_t *)&SourceAddr[0]、1);
// P2.6 - 1、CS = 1释放 SPI 闪存
SerialFlash_CS1();
}
您能否检查上述 API、我做了什么错误?
谢谢、此致、
John
能不能有人帮我解决这个问题。