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.

[参考译文] MSP430F5529:具有 W25Q16JV 的 MSP430F5529只读255

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1063826/msp430f5529-msp430f5529-with-w25q16jv-reads-only-255

器件型号:MSP430F5529
主题中讨论的其他器件:MSP430WARE

当我发送命令时、它可以完美地读取 ID、但当我写入和读取缓冲区时、它只读取255。我已经发布了代码、请让我解决这个问题

/*-版权所有-、BSD_EX
*版权所有(c) 2012、德州仪器(TI)公司
*保留所有权利。
*
*以源代码和二进制形式重新分发和使用、有无
*如果满足以下条件、则允许进行修改
符合*:
*
**源代码的重新分发必须保留上述版权
*注意、此条件列表和以下免责声明。
*
**二进制形式的再发行必须复制上述版权
*请注意、中的此条件列表和以下免责声明
*随分发提供的文档和/或其他材料。
*
**德州仪器公司的名称和名称均不相同
*其贡献者可用于认可或推广衍生产品
*未经特定的事先书面许可。
*
*本软件由版权所有者和贡献者"按原样"提供
*以及任何明示或暗示的保证、包括但不限于:
*特定适销性和适用性的隐含保证
*不承认目的。 在任何情况下、版权所有者不得或
*派遣国应对任何直接、间接、偶然、特殊、
*典型或必然的损害(包括但不限于
*采购替代货物或服务;丧失使用、数据或利润;
*或业务中断)、无论原因是什么以及任何责任理论、
*无论是合同、严格责任还是侵权行为(包括疏忽或)
*否则)因使用本软件而以任何方式产生、
*即使被告知可能会发生此类损坏。
*
秘书长的报告
*
* MSP430代码示例免责声明
*
* MSP430代码示例是通常包含的低级程序
*高度演示单个外设功能或器件功能
*简明扼要。 为此、代码可能依赖于器件的加电默认值
*寄存器值和设置、如时钟配置和注意
*在组合多个示例中的代码时应采取这种方法、以避免潜在的问题
*效果。 有关 GUI、另请参阅 www.ti.com/grace 和 www.ti.com/msp430ware
*用于外设配置的 API 函数库方法。
*
*--/版权--*/
//
// MSP430F552x 演示- USCI_A0、SPI 3线主器件递增数据
//
//说明:SPI 主设备使用3线制模式与 SPI 从设备通信。 令人惊叹
//数据由从0x01开始的主器件发送。 接收到的数据
//与之前的传输相同。 USCI RX ISR 被用来处理
//与 CPU 通信、通常在 LPM0中。 如果为高电平、则 P1.0指示
//有效数据接收。 因为 LPM0之后的所有执行都是 ISR、
//初始化等待 DCO 相对于 ACLK 稳定。
// ACLK =~32.768kHz、MCLK = SMCLK = DCO ~ 1048kHz。 BRCLK=SMCLK/2
//
//与 SPI 从器件数据回显代码示例一起使用。 如果从器件处于调试模式、则为 P1.1
//从器件复位信号与从器件的 JTAG 冲突;要解决此问题、请使用 IAR
//从器件上的“运行时释放 JTAG”。 如果在中设置了断点
//从器件 RX ISR、主器件也必须停止以避免从器件过载
// RXBUF。
//
// MSP430F552x
//------------
///|\||
//|||
//-|RST P1.0|->LED
//||
//| P3.3|->数据输出(UCA0SIMO)
//||
//| P3.4|<-数据输入(UCA0SOMI)
//||
//从机复位<-|P1.1 P2.7|->串行时钟输出(UCA0CLK)
//
//
// Bhargavi Nisarga
// Texas Instruments Inc.
// 2009年4月
//使用 CCSv4和 IAR Embedded Workbench 构建版本:4.21
//

#include
#include

unsigned char MST_Data、SLV_Data;
unsigned char temp;
#define SLAVE_CS_OUT P2OUT
#define SLAVE_CS_DIR P2DIR
#define SLAVE_CS_PIN BIT0

#define FLASH_WP_OUT P3OUT
#define FLASH_WP_DIR P3DIR
#define FLASH_WP_PIN BIT0

#define FLASH_RST_OUT P7OUT
#define FLASH_RST_DIR P7DIR
#define FLASH_RST_PIN BIT0

uint8_t write_buf[1]={2};
uint8_t read_buf[1]={0};

void flashInit (void);
void flashWrite (uint32_t address、uint8_t*数据、uint16_t size);
void flashRead (uint32_t address、uint8_t*数据、uint16_t size);
静态空 spiInit (void);
静态空 spiTxRx (uint8_t *地址、uint32_t addlen、uint8_t *数据、uint32_t datalen、uint8_t csEn);
static void GlobalBlockProtectionUnlock (void);
静态空复位(空);
静态空 WriteUnprotect (空);
静态空 WriteEnable (空);
静态 uint8_t FlashReadStatus (void);
static void configResetPin (void);


int main (空)

//volatile unsigned int i;

//WDTCTL = WDTPW+WDTHOLD;//停止看门狗计时器


// spiInit();

flashInit();

flashWrite (0、write_buf、1);
flashWrite (0、write_buf、1);

flashRead (0、read_buf、1);

/* UCA0IE |= UCRXIE;//启用 USCI_A0 RX 中断

P1OUT &=~0x02;//现在 SPI 信号已初始化、
P1OUT |= 0x02;//复位从器件

for (i=50;i>0;i--);//等待从设备初始化

MST_Data = 0x01;//初始化数据值
SLV_Data = 0x00;//

while (!(UCA0IFG&UCTXIFG));// USCI_A0 TX 缓冲器准备就绪?
UCA0TXBUF = MST_Data;//发送第一个字符

_bis_SR_register (LPM0_bits + GIE);// CPU 关闭,启用中断*/

void flashInit (void)

//初始化与闪存的 SPI 通信
spiInit();

//硬复位
FLASH_RST_OUT &=~(FLASH_RST_PIN);

// configResetPin ();
_DELAY_CYCLES (100000);

//onfigResetPin();

//__delay_cycles (100000);

FLASH_RST_OUT |= FLASH_RST_PIN;
_DELAY_CYCLES (100000);
FLASH_WP_OUT |= FLASH_WP_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;

//软复位:命令0x66、然后0x99
RESET();

///*测试:读取制造商 ID */
uint8_t command[4]={0};
uint8_t data[2]={0};
命令[0]= 0x90;
命令[1]= 0;
COMMAN[2]= 0;
命令[3]= 0;

spiTxRx (command、4、data、2、1);

WriteEnable();
WriteUnprotect();

/*芯片擦除*/
命令[0]= 0x60;//写入命令
spiTxRx (command、1、data、0、1);

_DELAY_CYCLES (250000);

命令[0]= 0x01;
命令[1]= 0x00;
spiTxRx (command、2、data、0、1);

命令[0]= 0x31;
命令[1]= 0x00;
spiTxRx (command、2、data、0、1);

命令[0]= 0x11;
命令[1]= 0x00;
spiTxRx (command、2、data、0、1);

//命令[0]= 0x05;
// spiTxRx (command、1、data、2、1);

//闪存加电前延迟10ms
_DELAY_CYCLES (250000);

空 flashWrite (uint32_t 地址、uint8_t*数据、uint16_t 大小)

//清除写保护
uint8_t 命令[5];
uint8_t dummy = 0;

WriteEnable();
WriteUnprotect();

/*此部分写入数据。 第一个字符是写入命令*/
命令[0]= 0x02;//写入命令
Command[1]=(无符号字符)(地址和0xFF000000 >> 24);
Command[2]=(unsigned char)(address & 0x0000 >> 16);
Command[3]=(无符号字符)(地址和0xFF00 >> 8);
Command[4]=(无符号字符)(地址& 0xFF);

Slave_CS_OUT &=~(SLAVE_CS_PIN);
_delay_cycles (8800);

spiTxRx (command、5、&dummy、0、0); //发送写入命令
spiTxRx (data、size、&dummy、0、0); //写入数据

_delay_cycles (8800);
SLAVE_CS_OUT |= SLAVE_CS_PIN;

while (FlashReadStatus ()= 0x03);//这确保读取操作已完成

_delay_cycles (3200);

void flashRead (uint32_t 地址、uint8_t*数据、uint16_t 大小)

uint8_t 命令[6];

/*本节读回数据。 第一个字符是读取命令*/
命令[0]= 0x0B;//发送读取命令
COMMAN[1]=(uint8_t)(地址和0xFF000000 >> 24);
COMMAN[2]=(uint8_t)(address& 0x0000 >> 16);
命令[3]=(uint8_t)(地址和0xFF00 >>8);
命令[4]=(uint8_t)(地址& 0xFF);
命令[5]= 0;

spiTxRx (command、6、data、size、1);//发送读取命令和读取数据

静态空 spiInit (空)

// volatile unsigned int i;

WDTCTL = WDTPW+WDTHOLD;//停止看门狗计时器

P1OUT |= 0x02;//为 LED 设置 P1.0
//为从器件复位设置 P1.1
P1DIR |= 0x03;//将 P1.0-2设置为输出方向
P3SEL |= BIT3+BIT4;// P3.3、4选项选择
P2SEL |= BIT7;// P2.7选项选择

UCA0CTL1 |= UCSWRST;//**将状态机置于复位状态**
UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;// 3引脚、8位 SPI 主器件
//时钟极性高,MSB
UCA0CTL1 |= UCSSEL_2;// SMCLK
UCA0BR0 = 0x02;///2
UCA0BR1 = 0;//
UCA0MCTL = 0;//无调制
UCA0CTL1 &=~UCSWRST;//**初始化 USCI 状态机**

返回;

静态空 spiTxRx (uint8_t *地址、uint32_t addlen、uint8_t *数据、uint32_t datalen、uint8_t csEn)

unsigned int i=0、j=0;
unsigned char 虚拟= 0;

如果(csEn = 1)

Slave_CS_OUT &=~(SLAVE_CS_PIN);
_delay_cycles (8800);

while (addlen-i)

while (!(UCA0IFG & UCTXIFG));
UCA0IFG &=~UCRXIFG;
UCA0TXBUF=addr[i++];
while (!(UCA0IFG & UCRXIFG));
虚拟= UCA0RXBUF;

虚拟= 0;

while (datalen-j)

while (!(UCA0IFG & UCTXIFG));
UCA0TXBUF=虚拟;
while (!(UCA0IFG & UCRXIFG));//等待字节被接收
DATA[j++]=UCA0RXBUF;

如果(csEn = 1)

_delay_cycles (8800);
SLAVE_CS_OUT |= SLAVE_CS_PIN;

返回;

静态空 GlobalBlockProtectionUnlock (空)

/*发送 global block unlock 命令*/
uint8_t 命令= 0x98;
uint8_t dummy = 0;

spiTxRx (&command、1、&dummy、0、1);

静态空复位(空)

/*发送 global block unlock 命令*/
uint8_t 命令= 0x66;
uint8_t dummy = 0;

spiTxRx (&command、1、&dummy、0、1);

命令= 0x99;
spiTxRx (&command、1、&dummy、0、1);

静态空 WriteUnprotect (空)

GlobalBlockProtectionUnlock();

_DELAY_CYCLES (250000);

静态空 WriteEnable (空)

/*发送写入启用命令*/
uint8_t 命令= 0x06;
uint8_t dummy = 0;

spiTxRx (&command、1、&dummy、0、1);

静态 uint8_t FlashReadStatus (空)

/*读取状态 REG-1 */
uint8_t 命令= 0x05;
uint8_t data = 0;

spiTxRx (&command、1、&data、1、1);

返回(uint8_t)数据;

静态空 configResetPin (空)

/*发送写入启用命令*/
uint8_t 命令[2];
uint8_t dummy = 0;

命令[0]= 0x11;
命令[1]= 0x80;

spiTxRx (命令、2、&dummy、0、1);


#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=USCI_A0_Vector
_interrupt void USCI_A0_ISR (void)
#Elif defined (_GNU_)
void __attribute__((中断(USCI_A0_Vector)) USCI_A0_ISR (void)
其他
错误编译器不受支持!
#endif

volatile unsigned int i;

switch (__evo_in_range (UCA0IV、4))

情况0:中断;//向量0 -无中断
情况2://向量2 - RXIFG
while (!(UCA0IFG&UCTXIFG));// USCI_A0 TX 缓冲器准备就绪?

if (UCA0RXBUF==SLV_Data)//测试正确的字符 RXd
P1OUT |= 0x01;//如果正确,亮起 LED
其他
P1OUT &=~0x01;//如果不正确,清除 LED

MST_Data++;//递增数据
SLV_Data++;
UCA0TXBUF = MST_Data;//发送下一个值

for (i = 20;i >0;i -);//将传输间隔时间添加到
//确保从机可以处理信息
中断;
情况4:中断;//向量4 - TXIFG
默认值:break;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请尽快回复

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好消息是 SPI 可以工作。 您可以 成功地与 W25Q16JV 通信。 对于 MSP430器件、我们不能提供任何帮助。

    我认为您需要检查您发送的命令是否正确。 您需要查看 W25Q16JV 的 UG。