我将 MSP430FR6877与外部闪存 W25Q16JV 搭配使用、
我正在使用 UCA0 SPI 进行通信、通信已启动并正在运行、我可以读取/写入状态寄存器和读取制造商 ID、例如、
但在存储器中读取/写入数据/代码仍然不起作用、
我尝试通过将5个字节写入闪存中的地址0来测试它、但是当我读取它们时、我会找到复位值"0xFF"、
代码如下所示:
1-初始化:
void flashInit (void) { //初始化与闪存 spiInit()的 SPI 通信; //硬复位 GPIO_setOutputLowOnPin (port_flash_RST、PIN_flash_RST); // configResetPin (); __delay_cycles (100000); GPIO_setOutputHighOnPin (port_flash_RST、 PIN_FLASH_RST); __DELAY_CYLES (100000); GPIO_setOutputHighOnPin (PORT_FLASH_WP、PIN_FLASH_WP); GPIO_setOutputHighOnPin (PORT_FLASH_CS、 PIN_FLASH_CS); //软复位:命令0x66,然后是0x99 复位(); ////*测试:读取制造商 ID */ uint8_t command[4]={0}; uint8_t data[2]={0}; 命令[0]= 0x90; 命令[1]= 0; 命令[2]= 0; 命令[3]= 0; spiTxRx (command、4、data、2、1); WriteEnable(); WriteUnprotect(); /*芯片擦除*/ COMMAN[0]= 0x60; //写入命令 spiTxRx (命令、1、数据、0、1); _DELAY_CYCLES (160000); 命令[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); // command[0]= 0x05; // spiTxRx (command、1、data、2、 1); //闪存加电前延迟10ms __DELAY_CYCLES (160000); }
2-写入:
void flashWrite (uint32_t address、uint8_t*数据、uint16_t size) { //清除写保护 uint8_t command[4]; uint8_t dummy = 0; WriteEnable(); WriteUnprotect(); /*此部分写入数据。 第一个字符是 WRITE 命令*/ COMMAN[0]= 0x02; //写入命令 命令命令[1]=(无符号字符)(地址>> 16); 命令[2]=(无符号字符)(地址>> 8); 命令[3]=(无符号字符)(地址>> 0); GPIO_setOutputLowOnPin (port_flash_CS、PIN_flash_CS); __delay_cycles (8800); spiTxRx (命令、4、&dummy、0、0); //发送写入命令 spiTxRx (data、size、&dummy、0、0); //写入数据 _DELAY_CYCLES (8800); GPIO_setOutputHighOnPin (PORT_FLASH_CS、PIN_FLASH_CS); while (FlashReadStatus ()= 0x03); //这确保读取操作完成 __delay_cycles (3200); }
3-读:
void flashRead (uint32_t address、uint8_t* data、uint16_t size) { uint8_t command[4]; /*本节回读数据。 第一个字符是读取命令*/ 命令[0]= 0x03; //send 读取命令 命令[1]=(uint8_t)(地址>> 16); 命令[2]=(uint8_t)(地址>> 8); 命令[3]=(uint8_t)(地址>> 0); spiTxRx (命令、4、数据、大小、 1); //发送读取命令和读取数据 }
4-其他使用的功能:
静态空 spiInit (void) { UCA0CTLW0 = UCSWRST; //**将状态机复位** UCA0CTLW0 |= UCMST + UCSYNC + UCCKPL + UCMSB;// 3引脚8位 SPI 主器件 MSB UCA0CTLW0 |= UCSSEL_2; // SMCLK 特定于器件 的 UCA0BR0 = 4; // CLK / 1 UCA0BR1 = 0; UCA0CTL1 &&~UCSWRST; return; } 静态空 spiTxRx (uint8_t * addr、uint32_t addlen、uint8_t *数据、uint32_t datalen、uint8_t csEn) { =0、 unsigned int char;i = 0;unsigned int if (csEn = 1) { GPIO_setOutputLowOnPin (PORT_FLASH_CS、PIN_FLASH_CS); _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; } if (csEn = 1) { _delay_cycles (8800); GPIO_setOutputHighOnPin (PORT_FLASH_CS、PIN_FLASH_CS); } return; } static void GlobalBlockProtectionUnlock (void) { //发送 global block unlock 命令*/ uint8_t 命令= 0x98; uint8_t dummy = 0; spitxRx (&command、1、&dummy、0、 1); } 静态空复位(void) { //发送 global 块解锁命令*/ uint8_t 命令= 0x66; uint8_t dummy = 0; spitxRx (&command、1、&dummy、0、 1); 命令= 0x99; spitxRx (&command、1、&dummy、0、 1); } 静态空 WriteUnprotect (void) { GlobalBlockProtectionUnlock(); __delay_cycles (160000); } 静态空 WriteEnable (void) { //*发送写入启用命令*/ uint8_t 命令= 0x06; uint8_t dummy = 0; spitTxRx (&command、1、&dummy、&0、 1); } 静态 uint8_t FlashReadStatus (void) { /*读取状态 reg-1 */ uint8_t 命令= 0x05; uint8_t 数据= 0; spitxRx (&command、1、&data、1、 1); 返回(uint8_t)数据; } 静态空 configResetPin (void) { //发送写入启用命令*/ uint8_t 命令[2]; uint8_t dummy = 0; 命令[0]= 0x11; 命令[1]= 0x80; spiTxRx (command、2、&dummy、 0、1); }