第22章 W25Q64存储小数和整数

第二十二章 W25Q64存储小数和整数

1. 硬件设计

参考上一章SPI读写实验

2. 软件设计

主要程序设计我们在上一章就见识过了,这个实验主要就是改下主函数就行了

  • 主函数
#include "stm32f10x.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"
#include "./flash/bsp_spi_flash.h" 

//读取的ID存储位置
__IO uint32_t DeviceID = 0;
__IO uint32_t FlashID = 0;

// 函数原型声明
void Delay(__IO uint32_t nCount);

int main(void)
{     
    uint8_t cal_flag = 0;
    uint8_t k;

    // 存储小数和整数的数组,各7个
    long double double_buffer[7] = {0};
    int int_bufffer[7] = {0};

    // led初始化
    LED_GPIO_Config();
    LED_BLUE;
    // 配置串口1为:115200 8-N-1 
    USART_Config();
    printf("\r\n这是一个FLASH 读写小数和长整数实验 \r\n");
    printf("\r\n 使用指南者底板时 左上角排针位置 不要将PC0盖有跳帽 防止影响PC0做SPIFLASH片选脚 \r\n");
    // 16M串行flash W25Q128初始化
    SPI_FLASH_Init();
    // 获取 Flash Device ID 
    DeviceID = SPI_FLASH_ReadDeviceID();
    Delay(200);
    // 获取 SPI Flash ID
    FlashID = SPI_FLASH_ReadID();
    printf("\r\nFlashID is 0x%X,  Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);

    // 检验 SPI Flash ID
    if(FlashID == sFLASH_ID) 
    {    
        LED_GREEN; // 成功,绿色指示灯
        printf("\r\n检测到SPI FLASH W25Q64 !\r\n");
        // 读取数据标志位
        SPI_FLASH_BufferRead(&cal_flag, SPI_FLASH_PageSize*0, 1);
    if(cal_flag == 0xCD ) // 若标志等于0xcd,表示之前已有写入数据
    {
        printf("\r\n检测到数据标志\r\n");

        // 读取小数数据
        SPI_FLASH_BufferRead((void*)double_buffer, SPI_FLASH_PageSize*1, sizeof(double_buffer));
        // 读取整数数据
        SPI_FLASH_BufferRead((void*)int_bufffer, SPI_FLASH_PageSize*2, sizeof(int_bufffer));
        printf("\r\n从芯片读到数据:\r\n");            
        for(k = 0; k < 7; k++ )
        {
            printf("小数 rx = %LF \r\n",double_buffer[k]);
            printf("整数 rx = %d \r\n",int_bufffer[k]);                
        }
    }    
    else
    {
        printf("\r\n没有检测到数据标志,FLASH没有存储数据,即将进行小数写入实验\r\n");
        cal_flag = 0xCD; // 给定标志位
        SPI_FLASH_SectorErase(0); // 扇区擦除第0页
        //写入标志到第0页
          SPI_FLASH_BufferWrite(&cal_flag, SPI_FLASH_PageSize*0, 1); 
          for(k = 0; k < 7; k++ )
          {
            double_buffer[k] = k +0.1;
            int_bufffer[k]=k*500+1 ;
          }
        // 写入小数数据到第一页
          SPI_FLASH_BufferWrite((void*)double_buffer, SPI_FLASH_PageSize*1, sizeof(double_buffer));
        // 写入整数数据到第二页
         SPI_FLASH_BufferWrite((void*)int_bufffer, SPI_FLASH_PageSize*2, sizeof(int_bufffer));

        printf("向芯片写入数据:");
        // 打印到串口
        for( k=0; k<7; k++ )
        {
            printf("小数tx = %LF\r\n",double_buffer[k]);
            printf("整数tx = %d\r\n",int_bufffer[k]);
        }    
        printf("\r\n请复位开发板,以读取数据进行检验\r\n");
    }   
    }// if (FlashID == sFLASH_ID)
    else
    {    
        LED_RED;
        printf("\r\n获取不到 W25Q64 ID!\n\r");
    }
    SPI_Flash_PowerDown();  
    while(1);  
}

void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

唯一的区别就是加了读写小数的功能,我们可以简单分析一下:

  • 前面定义缓存区,各项外设初始化

  • 获取Flash、SPI的ID,并且打印

  • 之后就可以获取标志位,如果没有获取到,进行写入小数操作:擦除->写入标志位第0页->写入小数到第一页

  • 之后复位开发板,这时应该能成功获取到标志位,于是通过for循环打印出我们写入的数据

3. 小结

下面整体概括一下:

1. 头文件引入

#include "stm32f10x.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"
#include "./flash/bsp_spi_flash.h"

这些头文件包含了不同模块所需的函数和宏定义。例如,stm32f10x.h 提供了STM32F10系列芯片的基础功能,而其他头文件则提供了LED、串口、Flash操作的具体实现。

举一反三:如果你在使用其他外设,比如定时器或ADC,你需要包含相应的头文件,如stm32f4xx_tim.hstm32f4xx_adc.h

2. 全局变量

__IO uint32_t DeviceID = 0;
__IO uint32_t FlashID = 0;

这些全局变量用来存储设备ID和Flash ID,__IO修饰符用于表示这些变量可能会被硬件或中断改变。

举一反三:类似地,如果你需要存储其他硬件相关的信息,可以使用类似的全局变量。

3. 函数原型声明

void Delay(__IO uint32_t nCount);

声明了一个延时函数,用于在程序中创建延时。

举一反三:如果需要其他功能的延时(例如基于定时器的延时),你可以声明并实现新的延时函数。

4. 主函数

int main(void)
{
    uint8_t cal_flag = 0;
    uint8_t k;
    long double double_buffer[7] = {0};
    int int_bufffer[7] = {0};

主函数中初始化了数据标志位、循环变量以及两个数据缓冲区:double_buffer用于存储小数,int_bufffer用于存储整数。

举一反三:如果需要处理更多的数据,可以增加更多的数组或缓冲区。例如,你可以增加一个float_buffer来存储浮点数数据。

5. 外设初始化

LED_GPIO_Config();
LED_BLUE;
USART_Config();

配置LED和串口的初始化函数,并点亮蓝色LED作为开始的指示。

举一反三:类似地,你可以配置其他外设,如定时器或DAC,通过相应的初始化函数。

6. Flash ID读取和验证

DeviceID = SPI_FLASH_ReadDeviceID();
FlashID = SPI_FLASH_ReadID();

从SPI Flash中读取设备ID和Flash ID,并打印出来进行验证。

举一反三:对于其他外设的ID读取和验证,流程类似。比如读取传感器ID,你也会用相应的函数读取数据并验证。

7. 数据读取和写入

if(cal_flag == 0xCD)
{
    SPI_FLASH_BufferRead((void*)double_buffer, SPI_FLASH_PageSize*1, sizeof(double_buffer));
    SPI_FLASH_BufferRead((void*)int_bufffer, SPI_FLASH_PageSize*2, sizeof(int_bufffer));
}
else
{
    SPI_FLASH_SectorErase(0);
    SPI_FLASH_BufferWrite((void*)double_buffer, SPI_FLASH_PageSize*1, sizeof(double_buffer));
    SPI_FLASH_BufferWrite((void*)int_bufffer, SPI_FLASH_PageSize*2, sizeof(int_bufffer));
}

检查标志位,如果数据已存在则读取数据,否则进行写入操作。

举一反三:类似的操作可以应用于其他存储设备,比如EEPROM或SD卡的读写。只需替换为对应的读写函数即可。

posted @ 2024-09-05 15:51  hazy1k  阅读(8)  评论(0编辑  收藏  举报