[开发板与模块] 【ESK32-30519 + ESK32-21001测评】03.I2C+EEPROM & SPI+SPI FLASH

[复制链接]
 楼主| xld0932 发表于 2022-10-10 17:26 | 显示全部楼层 |阅读模式
<
本帖最后由 xld0932 于 2022-10-10 17:30 编辑

HT32F54253 MCU带有3个硬件I2C接口和2个硬件SPI接口,具体的特性如下所示:

内部集成电路——I2C
支持高达 1 MHz 频率的主从模式
提供仲裁功能和时钟同步功能
支持 7-bit 10-bit 寻址模式和广播呼叫寻址
可屏蔽地址功能支持多种从机寻址模式
I2C 模块是一个允许与外部 I2C 接口通信的内部电路,此外部 I2C 接口是一个符合工业标准的用于连接外部硬件的两线串行接口。这两条串行线被称为串行数据线 SDA 和串行时钟线 SCLI2C
模块提供三种数据传输速率:即标准模式下的 100 kHz、快速模式下的 400 kHz 和高速模式下的1 MHzSCL 周期产生寄存器用于设置不同的占空比得到不同的 SCL 脉冲。
SDA 线是一条双向数据线,它连接整个 I2C 总线,在主机和从机之间用于数据的发送和接收。 I2C模块还具有仲裁检测功能和时钟同步,可防止多个主机试图同时传送数据到 I2C 总线的情况。

串行外设接口——SPI
支持主机和从机模式
主机模式频率高达 (fPCLK/2) MHz,从机模式频率高达 (fPCLK/3) MHz
▆ FIFO 深度: 8
多个主机和多个从机工作模式
串行外设接口
SPI 使用 SPI 协议可在主机和从机模式下进行数据发送和接收。 SPI 接口使用 4 个引脚,其中有串行数据输入和输出线, MISO MOSI,时钟线 SCK 和从机选择线 SELSPI 作为主机使用,用 SEL SCK 信号控制数据流来说明数据通信启动和数据采样率。要接收数据字节,数据流在特定的时钟边沿时被锁存且存储在数据寄存器或 RX FIFO。数据发送也是通过类似的方式,但以相反的顺序。模式故障检测功能使其适用于多主机应用。


原理图
  • ESK32-30519
5.png
  • ESK32-21001
6.png


实现功能
通过硬件I2C读写扩展板板载的EEPROM芯片,写入随机数据后再进行回读,比较写入数据和读出数据是否相一致;通过硬件SPI操作扩展板板载的SPI FLASH芯片,移植SFUD软件包组件实现对SPI FLASH的读、写、擦除等操作。


实现代码
  • EEPROM
  1. /* Define to prevent recursive inclusion -------------------------------------*/
  2. #define __EEPROM_C__


  3. /* Includes ------------------------------------------------------------------*/
  4. #include "EEPROM.h"


  5. /* Private typedef -----------------------------------------------------------*/
  6. /* Private define ------------------------------------------------------------*/
  7. /* Private macro -------------------------------------------------------------*/
  8. /* Private variables ---------------------------------------------------------*/
  9. /* Private function prototypes -----------------------------------------------*/
  10. /* Private functions ---------------------------------------------------------*/


  11. /* Exported variables --------------------------------------------------------*/
  12. /* Exported function prototypes ----------------------------------------------*/


  13. /*******************************************************************************
  14. * [url=home.php?mod=space&uid=247401]@brief[/url]      
  15. * @param      
  16. * @retval      
  17. * [url=home.php?mod=space&uid=93590]@Attention[/url]   
  18. *******************************************************************************/
  19. void _I2C_EEPROM_AckPolling(void)
  20. {
  21.     uint32_t reg;

  22.     /* wait if bus busy */
  23.     while(I2C_GetFlagStatus(HT_I2C1, I2C_FLAG_BUSBUSY));

  24.     while(1)
  25.     {
  26.         /* send slave address */
  27.         I2C_TargetAddressConfig(HT_I2C1, I2C_EEPROM_DEV_ADDR, I2C_MASTER_WRITE);

  28.         /* check status */
  29.         while(1)
  30.         {
  31.             reg = HT_I2C1->SR;

  32.             if(reg & I2C_FLAG_ADRS)
  33.             {
  34.                 return;
  35.             }

  36.             if(reg & I2C_FLAG_RXNACK)
  37.             {
  38.                 I2C_ClearFlag(HT_I2C1, I2C_FLAG_RXNACK);
  39.                 break;
  40.             }
  41.         }
  42.     }
  43. }


  44. /*******************************************************************************
  45. * [url=home.php?mod=space&uid=247401]@brief[/url]      
  46. * @param      
  47. * @retval      
  48. * [url=home.php?mod=space&uid=93590]@Attention[/url]   
  49. *******************************************************************************/
  50. void I2C_EEPROM_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
  51. {
  52.     /* check parameters */
  53.     Assert_Param(NumByteToRead > 0);

  54.     /* acknowledge polling */
  55.     _I2C_EEPROM_AckPolling();

  56.     /* set EEPROM address */
  57.     while (!I2C_CheckStatus(HT_I2C1, I2C_MASTER_TX_EMPTY));
  58.     I2C_SendData(HT_I2C1, ReadAddr);

  59.     /* send read command */
  60.     I2C_TargetAddressConfig(HT_I2C1, I2C_EEPROM_DEV_ADDR, I2C_MASTER_READ);
  61.     while(!I2C_CheckStatus( HT_I2C1, I2C_MASTER_SEND_START));
  62.     while(!I2C_CheckStatus( HT_I2C1, I2C_MASTER_RECEIVER_MODE));

  63.     /* enable master receiver ACK */
  64.     if(NumByteToRead > 1)
  65.     {
  66.         I2C_AckCmd(HT_I2C1, ENABLE);
  67.     }

  68.     /* sequential read */
  69.     while(NumByteToRead)
  70.     {
  71.         while(!I2C_CheckStatus(HT_I2C1, I2C_MASTER_RX_NOT_EMPTY));

  72.         *pBuffer++ = I2C_ReceiveData(HT_I2C1);

  73.         if(--NumByteToRead == 1)
  74.         {
  75.             I2C_AckCmd(HT_I2C1, DISABLE);
  76.         }
  77.     }

  78.     /* end of read */
  79.     I2C_GenerateSTOP(HT_I2C1);
  80. }


  81. /*******************************************************************************
  82. * @brief      
  83. * @param      
  84. * @retval      
  85. * @attention   
  86. *******************************************************************************/
  87. void I2C_EEPROM_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
  88. {
  89.     /* check parameters */
  90.     Assert_Param((NumByteToWrite > 0) &&
  91.                 ((NumByteToWrite <= (I2C_EEPROM_PAGE_SIZE - (WriteAddr & I2C_EEPROM_PAGE_MASK)))));

  92.     /* acknowledge polling */
  93.     _I2C_EEPROM_AckPolling();

  94.     /* set EEPROM address */
  95.     while(!I2C_CheckStatus(HT_I2C1, I2C_MASTER_TX_EMPTY));
  96.     I2C_SendData(HT_I2C1, WriteAddr);

  97.     /* page write */
  98.     while(NumByteToWrite--)
  99.     {
  100.         while(!I2C_CheckStatus(HT_I2C1, I2C_MASTER_TX_EMPTY));
  101.         I2C_SendData(HT_I2C1, *pBuffer++);
  102.     }

  103.     /* end of write */
  104.     while(!I2C_CheckStatus(HT_I2C1, I2C_MASTER_TX_EMPTY));
  105.     I2C_GenerateSTOP(HT_I2C1);
  106. }


  107. /*******************************************************************************
  108. * @brief      
  109. * @param      
  110. * @retval      
  111. * @attention   
  112. *******************************************************************************/
  113. void I2C_EEPROM_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
  114. {
  115.     uint16_t Byte2Wr, AvailableByte;

  116.     /* check parameters */
  117.     Assert_Param(NumByteToWrite <= I2C_EEPROM_CAPACITY);

  118.     /* sequential write */
  119.     while (NumByteToWrite)
  120.     {
  121.         AvailableByte = I2C_EEPROM_PAGE_SIZE - (WriteAddr & I2C_EEPROM_PAGE_MASK);
  122.         Byte2Wr       = (NumByteToWrite > AvailableByte)?(AvailableByte):(NumByteToWrite);

  123.         I2C_EEPROM_PageWrite(pBuffer, WriteAddr, Byte2Wr);

  124.         pBuffer        += Byte2Wr;
  125.         WriteAddr       = (WriteAddr + Byte2Wr) & I2C_EEPROM_ADDR_MASK;
  126.         NumByteToWrite -= Byte2Wr;
  127.     }
  128. }


  129. /*******************************************************************************
  130. * @brief      
  131. * @param      
  132. * @retval      
  133. * @attention   
  134. *******************************************************************************/
  135. void EEPROM_Init(void)
  136. {
  137.     I2C_InitTypeDef I2C_InitStructure;

  138.     CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
  139.     CKCUClock.Bit.PB   = 1;
  140.     CKCUClock.Bit.PC   = 1;
  141.     CKCUClock.Bit.I2C1 = 1;
  142.     CKCUClock.Bit.AFIO = 1;
  143.     CKCU_PeripClockConfig(CKCUClock, ENABLE);

  144.     AFIO_GPxConfig(GPIO_PB, AFIO_PIN_15, AFIO_FUN_I2C);
  145.     AFIO_GPxConfig(GPIO_PC, AFIO_PIN_0,  AFIO_FUN_I2C);

  146.     I2C_InitStructure.I2C_GeneralCall    = I2C_GENERALCALL_DISABLE;
  147.     I2C_InitStructure.I2C_AddressingMode = I2C_ADDRESSING_7BIT;
  148.     I2C_InitStructure.I2C_Acknowledge    = I2C_ACK_DISABLE;
  149.     I2C_InitStructure.I2C_OwnAddress     = 0x00;
  150.     I2C_InitStructure.I2C_Speed          = 400000;  //---400k
  151.     I2C_InitStructure.I2C_SpeedOffset    = 0;
  152.     I2C_Init(HT_I2C1, &I2C_InitStructure);

  153.     I2C_Cmd(HT_I2C1, ENABLE);
  154. }


  155. /*******************************************************************************
  156. * @brief      
  157. * @param      
  158. * @retval      
  159. * @attention   
  160. *******************************************************************************/
  161. void EEPROM_Demo(void)
  162. {
  163.     uint8_t wBuffer[I2C_EEPROM_PAGE_SIZE];
  164.     uint8_t rBuffer[I2C_EEPROM_PAGE_SIZE];

  165.     for(uint32_t j = 0; j < (I2C_EEPROM_CAPACITY / I2C_EEPROM_PAGE_SIZE); j++)
  166.     {
  167.         memset(rBuffer, 0, sizeof(rBuffer));
  168.         memset(wBuffer, 0, sizeof(wBuffer));

  169.         for(uint32_t i = 0; i < I2C_EEPROM_PAGE_SIZE; i++)
  170.         {
  171.             wBuffer[i] = rand();
  172.         }

  173.         I2C_EEPROM_BufferWrite((uint8_t *)wBuffer, I2C_EEPROM_PAGE_SIZE * j, I2C_EEPROM_PAGE_SIZE);

  174.         printf("\r\nEEPROM Write...[Page%d]", j+1);

  175.         for(uint32_t i = 0; i < I2C_EEPROM_PAGE_SIZE; i++)
  176.         {
  177.             if((i % 10) == 0) printf("\r\n");
  178.             printf("0x%02x ", wBuffer[i]);
  179.         }

  180.         I2C_EEPROM_BufferRead((uint8_t  *)rBuffer, I2C_EEPROM_PAGE_SIZE * j, I2C_EEPROM_PAGE_SIZE);

  181.         printf("\r\nEEPROM Read....[Page%d]", j+1);

  182.         for(uint32_t i = 0; i < I2C_EEPROM_PAGE_SIZE; i++)
  183.         {
  184.             if((i % 10) == 0) printf("\r\n");
  185.             printf("0x%02x ", rBuffer[i]);
  186.         }

  187.         for(uint32_t i = 0; i < I2C_EEPROM_PAGE_SIZE; i++)
  188.         {
  189.             if(rBuffer[i] != wBuffer[i])
  190.             {
  191.                 printf("\r\n\r\nEEPROM Read & Write Test Failed!!!"); while(1);
  192.             }
  193.         }

  194.         printf("\t\tCompare Success : %d%%\r\n", (int)((j + 1) * 100) / (I2C_EEPROM_CAPACITY / I2C_EEPROM_PAGE_SIZE));
  195.     }

  196.     printf("\r\n\r\nEEPROM Read & Write Test Pass!!!");
  197. }
  • SPI FLASH
  1. /* Define to prevent recursive inclusion -------------------------------------*/
  2. #define __SPI_FLASH_C__


  3. /* Includes ------------------------------------------------------------------*/
  4. #include "SPI_FLASH.h"
  5. #include <sfud.h>


  6. /* Private typedef -----------------------------------------------------------*/


  7. /* Private define ------------------------------------------------------------*/
  8. #define SFUD_DEMO_BUFFER_SIZE      (512)


  9. /* Private macro -------------------------------------------------------------*/


  10. /* Private variables ---------------------------------------------------------*/
  11. uint8_t sfud_demo_buf[SFUD_DEMO_BUFFER_SIZE];


  12. /* Private function prototypes -----------------------------------------------*/
  13. /* Private functions ---------------------------------------------------------*/


  14. /* Exported variables --------------------------------------------------------*/
  15. /* Exported function prototypes ----------------------------------------------*/


  16. /*******************************************************************************
  17. * @brief       SFUD demo for the first flash device test
  18. * @param       addr flash start address
  19. * @param       size test flash size
  20. * @param       size test flash data buffer
  21. * @retval      
  22. * @attention   
  23. *******************************************************************************/
  24. void sfud_demo(uint32_t addr, size_t size, uint8_t *data)
  25. {
  26.     sfud_err result = SFUD_SUCCESS;

  27.     const sfud_flash *flash = sfud_get_device_table() + 0;

  28.     size_t i;

  29.     /* prepare write data */
  30.     for(i = 0; i < size; i++)
  31.     {
  32.         data[i] = i;
  33.     }

  34.     /* erase test */
  35.     result = sfud_erase(flash, addr, size);

  36.     if(result == SFUD_SUCCESS)
  37.     {
  38.         printf("\r\nErase the %s flash data finish. Start from 0x%08X, size is %d.\r\n", flash->name, addr, size);
  39.     }
  40.     else
  41.     {
  42.         printf("\r\nErase the %s flash data failed.\r\n", flash->name);
  43.         return;
  44.     }

  45.     /* write test */
  46.     result = sfud_write(flash, addr, size, data);

  47.     if(result == SFUD_SUCCESS)
  48.     {
  49.         printf("\r\nWrite the %s flash data finish. Start from 0x%08X, size is %d.\r\n", flash->name, addr, size);
  50.     }
  51.     else
  52.     {
  53.         printf("\r\nWrite the %s flash data failed.\r\n", flash->name);
  54.         return;
  55.     }

  56.     /* read test */
  57.     result = sfud_read(flash, addr, size, data);

  58.     if(result == SFUD_SUCCESS)
  59.     {
  60.         printf("\r\nRead the %s flash data success. Start from 0x%08X, size is %d. The data is:\r\n", flash->name, addr, size);

  61.         printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n");

  62.         for(i = 0; i < size; i++)
  63.         {
  64.             if((i % 16) == 0)
  65.             {
  66.                 printf("[%08X] ", addr + i);
  67.             }

  68.             printf("%02X ", data[i]);

  69.             if(((i + 1) % 16 == 0) || (i == size - 1))
  70.             {
  71.                 printf("\r\n");
  72.             }
  73.         }

  74.         printf("\r\n");
  75.     }
  76.     else
  77.     {
  78.         printf("\r\nRead the %s flash data failed.\r\n", flash->name);
  79.     }

  80.     /* data check */
  81.     for(i = 0; i < size; i++)
  82.     {
  83.         if(data[i] != i % 256)
  84.         {
  85.             printf("\r\nRead and check write data has an error. Write the %s flash data failed.\r\n", flash->name);
  86.             break;
  87.         }
  88.     }

  89.     if(i == size)
  90.     {
  91.         printf("\r\nThe %s flash test is success.\r\n", flash->name);
  92.     }
  93. }


  94. /*******************************************************************************
  95. * @brief      
  96. * @param      
  97. * @retval      
  98. * @attention   
  99. *******************************************************************************/
  100. void SPI_FLASH_Init(void)
  101. {
  102.     printf("\r\n");

  103.     if(sfud_init() == SFUD_SUCCESS)
  104.     {
  105.         sfud_demo(0, sizeof(sfud_demo_buf), sfud_demo_buf);
  106.     }
  107. }
  • SFUD移植接口
  1. #include <sfud.h>
  2. #include <stdarg.h>
  3. #include "config.h"

  4. static char log_buf[256];

  5. void sfud_log_debug(const char *file, const long line, const char *format, ...);

  6. /**
  7. * SPI write data then read data
  8. */
  9. static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
  10.         size_t read_size) {
  11.     sfud_err result = SFUD_SUCCESS;
  12.     uint8_t send_data, read_data;

  13.     if (write_size) {
  14.         SFUD_ASSERT(write_buf);
  15.     }

  16.     if (read_size) {
  17.         SFUD_ASSERT(read_buf);
  18.     }

  19.     /**
  20.      * add your spi write and read code
  21.      */
  22.     GPIO_ClearOutBits(HT_GPIOA, GPIO_PIN_8);

  23.     for (size_t i = 0; i < (write_size + read_size); i++) {
  24.         if (i < write_size) {
  25.             send_data = *write_buf++;
  26.         } else {
  27.             send_data = SFUD_DUMMY_DATA;
  28.         }

  29.         while(!SPI_GetFlagStatus(HT_SPI1, SPI_FLAG_TXBE));
  30.         SPI_SendData(HT_SPI1, send_data);

  31.         while(!SPI_GetFlagStatus(HT_SPI1, SPI_FLAG_RXBNE));
  32.         read_data = SPI_ReceiveData(HT_SPI1);

  33.         if (i >= write_size) {
  34.             *read_buf++ = read_data;
  35.         }
  36.     }

  37.     GPIO_SetOutBits(HT_GPIOA, GPIO_PIN_8);

  38.     return result;
  39. }

  40. #ifdef SFUD_USING_QSPI
  41. /**
  42. * read flash data by QSPI
  43. */
  44. static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
  45.         uint8_t *read_buf, size_t read_size) {
  46.     sfud_err result = SFUD_SUCCESS;

  47.     /**
  48.      * add your qspi read flash data code
  49.      */

  50.     return result;
  51. }
  52. #endif /* SFUD_USING_QSPI */

  53. static void rcc_initialize(void) {
  54.     CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
  55.     CKCUClock.Bit.PA   = 1;
  56.     CKCUClock.Bit.PB   = 1;
  57.     CKCUClock.Bit.PC   = 1;
  58.     CKCUClock.Bit.SPI1 = 1;
  59.     CKCUClock.Bit.AFIO = 1;
  60.     CKCU_PeripClockConfig(CKCUClock, ENABLE);
  61. }

  62. static void gpio_initialize(void) {
  63.     AFIO_GPxConfig(GPIO_PA, GPIO_PIN_8,  AFIO_FUN_GPIO);
  64.     AFIO_GPxConfig(GPIO_PA, GPIO_PIN_15, AFIO_FUN_SPI);
  65.     AFIO_GPxConfig(GPIO_PB, GPIO_PIN_6,  AFIO_FUN_SPI);
  66.     AFIO_GPxConfig(GPIO_PC, GPIO_PIN_3,  AFIO_FUN_SPI);

  67.     GPIO_SetOutBits(HT_GPIOA, GPIO_PIN_8);
  68.     GPIO_DirectionConfig(HT_GPIOA, GPIO_PIN_8, GPIO_DIR_OUT);
  69. }

  70. static void spi_device_initialize(void) {
  71.     SPI_InitTypeDef  SPI_InitStructure;

  72.     SPI_InitStructure.SPI_Mode        = SPI_MASTER;
  73.     SPI_InitStructure.SPI_FIFO        = SPI_FIFO_DISABLE;
  74.     SPI_InitStructure.SPI_DataLength  = SPI_DATALENGTH_8;
  75.     SPI_InitStructure.SPI_SELMode     = SPI_SEL_SOFTWARE;
  76.     SPI_InitStructure.SPI_SELPolarity = SPI_SELPOLARITY_LOW;
  77.     SPI_InitStructure.SPI_FirstBit    = SPI_FIRSTBIT_MSB;
  78.     SPI_InitStructure.SPI_CPOL        = SPI_CPOL_HIGH;
  79.     SPI_InitStructure.SPI_CPHA        = SPI_CPHA_SECOND;
  80.     SPI_InitStructure.SPI_RxFIFOTriggerLevel = 0;
  81.     SPI_InitStructure.SPI_TxFIFOTriggerLevel = 0;
  82. #if (LIBCFG_MAX_SPEED > 48000000)
  83.     SPI_InitStructure.SPI_ClockPrescaler = 4;
  84. #else
  85.     SPI_InitStructure.SPI_ClockPrescaler = 2;
  86. #endif
  87.     SPI_Init(HT_SPI1, &SPI_InitStructure);

  88.     SPI_SELOutputCmd(HT_SPI1, ENABLE);

  89.     SPI_Cmd(HT_SPI1, ENABLE);
  90. }

  91. static void spi_lock(const sfud_spi *spi) {
  92.     __disable_irq();
  93. }

  94. static void spi_unlock(const sfud_spi *spi) {
  95.     __enable_irq();
  96. }

  97. static void retry_delay_100us(void) {
  98.     uint32_t delay = 120;
  99.     while (delay--);
  100. }

  101. sfud_err sfud_spi_port_init(sfud_flash *flash) {
  102.     sfud_err result = SFUD_SUCCESS;

  103.     /**
  104.      * add your port spi bus and device object initialize code like this:
  105.      * 1. rcc initialize
  106.      * 2. gpio initialize
  107.      * 3. spi device initialize
  108.      * 4. flash->spi and flash->retry item initialize
  109.      *    flash->spi.wr = spi_write_read; //Required
  110.      *    flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
  111.      *    flash->spi.lock = spi_lock;
  112.      *    flash->spi.unlock = spi_unlock;
  113.      *    flash->spi.user_data = &spix;
  114.      *    flash->retry.delay = null;
  115.      *    flash->retry.times = 10000; //Required
  116.      */
  117.     switch (flash->index) {
  118.         case SFUD_FLASH_DEVICE_INDEX:
  119.             rcc_initialize();

  120.             gpio_initialize();

  121.             spi_device_initialize();

  122.             flash->spi.wr        = spi_write_read;
  123.             flash->spi.qspi_read = qspi_read;
  124.             flash->spi.lock      = spi_lock;
  125.             flash->spi.unlock    = spi_unlock;
  126.             flash->spi.user_data = NULL;
  127.             flash->retry.delay   = retry_delay_100us;
  128.             flash->retry.times   = 60 * 10000;
  129.             break;

  130.         default: break;
  131.     }

  132.     return result;
  133. }

  134. /**
  135. * This function is print debug info.
  136. *
  137. * @param file the file which has call this function
  138. * @param line the line number which has call this function
  139. * @param format output format
  140. * @param ... args
  141. */
  142. void sfud_log_debug(const char *file, const long line, const char *format, ...) {
  143.     va_list args;

  144.     /* args point to the first variable parameter */
  145.     va_start(args, format);
  146.     printf("[SFUD](%s:%ld) ", file, line);
  147.     /* must use vprintf to print */
  148.     vsnprintf(log_buf, sizeof(log_buf), format, args);
  149.     printf("%s\r\n", log_buf);
  150.     va_end(args);
  151. }

  152. /**
  153. * This function is print routine info.
  154. *
  155. * @param format output format
  156. * @param ... args
  157. */
  158. void sfud_log_info(const char *format, ...) {
  159.     va_list args;

  160.     /* args point to the first variable parameter */
  161.     va_start(args, format);
  162.     printf("[SFUD]");
  163.     /* must use vprintf to print */
  164.     vsnprintf(log_buf, sizeof(log_buf), format, args);
  165.     printf("%s\r\n", log_buf);
  166.     va_end(args);
  167. }


运行结果
  • EEPROM
1.png 2.png 3.png
  • SPI FLASH
4.png


软件工程源代码
Project.zip (896.97 KB, 下载次数: 10)

51xlf 发表于 2022-11-1 14:29 | 显示全部楼层
SPI FLASH 主要用于哪些产品呢?
houjiakai 发表于 2022-11-1 15:24 | 显示全部楼层
是硬件spi驱动的吗?              
fengm 发表于 2022-11-1 15:45 | 显示全部楼层
eeprom可以实现文件的存储吗
olivem55arlowe 发表于 2022-11-1 17:12 | 显示全部楼层
移植了fatfs文件操作系统了吗
hudi008 发表于 2023-1-5 14:14 | 显示全部楼层
最大的读写速度是多少?              
sheflynn 发表于 2023-1-5 14:24 | 显示全部楼层
可以跑fatfs系统的吗?              
beacherblack 发表于 2023-1-5 16:17 | 显示全部楼层
硬件iic和spi搞起来。              
kmzuaz 发表于 2023-1-5 18:04 | 显示全部楼层
这个写的非常的详细了。              
bartonalfred 发表于 2023-1-6 16:40 | 显示全部楼层
这个flash可以做字库使用的。
mollylawrence 发表于 2023-1-6 19:26 | 显示全部楼层
单片机的性能看着非常的给力。              
benjaminka 发表于 2023-1-9 13:49 | 显示全部楼层
可以移植fatfs?              
albertaabbot 发表于 2023-1-9 17:45 | 显示全部楼层
这个设计的性能怎么              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:King.Xu

77

主题

3023

帖子

38

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:King.Xu

77

主题

3023

帖子

38

粉丝
快速回复 在线客服 返回列表 返回顶部