Hi,
I am using custom board with nRF52832.In the custom board, there is a SPI flash to storage some data.
I can read or write the flash normally at the beginning,but whenI create a timer to read/write the flash, the SPI interface will never work normally again. The spi_xfer_done will never turn to true.
Before into for(;;), I can read/wirite the data normally in W25QXX_Init() or W25QXX_test().But when I create a 1s timer to read/write again(W25QXX_test()), the RTT Viewer will always print "SPI WRITE".
BTW, my application is based on examples\ble_peripheral\ble_app_uart\pca10040\s112 and I have closed the bspxx to avoid the conflict of GPIO. To find the reason of SPI error, I added LOG in SPI driver when create the timer.
Here is the application code.
int main(void) { // bool erase_bonds; // ret_code_t err_code; // Initialize. log_init(); // Initialize the async SVCI interface to bootloader before any interrupts are enabled. // err_code = ble_dfu_buttonless_async_svci_init(); // APP_ERROR_CHECK(err_code); timers_init(); // buttons_leds_init(&erase_bonds); power_management_init(); ble_stack_init(); // sd_power_dcdc_mode_set(NRF_POWER_DCDC_DISABLE); gap_params_init(); gatt_init(); services_init(); advertising_init(); conn_params_init(); m_application_config(); m_timer_init(); // m_work_upgrade_event(); // Start execution. NRF_LOG_INFO("Debug logging for UART over RTT started."); advertising_start(); W25QXX_test(); // Enter main loop. for (;;) { // m_work_nus_event(); idle_state_handle(); } } /**@brief Function for configurate IO. * * @details */ void m_application_config(void) { nrf_gpio_cfg_output(M_OUT_OE_PIN); nrf_gpio_pin_set(M_OUT_OE_PIN); nrf_gpio_cfg_output(M_OUT_RESET_PIN); nrf_gpio_pin_set(M_OUT_RESET_PIN); nrf_gpio_cfg_output(M_OUT_BOOT_PIN); nrf_gpio_pin_clear(M_OUT_BOOT_PIN); W25QXX_Init(); } void W25QXX_Init(void) { uint8_t flash_w_data[9]="12345678"; uint8_t flash_r_data[8]={0}; m_spi_init(); //³õʼ»¯SPI W25QXX_PowerDown(); W25QXX_WAKEUP(); W25QXX_TYPE=W25QXX_ReadID(); //¶ÁÈ¡FLASH ID. NRF_LOG_INFO("W25QXX ID: %04x",W25QXX_TYPE); W25QXX_Write(flash_w_data,0,8); W25QXX_Write(flash_w_data,8,8); W25QXX_Write(flash_w_data,16,8); W25QXX_Write(flash_w_data,24,8); W25QXX_Read(flash_r_data,0,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,8,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,16,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,24,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Erase_Chip(); } void W25QXX_test(void) { uint8_t flash_w_data[9]="TESTBLE!"; uint8_t flash_r_data[8]={0}; W25QXX_PowerDown(); W25QXX_WAKEUP(); W25QXX_Write(flash_w_data,0,8); W25QXX_Write(flash_w_data,8,8); W25QXX_Write(flash_w_data,16,8); W25QXX_Write(flash_w_data,24,8); W25QXX_Read(flash_r_data,0,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,8,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,16,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,24,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); } /**@brief Function for transmit device log imformation. */ static void m_log_device_app_timeout_handler(void * p_context) { UNUSED_PARAMETER(p_context); uint8_t num_zh = 0; uint8_t num_yu = 0; uint8_t log_data[200]; W25QXX_test(); // if(m_nus_data.log_status == true) // { // if((m_nus_data.uart_num!=0)&&(m_nus_data.uart_num<=200)) // { // m_nus_transmit_data(m_nus_data.uart_buff,m_nus_data.uart_num,NUS_NOTIFY_LOG); //// NRF_LOG_HEXDUMP_INFO(m_nus_data.uart_buff,m_nus_data.uart_num); // }else if(m_nus_data.uart_num>200) // { // num_zh = m_nus_data.uart_num/200;//取整 // num_yu = m_nus_data.uart_num%200;//取余 // for(int i=0;i<num_zh;i++) // { // for(int j=0;j<200;j++) // { // log_data[j] = m_nus_data.uart_buff[200*i+j]; // } // m_nus_transmit_data(log_data,200,NUS_NOTIFY_LOG); // } // if(num_yu!=0)//最后一条数据 // { // for(int k=0;k<num_yu;k++) // { // log_data[k] = m_nus_data.uart_buff[200*num_zh+k]; // } // m_nus_transmit_data(log_data,num_yu,NUS_NOTIFY_LOG); //// NRF_LOG_HEXDUMP_INFO(log_data,num_yu); // } // } // }else if(m_nus_data.log_status == false) // { // m_log_timer_stop(); // } // m_nus_data.uart_num = 0; } /**@brief Function for user timer. */ void m_timer_init(void) { ret_code_t err_code; // Create log timer. err_code = app_timer_create(&m_log_timer_id, APP_TIMER_MODE_REPEATED, m_log_device_app_timeout_handler); APP_ERROR_CHECK(err_code); err_code = app_timer_create(&m_cmd_timer_id, APP_TIMER_MODE_SINGLE_SHOT, m_command_timeout_handler); APP_ERROR_CHECK(err_code); err_code = app_timer_start(m_log_timer_id,M_LOG_INTERVAL,NULL); APP_ERROR_CHECK(err_code); }
Here is the SPI interface.
#include "w25qxx.h" #include "nrf_drv_spi.h" #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #define SPI_INSTANCE 0 /**< SPI instance index. */ static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */ static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */ uint16_t W25QXX_TYPE=W25Q128; //ĬÈÏÊÇW25Q128 uint8_t SPI_Tx_Buf[8]; uint8_t SPI_Rx_Buf[8]; volatile uint8_t SPIReadLength, SPIWriteLength; /** * @brief SPI user event handler. * @param event */ void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context) { spi_xfer_done = true; } /** * @brief SPI init. * @param */ static void m_spi_init(void) { nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; // spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; spi_config.miso_pin = SPI_MOSI_PIN; spi_config.mosi_pin = SPI_MISO_PIN; spi_config.sck_pin = SPI_SCK_PIN; nrf_gpio_cfg_output(SPI_SS_PIN); nrf_gpio_pin_clear(SPI_SS_PIN); //ƬѡÎÞЧ APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL)); nrf_delay_ms(200); nrf_gpio_pin_set(SPI_SS_PIN); //ƬѡÎÞЧ nrf_delay_ms(200); } /** * @brief SPI read/write byte. * @param */ void W25QXX_write_reg(int data) { spi_xfer_done = false; SPIWriteLength = 1; SPIReadLength = 0; SPI_Tx_Buf[0] = data; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, SPI_Tx_Buf, SPIWriteLength, SPI_Rx_Buf, SPIReadLength)); while (!spi_xfer_done) { __WFE(); NRF_LOG_INFO("SPI Write."); NRF_LOG_FLUSH(); } } uint8_t W25QXX_read_reg(int reg) { spi_xfer_done = false; SPI_Tx_Buf[0] = reg; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, SPI_Tx_Buf, 0, SPI_Rx_Buf,1)); while (!spi_xfer_done) { __WFE(); NRF_LOG_INFO("SPI Read."); NRF_LOG_FLUSH(); } return SPI_Rx_Buf[0]; } //4KbytesΪһ¸öSector //16¸öÉÈÇøΪ1¸öBlock //W25Q128 //ÈÝÁ¿Îª16M×Ö½Ú,¹²ÓÐ128¸öBlock,4096¸öSector //³õʼ»¯SPI FLASHµÄIO¿Ú void W25QXX_Init(void) { uint8_t flash_w_data[9]="12345678"; uint8_t flash_r_data[8]={0}; m_spi_init(); //³õʼ»¯SPI W25QXX_PowerDown(); W25QXX_WAKEUP(); W25QXX_TYPE=W25QXX_ReadID(); //¶ÁÈ¡FLASH ID. NRF_LOG_INFO("W25QXX ID: %04x",W25QXX_TYPE); W25QXX_Write(flash_w_data,0,8); W25QXX_Write(flash_w_data,8,8); W25QXX_Write(flash_w_data,16,8); W25QXX_Write(flash_w_data,24,8); W25QXX_Read(flash_r_data,0,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,8,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,16,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,24,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Erase_Chip(); } void W25QXX_test(void) { uint8_t flash_w_data[9]="TESTBLE!"; uint8_t flash_r_data[8]={0}; W25QXX_PowerDown(); W25QXX_WAKEUP(); W25QXX_Write(flash_w_data,0,8); W25QXX_Write(flash_w_data,8,8); W25QXX_Write(flash_w_data,16,8); W25QXX_Write(flash_w_data,24,8); W25QXX_Read(flash_r_data,0,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,8,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,16,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); W25QXX_Read(flash_r_data,24,8); NRF_LOG_HEXDUMP_INFO(flash_r_data,8); } //¶ÁÈ¡W25QXXµÄ״̬¼Ä´æÆ÷ //BIT7 6 5 4 3 2 1 0 //SPR RV TB BP2 BP1 BP0 WEL BUSY //SPR:ĬÈÏ0,״̬¼Ä´æÆ÷±£»¤Î»,ÅäºÏWPʹÓà //TB,BP2,BP1,BP0:FLASHÇøÓòд±£»¤ÉèÖà //WEL:дʹÄÜËø¶¨ //BUSY:æ±ê¼Çλ(1,æ;0,¿ÕÏÐ) //ĬÈÏ:0x00 uint8_t W25QXX_ReadSR(void) { uint8_t byte=0; SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_ReadStatusReg); //·¢ËͶÁȡ״̬¼Ä´æÆ÷ÃüÁî byte=W25QXX_read_reg(0Xff); //¶ÁÈ¡Ò»¸ö×Ö½Ú SPI_NSS_HIGH(); //È¡ÏûƬѡ return byte; } //дW25QXX״̬¼Ä´æÆ÷ //Ö»ÓÐSPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)¿ÉÒÔд!!! void W25QXX_Write_SR(uint8_t sr) { SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_WriteStatusReg); //·¢ËÍдȡ״̬¼Ä´æÆ÷ÃüÁî W25QXX_write_reg(sr); //дÈëÒ»¸ö×Ö½Ú SPI_NSS_HIGH(); //È¡ÏûƬѡ } //W25QXXдʹÄÜ //½«WELÖÃλ void W25QXX_Write_Enable(void) { SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_WriteEnable); //·¢ËÍдʹÄÜ SPI_NSS_HIGH(); //È¡ÏûƬѡ } //W25QXXд½ûÖ¹ //½«WELÇåÁã void W25QXX_Write_Disable(void) { SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_WriteDisable); //·¢ËÍд½ûÖ¹Ö¸Áî SPI_NSS_HIGH(); //È¡ÏûƬѡ } //¶ÁȡоƬID //·µ»ØÖµÈçÏÂ: //0XEF13,±íʾоƬÐͺÅΪW25Q80 //0XEF14,±íʾоƬÐͺÅΪW25Q16 //0XEF15,±íʾоƬÐͺÅΪW25Q32 //0XEF16,±íʾоƬÐͺÅΪW25Q64 //0XEF17,±íʾоƬÐͺÅΪW25Q128 uint16_t W25QXX_ReadID(void) { uint16_t Temp = 0; SPI_NSS_LOW(); W25QXX_write_reg(0x90);//·¢ËͶÁÈ¡IDÃüÁî W25QXX_write_reg(0x00); W25QXX_write_reg(0x00); W25QXX_write_reg(0x00); Temp|=W25QXX_read_reg(0xFF)<<8; Temp|=W25QXX_read_reg(0xFF); SPI_NSS_HIGH(); return Temp; } //¶ÁÈ¡SPI FLASH //ÔÚÖ¸¶¨µØÖ·¿ªÊ¼¶ÁÈ¡Ö¸¶¨³¤¶ÈµÄÊý¾Ý //pBuffer:Êý¾Ý´æ´¢Çø //ReadAddr:¿ªÊ¼¶ÁÈ¡µÄµØÖ·(24bit) //NumByteToRead:Òª¶ÁÈ¡µÄ×Ö½ÚÊý(×î´ó65535) void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead) { uint16_t i; SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_ReadData); //·¢ËͶÁÈ¡ÃüÁî W25QXX_write_reg((uint8_t)((ReadAddr)>>16)); //·¢ËÍ24bitµØÖ· W25QXX_write_reg((uint8_t)((ReadAddr)>>8)); W25QXX_write_reg((uint8_t)ReadAddr); for(i=0;i<NumByteToRead;i++) { pBuffer[i]=W25QXX_read_reg(0XFF); //Ñ»·¶ÁÊý } SPI_NSS_HIGH(); } //SPIÔÚÒ»Ò³(0~65535)ÄÚдÈëÉÙÓÚ256¸ö×Ö½ÚµÄÊý¾Ý //ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´Èë×î´ó256×Ö½ÚµÄÊý¾Ý //pBuffer:Êý¾Ý´æ´¢Çø //WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit) //NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó256),¸ÃÊý²»Ó¦¸Ã³¬¹ý¸ÃÒ³µÄÊ£Óà×Ö½ÚÊý!!! void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) { uint16_t i; W25QXX_Write_Enable(); //SET WEL SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_PageProgram); //·¢ËÍдҳÃüÁî W25QXX_write_reg((uint8_t)((WriteAddr)>>16)); //·¢ËÍ24bitµØÖ· W25QXX_write_reg((uint8_t)((WriteAddr)>>8)); W25QXX_write_reg((uint8_t)WriteAddr); for(i=0;i<NumByteToWrite;i++)W25QXX_write_reg(pBuffer[i]);//Ñ»·Ð´Êý SPI_NSS_HIGH(); //È¡ÏûƬѡ W25QXX_Wait_Busy(); //µÈ´ýдÈë½áÊø } //ÎÞ¼ìÑéдSPI FLASH //±ØÐëÈ·±£ËùдµÄµØÖ··¶Î§ÄÚµÄÊý¾ÝÈ«²¿Îª0XFF,·ñÔòÔÚ·Ç0XFF´¦Ð´ÈëµÄÊý¾Ý½«Ê§°Ü! //¾ßÓÐ×Ô¶¯»»Ò³¹¦ÄÜ //ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´ÈëÖ¸¶¨³¤¶ÈµÄÊý¾Ý,µ«ÊÇҪȷ±£µØÖ·²»Ô½½ç! //pBuffer:Êý¾Ý´æ´¢Çø //WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit) //NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó65535) //CHECK OK void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) { uint16_t pageremain; pageremain=256-WriteAddr%256; //µ¥Ò³Ê£ÓàµÄ×Ö½ÚÊý if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//²»´óÓÚ256¸ö×Ö½Ú while(1) { W25QXX_Write_Page(pBuffer,WriteAddr,pageremain); if(NumByteToWrite==pageremain)break;//дÈë½áÊøÁË else //NumByteToWrite>pageremain { pBuffer+=pageremain; WriteAddr+=pageremain; NumByteToWrite-=pageremain; //¼õÈ¥ÒѾдÈëÁ˵Ä×Ö½ÚÊý if(NumByteToWrite>256)pageremain=256; //Ò»´Î¿ÉÒÔдÈë256¸ö×Ö½Ú else pageremain=NumByteToWrite; //²»¹»256¸ö×Ö½ÚÁË } }; } //дSPI FLASH //ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´ÈëÖ¸¶¨³¤¶ÈµÄÊý¾Ý //¸Ãº¯Êý´ø²Á³ý²Ù×÷! //pBuffer:Êý¾Ý´æ´¢Çø //WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit) //NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó65535) uint8_t W25QXX_BUFFER[4096]; void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) { uint32_t secpos; uint16_t secoff; uint16_t secremain; uint16_t i; uint8_t * W25QXX_BUF; W25QXX_BUF=W25QXX_BUFFER; secpos=WriteAddr/4096;//ÉÈÇøµØÖ· secoff=WriteAddr%4096;//ÔÚÉÈÇøÄÚµÄÆ«ÒÆ secremain=4096-secoff;//ÉÈÇøÊ£Óà¿Õ¼ä´óС //printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//²âÊÔÓà if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//²»´óÓÚ4096¸ö×Ö½Ú while(1) { W25QXX_Read(W25QXX_BUF,secpos*4096,4096);//¶Á³öÕû¸öÉÈÇøµÄÄÚÈÝ for(i=0;i<secremain;i++)//УÑéÊý¾Ý { if(W25QXX_BUF[secoff+i]!=0XFF)break;//ÐèÒª²Á³ý } if(i<secremain)//ÐèÒª²Á³ý { W25QXX_Erase_Sector(secpos);//²Á³ýÕâ¸öÉÈÇø for(i=0;i<secremain;i++) //¸´ÖÆ { W25QXX_BUF[i+secoff]=pBuffer[i]; } W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//дÈëÕû¸öÉÈÇø }else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);//дÒѾ²Á³ýÁ˵Ä,Ö±½ÓдÈëÉÈÇøÊ£ÓàÇø¼ä. if(NumByteToWrite==secremain)break;//дÈë½áÊøÁË else//дÈëδ½áÊø { secpos++;//ÉÈÇøµØÖ·Ôö1 secoff=0;//Æ«ÒÆλÖÃΪ0 pBuffer+=secremain; //Ö¸ÕëÆ«ÒÆ WriteAddr+=secremain;//дµØÖ·Æ«ÒÆ NumByteToWrite-=secremain; //×Ö½ÚÊýµÝ¼õ if(NumByteToWrite>4096)secremain=4096; //ÏÂÒ»¸öÉÈÇø»¹ÊÇд²»Íê else secremain=NumByteToWrite; //ÏÂÒ»¸öÉÈÇø¿ÉÒÔдÍêÁË } }; } //²Á³ýÕû¸öоƬ //µÈ´ýʱ¼ä³¬³¤... void W25QXX_Erase_Chip(void) { W25QXX_Write_Enable(); //SET WEL W25QXX_Wait_Busy(); SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_ChipErase); //·¢ËÍƬ²Á³ýÃüÁî SPI_NSS_HIGH(); //È¡ÏûƬѡ W25QXX_Wait_Busy(); //µÈ´ýоƬ²Á³ý½áÊø NRF_LOG_INFO("Erase flash W25QXX."); } //²Á³ýÒ»¸öÉÈÇø //Dst_Addr:ÉÈÇøµØÖ· ¸ù¾Ýʵ¼ÊÈÝÁ¿ÉèÖà //²Á³ýÒ»¸öɽÇøµÄ×îÉÙʱ¼ä:150ms void W25QXX_Erase_Sector(uint32_t Dst_Addr) { //¼àÊÓfalsh²Á³ýÇé¿ö,²âÊÔÓà // printf("fe:%x\r\n",Dst_Addr); Dst_Addr*=4096; W25QXX_Write_Enable(); //SET WEL W25QXX_Wait_Busy(); SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_SectorErase); //·¢ËÍÉÈÇø²Á³ýÖ¸Áî W25QXX_write_reg((uint8_t)((Dst_Addr)>>16)); //·¢ËÍ24bitµØÖ· W25QXX_write_reg((uint8_t)((Dst_Addr)>>8)); W25QXX_write_reg((uint8_t)Dst_Addr); SPI_NSS_HIGH(); //È¡ÏûƬѡ W25QXX_Wait_Busy(); //µÈ´ý²Á³ýÍê³É } //µÈ´ý¿ÕÏÐ void W25QXX_Wait_Busy(void) { while((W25QXX_ReadSR()&0x01)==0x01); // µÈ´ýBUSYλÇå¿Õ } //½øÈëµôµçģʽ void W25QXX_PowerDown(void) { SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_PowerDown); //·¢Ë͵ôµçÃüÁî SPI_NSS_HIGH(); //È¡ÏûƬѡ nrf_delay_us(30); //µÈ´ýTDP£¬¸ù¾ÝdatasheetÉèÖà } //»½ÐÑ void W25QXX_WAKEUP(void) { SPI_NSS_LOW(); //ʹÄÜÆ÷¼þ W25QXX_write_reg(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB SPI_NSS_HIGH(); //È¡ÏûƬѡ nrf_delay_us(30); //µÈ´ýTRES1£¬¸ù¾ÝdatasheetÉèÖà }