你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32-SPI读取串行FLASH

[复制链接]
STMCU小助手 发布时间:2022-2-3 19:00
SPI协议:是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD 等设备与MCU 间,要求通讯速率较高的场合。

物理层:
S S  ( Slave Select):从设备选择信号线,常称为片选信号线,也称为NSS、CS,以下用NSS 表示。当有多个SPI 从设备与SPI 主机相连时,设备的其它信号线SCK、MOSI及MISO 同时并联到相同的SPI 总线上,即无论有多少个从设备,都共同只使用这3 条总线;而每个从设备都有独立的这一条NSS 信号线,本信号线独占主机的一个引脚,即有多少个从设备,就有多少条片选信号线。I2C  协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;而SPI 协议中没有设备地址,它使用NSS 信号线来寻址,当主机要选择从设备时,把该从设备的NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI通讯。所以SPI通讯以NSS 线置低电平为开始信号,以NSS 线被拉高作为结束信号。

SCK (Serial Clock):时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如STM32 的SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。

MOSI (Master Output,Slave Input):主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机,只有这条线的信号由从机产生。
SPI设备之间的常用连线方式如下:

1424785-20180627201708179-223816288.png

协议层:
SPI 一共有四种通讯模式,它们的主要区别是总线空闲时SCK 的时钟状态以及数据采样时刻。为方便说明,在此引入“时钟极性CPOL”和“时钟相位CPHA”的概念。时钟极性CPOL 是指SPI 通讯设备处于空闲状态时,SCK 信号线的电平信号(即SPI 通讯开始前、NSS 线为高电平时SCK 的状态)。CPOL=0 时,SCK 在空闲状态时为低电平,CPOL=1 时,则相反。时钟相位CPHA 是指数据的采样的时刻,当CPHA=0 时,MOSI 或MISO 数据线上的信号将会在SCK 时钟线的“奇数边沿”被采样。当CPHA=1 时,数据线在SCK 的“偶数边沿”采样。

1424785-20180627201728482-474134694.png

bsp_spi_flash.h文件:
  1. #ifndef __SPI_FLASH_H
  2. #define __SPI_FLASH_H

  3. #include "stm32f10x.h"
  4. #include <stdio.h>
  5. #define  sFLASH_ID    0XEF4017
  6. #define  SPI_FLASH_PageSize   256
  7. #define  SPI_FLASH_PerWritePageSize 256
  8. //Flash命令定义
  9. #define W25X_WriteEnable              0x06
  10. #define W25X_WriteDisable              0x04
  11. #define W25X_ReadStatusReg            0x05
  12. #define W25X_WriteStatusReg            0x01
  13. #define W25X_ReadData                    0x03
  14. #define W25X_FastReadData              0x0B
  15. #define W25X_FastReadDual              0x3B
  16. #define W25X_PageProgram              0x02
  17. #define W25X_BlockErase                  0xD8
  18. #define W25X_SectorErase              0x20
  19. #define W25X_ChipErase                  0xC7
  20. #define W25X_PowerDown                  0xB9
  21. #define W25X_ReleasePowerDown        0xAB
  22. #define W25X_DeviceID                    0xAB
  23. #define W25X_ManufactDeviceID       0x90
  24. #define W25X_JedecDeviceID            0x9F
  25. //WIP(busy) 标志,Flash内部正在写入
  26. #define WIP_flag   0x01
  27. #define Dummy_Byte 0xFF
  28. //SPI接口定义
  29. #define FLASH_SPIx   SPI1
  30. #define FLASH_SPI_CLK   RCC_APB2Periph_SPI1
  31. //片选引脚
  32. #define FLASH_SPI_CS_CLK   RCC_APB2Periph_GPIOC
  33. #define FLASH_SPI_CS_PORT  GPIOC
  34. #define FLASH_SPI_CS_PIN   GPIO_Pin_0
  35. //SCK引脚
  36. #define FLASH_SPI_SCK_CLK  RCC_APB2Periph_GPIOA
  37. #define FLASH_SPI_SCK_PORT GPIOA
  38. #define FLASH_SPI_SCK_PIN  GPIO_Pin_5
  39. //MISO引脚
  40. #define FLASH_SPI_MISO_CLK  RCC_APB2Periph_GPIOA
  41. #define FLASH_SPI_MISO_PORT GPIOA
  42. #define FLASH_SPI_MISO_PIN  GPIO_Pin_6
  43. //MOSI引脚
  44. #define FLASH_SPI_MOSI_CLK  RCC_APB2Periph_GPIOA
  45. #define FLASH_SPI_MOSI_PORT GPIOA
  46. #define FLASH_SPI_MOSI_PIN  GPIO_Pin_7

  47. #define SPI_FLASH_CS_LOW()   GPIO_ResetBits(FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN)
  48. #define SPI_FLASH_CS_HIGH()  GPIO_SetBits( FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN )

  49. #define SPIT_FLAG_TIMEOUT         ((uint32_t)0x1000)
  50. #define SPIT_LONG_TIMEOUT         ((uint32_t)(10 * SPIT_FLAG_TIMEOUT))

  51. #define FLASH_DEBUG_ON         1

  52. #define FLASH_INFO(fmt,arg...)           printf("<<-FLASH-INFO->> "fmt"\n",##arg)
  53. #define FLASH_ERROR(fmt,arg...)          printf("<<-FLASH-ERROR->> "fmt"\n",##arg)
  54. #define FLASH_DEBUG(fmt,arg...)          do{\
  55.                                           if(FLASH_DEBUG_ON)\
  56.                                           printf("<<-FLASH-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\
  57.                                           }while(0)

  58. void SPI_FLASH_Init(void);
  59. void SPI_FLASH_SectorErase(u32 SectorAddr);
  60. void SPI_FLASH_BulkErase(void);
  61. void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
  62. void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
  63. void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
  64. u32 SPI_FLASH_ReadID(void);
  65. u32 SPI_FLASH_ReadDeviceID(void);
  66. void SPI_FLASH_StartReadSequence(up32 ReadAddr);
  67. void SPI_Flash_PowerDown(void);
  68. void SPI_Flash_WAKEUP(void);


  69. u8 SPI_FLASH_ReadByte(void);
  70. u8 SPI_FLASH_SendByte(u8 byte);
  71. u16 SPI_FLASH_SendHalfWord(u16 HalfWord);
  72. void SPI_FLASH_WriteEnable(void);
  73. void SPI_FLASH_WaitForWriteEnd(void);
  74. #endif
复制代码

bsp_spi_flash.c文件:
  1. #include "bsp_spi_flash.h"

  2. static __IO uint32_t  SPITimeout = SPIT_LONG_TIMEOUT;   
  3. static uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode);

  4. void SPI_FLASH_Init(void)
  5. {
  6.   SPI_InitTypeDef  SPI_InitStructure;
  7.   GPIO_InitTypeDef GPIO_InitStructure;
  8.     RCC_APB2PeriphClockCmd(FLASH_SPI_CLK, ENABLE );
  9.      RCC_APB2PeriphClockCmd(FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|
  10.         FLASH_SPI_MISO_PIN|FLASH_SPI_MOSI_PIN, ENABLE );
  11.   GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;
  12.   //配置片选
  13.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  15.   GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);
  16.   GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;
  17.   //配置SCK
  18.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  19.   GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);
  20.   //配置MISO
  21.   GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;
  22.   GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);
  23.   //配置MOSI
  24.   GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;
  25.   GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
  26.   //cs高电平,通讯停止
  27.   SPI_FLASH_CS_HIGH();
  28.   //SPI模式配置
  29.   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  30.   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  31.   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  32.   SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  33.   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  34.   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  35.   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  36.   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  37.   SPI_InitStructure.SPI_CRCPolynomial = 7;
  38.   SPI_Init(FLASH_SPIx , &SPI_InitStructure);
  39.   SPI_Cmd(FLASH_SPIx , ENABLE);
  40.    
  41. }
  42. //擦除FLASH
  43. void SPI_FLASH_SectorErase(u32 SectorAddr)
  44. {
  45.   SPI_FLASH_WriteEnable();
  46.   SPI_FLASH_WaitForWriteEnd();
  47.   SPI_FLASH_CS_LOW();
  48.   SPI_FLASH_SendByte(W25X_SectorErase);
  49.   SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  50.   SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  51.   SPI_FLASH_SendByte(SectorAddr & 0xFF);
  52.   SPI_FLASH_CS_HIGH();
  53.   SPI_FLASH_WaitForWriteEnd();
  54. }
  55. //擦除FLASH扇区
  56. void SPI_FLASH_BulkErase(void)
  57. {
  58.   SPI_FLASH_WriteEnable();
  59.   SPI_FLASH_CS_LOW();
  60.   SPI_FLASH_SendByte(W25X_ChipErase);
  61.   SPI_FLASH_CS_HIGH();
  62.   SPI_FLASH_WaitForWriteEnd();
  63. }

  64. //按页写入数据
  65. void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
  66. {
  67.   SPI_FLASH_WriteEnable();
  68.   SPI_FLASH_CS_LOW();
  69.   SPI_FLASH_SendByte(W25X_PageProgram);
  70.   SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  71.   SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  72.   SPI_FLASH_SendByte(WriteAddr & 0xFF);
  73.   if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
  74.   {
  75.      NumByteToWrite = SPI_FLASH_PerWritePageSize;
  76.      FLASH_ERROR("SPI_FLASH_PageWrite too large!");
  77.   }
  78.   while (NumByteToWrite--)
  79.   {
  80.     SPI_FLASH_SendByte(*pBuffer);
  81.     pBuffer++;
  82.   }
  83.   SPI_FLASH_CS_HIGH();
  84.   SPI_FLASH_WaitForWriteEnd();
  85. }
  86. //写数据
  87. void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
  88. {
  89.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
  90.   Addr = WriteAddr % SPI_FLASH_PageSize;
  91.   count = SPI_FLASH_PageSize - Addr;
  92.   NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
  93.   NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
  94.   if (Addr == 0)
  95.   {
  96.     if (NumOfPage == 0)
  97.     {
  98.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  99.     }
  100.     else
  101.     {
  102.       while (NumOfPage--)
  103.       {
  104.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
  105.         WriteAddr +=  SPI_FLASH_PageSize;
  106.         pBuffer += SPI_FLASH_PageSize;
  107.       }
  108.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  109.     }
  110.   }
  111.   else
  112.   {
  113.     if (NumOfPage == 0)
  114.     {
  115.       if (NumOfSingle > count)
  116.       {
  117.         temp = NumOfSingle - count;
  118.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
  119.                
  120.         WriteAddr +=  count;
  121.         pBuffer += count;
  122.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
  123.       }
  124.       else
  125.       {
  126.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  127.       }
  128.     }
  129.     else
  130.     {
  131.       NumByteToWrite -= count;
  132.       NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
  133.       NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
  134.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
  135.       WriteAddr +=  count;
  136.       pBuffer += count;
  137.       while (NumOfPage--)
  138.       {
  139.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
  140.         WriteAddr +=  SPI_FLASH_PageSize;
  141.         pBuffer += SPI_FLASH_PageSize;
  142.       }
  143.       if (NumOfSingle != 0)
  144.       {
  145.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  146.       }
  147.     }
  148.   }
  149. }

  150. //读数据
  151. void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
  152. {
  153.   SPI_FLASH_CS_LOW();
  154.   SPI_FLASH_SendByte(W25X_ReadData);
  155.   SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  156.   SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  157.   SPI_FLASH_SendByte(ReadAddr & 0xFF);
  158.   while (NumByteToRead--)
  159.   {
  160.     *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
  161.     pBuffer++;
  162.   }
  163.   SPI_FLASH_CS_HIGH();
  164. }
  165. //读取ID
  166. u32 SPI_FLASH_ReadID(void)
  167. {
  168.   u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
  169.   SPI_FLASH_CS_LOW();
  170.   SPI_FLASH_SendByte(W25X_JedecDeviceID);
  171.   Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
  172.   Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
  173.   Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
  174.   SPI_FLASH_CS_HIGH();
  175.     Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  176.   return Temp;
  177. }
  178. //读取DeviceID
  179. u32 SPI_FLASH_ReadDeviceID(void)
  180. {
  181.   u32 Temp = 0;
  182.   SPI_FLASH_CS_LOW();
  183.   SPI_FLASH_SendByte(W25X_DeviceID);
  184.   SPI_FLASH_SendByte(Dummy_Byte);
  185.   SPI_FLASH_SendByte(Dummy_Byte);
  186.   SPI_FLASH_SendByte(Dummy_Byte);
  187.   Temp = SPI_FLASH_SendByte(Dummy_Byte);
  188.   SPI_FLASH_CS_HIGH();

  189.   return Temp;
  190. }

  191. void SPI_FLASH_StartReadSequence(u32 ReadAddr)
  192. {
  193.   SPI_FLASH_CS_LOW();
  194.   SPI_FLASH_SendByte(W25X_ReadData);
  195.   SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  196.   SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  197.   SPI_FLASH_SendByte(ReadAddr & 0xFF);
  198. }

  199. u8 SPI_FLASH_ReadByte(void)
  200. {
  201.   return (SPI_FLASH_SendByte(Dummy_Byte));
  202. }

  203. u8 SPI_FLASH_SendByte(u8 byte)
  204. {
  205.      SPITimeout = SPIT_FLAG_TIMEOUT;
  206.   while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_TXE) == RESET)
  207.     {
  208.     if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);
  209.    }
  210.   SPI_I2S_SendData(FLASH_SPIx , byte);

  211.     SPITimeout = SPIT_FLAG_TIMEOUT;
  212.   while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_RXNE) == RESET)
  213.   {
  214.     if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);
  215.    }
  216.   return SPI_I2S_ReceiveData(FLASH_SPIx );
  217. }

  218. u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
  219. {
  220.       SPITimeout = SPIT_FLAG_TIMEOUT;
  221.   while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_TXE) == RESET)
  222.     {
  223.     if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(2);
  224.    }
  225.   SPI_I2S_SendData(FLASH_SPIx , HalfWord);

  226.      SPITimeout = SPIT_FLAG_TIMEOUT;
  227.   while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_RXNE) == RESET)
  228.      {
  229.     if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(3);
  230.    }
  231.   return SPI_I2S_ReceiveData(FLASH_SPIx );
  232. }

  233. void SPI_FLASH_WriteEnable(void)
  234. {
  235.   SPI_FLASH_CS_LOW();
  236.   SPI_FLASH_SendByte(W25X_WriteEnable);
  237.   SPI_FLASH_CS_HIGH();
  238. }

  239. void SPI_FLASH_WaitForWriteEnd(void)
  240. {
  241.   u8 FLASH_Status = 0;
  242.   SPI_FLASH_CS_LOW();
  243.   SPI_FLASH_SendByte(W25X_ReadStatusReg);
  244.   do
  245.   {
  246.     FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);     
  247.   }
  248.   while ((FLASH_Status & WIP_flag ) == SET);  
  249.   SPI_FLASH_CS_HIGH();
  250. }

  251. void SPI_Flash_PowerDown(void)   
  252. {
  253.   SPI_FLASH_CS_LOW();
  254.   SPI_FLASH_SendByte(W25X_PowerDown);
  255.   SPI_FLASH_CS_HIGH();
  256. }   

  257. void SPI_Flash_WAKEUP(void)   
  258. {
  259.   SPI_FLASH_CS_LOW();
  260.   SPI_FLASH_SendByte(W25X_ReleasePowerDown);
  261.   SPI_FLASH_CS_HIGH();
  262. }   
  263.    
  264. static  uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)
  265. {
  266.   FLASH_ERROR("SPI等待超时!errorCode = %d",errorCode);
  267.   return 0;
  268. }
复制代码

main.c文件:
  1. #include "stm32f10x.h"
  2. #include "bsp_usart.h"
  3. #include "bsp_led.h"
  4. #include "bsp_spi_flash.h"


  5. typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;

  6. #define TxBufferSize1   (countof(TxBuffer1) - 1)
  7. #define RxBufferSize1   (countof(TxBuffer1) - 1)
  8. #define countof(a)      (sizeof(a) / sizeof(*(a)))
  9. #define  BufferSize (countof(Tx_Buffer)-1)

  10. #define  FLASH_WriteAddress     0x00000
  11. #define  FLASH_ReadAddress      FLASH_WriteAddress
  12. #define  FLASH_SectorToErase    FLASH_WriteAddress

  13. uint8_t Tx_Buffer[] = "hello stm32!!!\r\n";
  14. uint8_t Rx_Buffer[BufferSize];

  15. __IO uint32_t DeviceID = 0;
  16. __IO uint32_t FlashID = 0;
  17. __IO TestStatus TransferStatus1 = FAILED;

  18. void Delay(__IO uint32_t nCount);
  19. TestStatus Buffercmp(uint8_t* pBuffer1,uint8_t* pBuffer2, uint16_t BufferLength);

  20. int main(void)
  21. {     
  22.     LED_GPIO_Config();
  23.     USART_Config();
  24.     printf("\r\n 这是一个8M的串行flash W25Q64实验!\r\n");
  25.     SPI_FLASH_Init();
  26.     DeviceID = SPI_FLASH_ReadDeviceID();   
  27.     Delay( 200 );
  28.     FlashID = SPI_FLASH_ReadID();   
  29.     printf("\r\n FlashID is 0x%X,\
  30.     Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);
  31.     if (FlashID == sFLASH_ID)
  32.     {   
  33.         printf("\r\n检测到串行flash W25Q64\r\n");
  34.         SPI_FLASH_SectorErase(FLASH_SectorToErase);         
  35.         SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);        
  36.         printf("\r\n 写入的数据为:%s \r\t", Tx_Buffer);
  37.         SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
  38.         printf("\r\n 读出的数据为\r\n", Rx_Buffer);
  39.         TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
  40.         if( PASSED == TransferStatus1 )
  41.         {
  42.             green(ON);
  43.             printf("\r\n 测试成功!\n\r");
  44.         }
  45.         else
  46.         {        
  47.             red(ON);
  48.             printf("\r\n 测试失败\n\r");
  49.         }
  50.     }// if (FlashID == sFLASH_ID)
  51.     else// if (FlashID == sFLASH_ID)
  52.     {
  53.         red(ON);
  54.         printf("\r\n 获取不到W25Q64 ID!\n\r");
  55.     }
  56.    
  57.     while(1);  
  58. }
  59. //比较两个缓冲区的内容是否一样
  60. TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
  61. {
  62.   while(BufferLength--)
  63.   {
  64.     if(*pBuffer1 != *pBuffer2)
  65.     {
  66.       return FAILED;
  67.     }
  68.     pBuffer1++;
  69.     pBuffer2++;
  70.   }
  71.   return PASSED;
  72. }

  73. void Delay(__IO uint32_t nCount)
  74. {
  75.   for(; nCount != 0; nCount--);
  76. }
复制代码

收藏 评论0 发布时间:2022-2-3 19:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版