【随手笔记】FLASH-W25Q16(三)

详述16M bits串行Flash(W25Q16)的特性和用法 W25Q16JV阵列被组织成8192个可编程页面,每个页面256字节。最多可达256字节一次被编程。页可以以16为一组(4KB扇区擦除),128为一组(32KB)进行擦除块擦除),组256 (64KB块擦除)或整个芯片(芯片擦除)。W25Q16JV有512个可擦扇区和32个可擦块。较小的4KB扇区允许更大的灵活性需要数据和参数存储的应用程序。 阅读详情
#include "bsp_w25q16.h"

/*内部函数声明区*/
static HAL_StatusTypeDef bsp_w25q_Transmit(uint8_t * T_pData, uint16_t T_Size);
static HAL_StatusTypeDef bsp_w25q_Receive(uint8_t * R_pData, uint16_t R_Size);


/*内部函数定义区*/


/*
函数参数:
        1、T_pData:发送数据缓冲区中取出数据发送出去
        2、T_Size :需要发送的数据的长度
*/
static HAL_StatusTypeDef bsp_w25q_Transmit(uint8_t * T_pData, uint16_t T_Size)
{
    return HAL_SPI_Transmit(&W25Q_SPI, T_pData, T_Size, 0xffff);
}

/*
函数参数:
        1、R_pData:接收数据并放置到接收数据缓冲区中
        2、R_Size :需要接收的数据的长度
*/
static HAL_StatusTypeDef bsp_w25q_Receive(uint8_t * R_pData, uint16_t R_Size)
{
    return HAL_SPI_Receive(&W25Q_SPI, R_pData, R_Size, 0xffff);
}

/*
写使能或失能
    参数:
        Type:
            1、为1时使能
            2、为0时失能
*/
HAL_StatusTypeDef Bsp_Write_En_De(uint8_t Type)
{
    uint8_t cmd;
    HAL_StatusTypeDef STD = HAL_ERROR;

    W25Q_CS_Level(0);
    SPI_Delay(1);
    switch(Type)
    {
        case 1:
            cmd = W25Q_W_EN;
            break;
        case 0:
            cmd = W25Q_W_DIS;
            break;
        default:
            cmd = W25Q_W_DIS;
            break;
    }

    if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
    {
        STD = HAL_OK;
    }

    W25Q_CS_Level(1);
    return STD;
}

/*
读状态寄存器
    参数:Select
        1、为0时是寄存器1
        2、为1时是寄存器2
    参数:State(指针)
        1、返回的状态标志

    流程:先写入命令,然后读取状态
*/
HAL_StatusTypeDef Bsp_Read_State_Reg(uint8_t Select, uint8_t* State)
{
    uint8_t cmd;
    HAL_StatusTypeDef STD = HAL_ERROR;

    W25Q_CS_Level(0);
    SPI_Delay(1);
    switch(Select)
    {
        case 0:
            cmd = W25Q_R_STA_REG1;
            break;
        case 1:
            cmd = W25Q_R_STA_REG2;
            break;
        default:
            cmd = W25Q_R_STA_REG1;
            break;
    }

    if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
    {
        if(bsp_w25q_Receive(State,1) == HAL_OK)
        {
            STD = HAL_OK;
        }
    }

    W25Q_CS_Level(1);

    return STD;
}

/*
判忙
        用处:判断当前flash是否在忙碌状态
        BUSY只读寄存器
        忙时高电平
        空闲低电平
*/
void Bsp_Judge_Busy(void)
{
    uint8_t State;
    do{
        Bsp_Read_State_Reg(0, &State);  //不要用指针类型局部变量传进去,必被卡死
        State &= 0x01;
    }while(State == 0x01);//寄存器为1时为忙
}


/*
读数据
            参数:R_Addr
                        1、读取数据的地址
            参数:R_Data(数组指针)
                        1、获取读取的数据
            参数:R_Size
                        1、读取的数据的大小
*/
HAL_StatusTypeDef Bsp_W25Q_Read_Data(uint32_t R_Addr, uint8_t * R_Data, uint16_t R_Size)
{
    HAL_StatusTypeDef STD = HAL_ERROR;

    uint8_t addr[4] = {0};
    addr[0] = W25Q_R_Data;
    addr[1] = (R_Addr >> 16) & 0xFF;
    addr[2] = (R_Addr >> 8) & 0xFF;
    addr[3] = (R_Addr) & 0xFF;

    Bsp_Judge_Busy();   //判忙
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
    {
        if(bsp_w25q_Receive(R_Data,R_Size) == HAL_OK)
        {
            STD = HAL_OK;
        }
    }

    W25Q_CS_Level(1);

    return STD;
}


/*
写数据-页
    页的描述:1字节到 256 字节(一页)
    页写的前提条件:编程之前必须保证额你存空间是0xff,
    所以得先进行擦除(擦除后模式全为1)
    页写的注意事项:进行页编程时,如果数据字节数超过了 256 字节,
    地址将自动回到页的起始地址,覆盖掉之前的数据。

    参数:WriteAddr
                1、地址,三个字节地址
    参数:PW_Data(数组指针)
                1、要写入的数据,长度根据PW_size来定
                2、高位先传
    参数:PW_Size
                2、要写入的数据长度

    先通过状态寄存器判断是否在忙,
    然后写使能,
    接着判忙,
    拉底片选选中,
    发命令字节0x02,
    发三个地址,高位优先,
    然后发你要写的数据,
    最后拉高片选
*/

HAL_StatusTypeDef Bsp_W25Q_Page_Write(uint32_t WriteAddr, uint8_t * PW_Data, uint16_t PW_Size)
{
    HAL_StatusTypeDef STD = HAL_ERROR;

    uint8_t addr[4] = {0};
    addr[0] = W25Q_Page_Program;
    addr[1] = (WriteAddr >> 16) & 0xFF;
    addr[2] = (WriteAddr >> 8) & 0xFF;
    addr[3] = (WriteAddr) & 0xFF;

    Bsp_Judge_Busy();   //判忙
    Bsp_Write_En_De(1);

    Bsp_Judge_Busy();
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
    {
        if(bsp_w25q_Transmit(PW_Data, PW_Size) == HAL_OK)
        {
            STD = HAL_OK;
        }
    }

    W25Q_CS_Level(1);
    Bsp_Judge_Busy();

    return STD;
}



/*
扇区擦除
    扇区的描述:W25Q16总共2MB,分为32块(每块64KB),
                            每块16个扇区,每个扇区4K个字节。
    扇区的备注:W25Q16的最小擦除单位就是一个扇区
                            所以至少给芯片开辟一个4KB的缓存区,
                            以防止一次性删除太多,而丢失数据。(显然单片机不会给他开辟这么大的空间)

    参数:num : 扇区的序号


*/
HAL_StatusTypeDef Bsp_W25Q_Sector_Erase(uint32_t num)
{
    HAL_StatusTypeDef STD = HAL_ERROR;

    //一个扇区有4KB的大小,
    //为了使找到对应的扇区地址,所以要乘以4KB
    //(1<<12) = 4096
    num *= (1<<12);

    uint8_t addr[4] = {0};
    addr[0] = W25Q_Sector_Erase;
    addr[1] = (num >> 16) & 0xFF;
    addr[2] = (num >> 8) & 0xFF;
    addr[3] = (num) & 0xFF;

    Bsp_Judge_Busy();
    Bsp_Write_En_De(1);

    Bsp_Judge_Busy();
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
    {
        STD = HAL_OK;
    }

    W25Q_CS_Level(1);
    Bsp_Judge_Busy();

    return STD;
}



/*
块擦除
    块的描述:W25Q16有2MB的容量,而2MB有32个块,所以1块有64kB的大小,
                        所以这个函数一次能擦除64KB的大小。

    参数:Block_Addr
                1、块地址,共32个块,对应32个地址,以64K为单位寻址
                2、高位先传

    流程:先开写使能、判忙,再写命令,
                再写3个字节的地址,最后写失能

      参数:num : 块的序号
*/
HAL_StatusTypeDef   Bsp_W25Q_Block_Erase(uint32_t num)
{
    uint8_t cmd = W25Q_Block_Erase;
    HAL_StatusTypeDef STD = HAL_ERROR;

    //总共有32个块,而一个块有64KB的大小,
    //为了使找到对应的块地址,所以要乘以64KB
    num *= (1<<16);

    uint8_t addr[4] = {0};
    addr[0] = W25Q_Block_Erase;
    addr[1] = (num >> 16) & 0xFF;
    addr[2] = (num) & 0xFF;
    addr[3] = (num) & 0xFF;

    Bsp_Judge_Busy();
    Bsp_Write_En_De(1);

    Bsp_Judge_Busy();
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(addr, 4) == HAL_OK)
    {
        STD = HAL_OK;
    }

    W25Q_CS_Level(1);
    Bsp_Judge_Busy();
    return STD;
}


/*
全片擦除
    描述:直接把芯片全部擦除
*/
HAL_StatusTypeDef Bsp_W25Q_Full_Erase(void)
{
    uint8_t cmd = W25Q_Full_Erase;
    HAL_StatusTypeDef STD = HAL_ERROR;

    Bsp_Judge_Busy();
    Bsp_Write_En_De(1);

    Bsp_Judge_Busy();
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
    {
        STD = HAL_OK;
    }

    W25Q_CS_Level(1);
    Bsp_Judge_Busy();

    return STD;
}


/*
读ID
    描述:读3个字节分别是生产厂家、存储器类型、容量
*/
HAL_StatusTypeDef Bsp_Read_Jedec_ID(uint8_t * R_Jedec_ID)
{
    uint8_t read_id[3] = {0};
    uint8_t cmd = W25Q_JEDEC_ID;
    HAL_StatusTypeDef STD = HAL_ERROR;

    Bsp_Judge_Busy();
    W25Q_CS_Level(0);
    SPI_Delay(1);

    if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK)
    {
        if(bsp_w25q_Receive(read_id, 3) == HAL_OK)
        {
            STD = HAL_OK;
        }
    }

    W25Q_CS_Level(1);

    if(STD == HAL_OK)
    {
        LOG_OUT("read_id= %x %x %x\r\n", read_id[0], read_id[1], read_id[2]);
    }
    else
    {
        LOG_OUT("read_id= err\r\n");
    }
    return STD;
}

/*
 * 电源开启
 */
void W26Q16_Power_On(void)
{
    MX_SPI1_Init();
    //W25Q_WP_HIGH;
    rt_thread_mdelay(100);
    Bsp_Read_Jedec_ID(NULL);

}

/*
 * 电源关闭
 */
void W26Q16_Power_Off(void)
{
    //WP拉低开启读保护
    //W25Q_WP_LOW;

    W25Q_CS_Level(GPIO_PIN_RESET);
    rt_thread_mdelay(10);

    //失能SPI配置为IO
    w25q16_init_sleep();
    rt_thread_mdelay(1000);
}

#ifndef __DRV_W25Q16_H
#define __DRV_W25Q16_H

#include "app_user.h"
#include "spi.h"

/*句柄重命名*/
#define W25Q_SPI                hspi1

#define SPI_Delay(ms)           rt_thread_mdelay(ms+1)

/*片选引脚定义与函数调用*/
#define W25Q_CS_Pin             GPIO_PIN_4
#define W25Q_CS_Port            GPIOA

#define W25Q_CS_Level(_CS_STATE__)      HAL_GPIO_WritePin(W25Q_CS_Port, W25Q_CS_Pin, (GPIO_PinState)_CS_STATE__)

//#define W25Q_WP_HIGH   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET)
//#define W25Q_WP_LOW    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET)

#define W25Q_W_EN               0x06        //写使能
#define W25Q_W_DIS              0x04        //写禁止

#define W25Q_R_Data             0x03        //读数据

#define W25Q_R_STA_REG1     0x05        //读状态寄存器1,紧跟着的字节就是当前状态
#define W25Q_R_STA_REG2     0x35        //读状态寄存器2,紧跟着的字节就是当前状态

#define W25Q_W_STA_REG      0x01        //写状态寄存器,写入两个字节,分别到寄存器1,和寄存器2

#define W25Q_Page_Program   0x02        //页编程,先跟3个地址字节,再跟一个数据字节

#define W25Q_Block_Erase    0xD8        //块擦除64k,三个地址字节

#define W25Q_Sector_Erase   0x20        //扇区擦除,跟三个地址

#define W25Q_Full_Erase     0xC7        //全片擦除//0x60

#define W25Q_Susp_Erase     0x75        //暂停擦除

#define W25Q_Rest_Erase     0x7A        //恢复擦除

#define W25Q_PowDow_Mode    0xB9        //掉电模式

#define W25Q_HPer_Mode      0xA3        //高性能模式

#define W25Q_JEDEC_ID       0x9F        //读3个字节分别是生产厂家、存储器类型、容量

/*写使能或失能*/
HAL_StatusTypeDef Bsp_Write_En_De(uint8_t Type);

/*读状态寄存器*/
HAL_StatusTypeDef Bsp_Read_State_Reg(uint8_t Select, uint8_t* State);

/*判忙*/
void Bsp_Judge_Busy(void);

/*读数据*/
HAL_StatusTypeDef Bsp_W25Q_Read_Data(uint32_t R_Addr, uint8_t * R_Data, uint16_t R_Size);

/*页写*/
HAL_StatusTypeDef Bsp_W25Q_Page_Write(uint32_t WriteAddr, uint8_t * PW_Data, uint16_t PW_Size);

/*扇区擦除*/
HAL_StatusTypeDef Bsp_W25Q_Sector_Erase(uint32_t num);

/*块擦除*/
HAL_StatusTypeDef   Bsp_W25Q_Block_Erase(uint32_t num);

/*全片擦除*/
HAL_StatusTypeDef Bsp_W25Q_Full_Erase(void);

/*读ID*/
HAL_StatusTypeDef Bsp_Read_Jedec_ID(uint8_t * R_Jedec_ID);

void W26Q16_Power_On(void);
void W26Q16_Power_Off(void);
#endif /*W25Q16__H__*/

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    spi.c
  * @brief   This file provides code for the configuration
  *          of the SPI instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "spi.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

SPI_HandleTypeDef hspi1;

/* SPI1 init function */
void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */
    /* SPI1 clock enable */
    __HAL_RCC_SPI1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI1_MspInit 1 */

  /* USER CODE END SPI1_MspInit 1 */
  }
}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{

  if(spiHandle->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspDeInit 0 */

  /* USER CODE END SPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SPI1_CLK_DISABLE();

    /**SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

  /* USER CODE BEGIN SPI1_MspDeInit 1 */

  /* USER CODE END SPI1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */


void w25q16_init_sleep(void)
{
    extern SPI_HandleTypeDef hspi1;
    HAL_SPI_DeInit(&hspi1);

    __HAL_RCC_GPIOA_CLK_ENABLE();

     GPIO_InitTypeDef GPIO_InitStruct = {0};

     GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
}
W25Q16 存储器(Flash) W25Q16 Flash知识总结 阅读详情

相关推荐

STM8L151 使用硬件SPI驱动W25Q16 Flash

STM8L 该如何使用硬件SPI驱动W25Q16 Flash 芯片

jnu_fangzebin的专栏 1万+

W25Q16_Flash手册总结

前面学习了我们的spi协议,下面我们需要对Flash芯片手册进行简单的学习总结,后面通过spi协议对flash进行读写。FLASH 存储器又称闪存,是一种长寿命的非易失性(在断电情况下仍能保持所存储的数据信息)存储器,一般用来保存一些重要的设置信息或者程序等等。通常采用 SPI 协议跟 FLASH 芯片进行数据交互。W25Q16BV是串行闪存为空间,引脚和功耗有限的系统提供存储解决方案。25Q 系列提供的灵活性和性能远远超过普通串行闪存设备。

qq_52215423的博客 9021

SPI FLASH_W25Q64驱动 代码

#include "flash.h" #include "spi.h" #include "delay.h"    #include "usart.h"    //////////////////////////////////////////////////////////////////////////////////  //本程序只供学习使用,未经作者许可,不得用于其它任

zongguo的专栏 1万+

W25Q16编址详解

W25Q16是一款基于SPI接口Flash存储器。 但往往我们对一串长长的16进制地址无从下手,以至于数据存储位置不当。 本文对W25Q16的编址进行详细解说

snoopy_13579的博客 3905

W25Q64 Flash芯片原理与应用方案(含W25Q64中文数据手册)

W25Q64是华邦公司推出的大容量SPI FLASH产品,其容量为64Mb(8MB),应用较为广泛。 W25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件。W25Q64将8M字节的容量分为128个块,每个块大小为64K字节,每个块又分为16个扇区,每个扇区4K个字节。W25Q64的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。所以,这需要给W25Q64开辟一个至少4K的缓存区,这样必须要求芯片有4K以上的SRAM才能有很好的操作。 W25Q64的擦写周期多达10W次,可将数据保存达2.

硬件之家,技术前行 2万+

stm32 W25QXX系列驱动 W25Q80 W25Q16 W25Q32 W25Q64 W25Q128 W25Q256

W25QXX系列驱动,支持W25Q80,W25Q32,W25Q128,W25Q256,W25Q64,W25Q16,详细中文注释

qq_30551297的博客 5904

SPI Flash Rom W25Q16 ----基于STC15

(。。。。)先来简单认识一下这个芯片 W25Q16 其实就是以SPI作为通信时序要求的一款储存芯片,升级版的EEPROM,比EEPROM读取速度快,价格还差不多。 W25X16分为8192页,每页256字节,用“页编程指令”每次就可以编程256字节,用“扇区擦除指令”每次可擦除16页,用“块擦除指令”每次可擦除256页,用“整片擦除指令”可一次擦除整个芯片,W25X16有512个可擦除

悟已往之不谏 知来者之可追 1万+

Altera USB-Blaster在Win10/Win11的驱动兼容性处理

解决Altera USB-Blaster在Windows 10和Windows 11系统下的驱动兼容性问题,详细演示如何手动安装与更新altera usb-blaster驱动安装,确保下载电缆正常识别,提升开发调试效率。

weixin_42284380的博客 1289

Flash存储W25Q16芯片

1          一般描述 W25Q16BV(16M-bit)是为有限的空间、引脚和功耗的系统提供一个存储解决方案。25Q系列比普通的串行Flash存储器更灵活,性能更优越。基于双倍/四倍的SPI,它们能够可以立即完成提供数据给RAM,包括存储声音、文本和数据。芯片支持的工作电压2.7V到3.6V,正常工作时电流小于4mA,掉电时低于1uA。工作温度为-40℃到85℃。所有芯片提供标准的封装

Ccode11的专栏 3万+

嘉立创EDA实战:从点亮第一盏灯到完成首块PCB

本文详细介绍了使用嘉立创EDA从点亮第一盏LED灯到完成首块PCB的全过程。通过实战案例分享,包括原理图绘制、PCB设计、DRC检查、覆铜操作等关键步骤,帮助电子设计爱好者快速掌握嘉立创EDA的使用技巧,并避免常见的设计错误。

weixin_30314793的博客 372

K-近邻算法: k-nearest neighbor classification (kNN) 详细介绍

@创建于:2020.04.09 @修改于:2020.04.09,2024.06.22 文章目录1、kNN介绍2、k近邻法的三要素详解2.1 距离度量2.2 k值的选择2.3 分类决策规则3、k近邻法的实现:kd树4、Python实现过程5、优缺点6、常见问题 1、kNN介绍 kNN是一个基本而简单的分类算法,作为监督学习,那么KNN模型需要的是有标签的训练数据,对于新样本的类别由与新样本距离最近的k个训练样本点按照分类...

chenhepg的博客 9万+

W25Q16基本知识

关键字:RTC,定时器, Flash, stm32,SPI,W25Q16 W25Q16 25Q系列,**16M-bit(1bytes=8 bits) **的flash。可以保存voice,text,data. The W25Q16JV array is organized into 8,192 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time. Pages canbe erased in gr

weixin_38324309的博客 8237

深度拆解 ‘High-Frequency Trading’ (HFT) 系统:解析如何在 100 纳秒内完成从网卡到 C++ 策略的响应

在100纳秒内完成从网卡到C++策略的响应,这是一项对技术栈每一个层面都进行极限优化的系统工程。它要求我们深入理解计算机体系结构、操作系统、网络协议和C++语言的底层机制。从物理距离的极致缩短,到高性能网卡和内核旁路技术,再到C++代码中每一个字节、每一个CPU周期的精打细算,HFT系统展现了人类对计算速度的永恒追求。这项技术不仅仅应用于金融交易,其背后的低延迟理念和实现方法,如DPDK、无锁编程、硬件加速等,正在逐渐渗透到其他对延迟敏感的领域,例如电信网络、边缘计算和工业自动化。

weixin_41455464的博客 1039

SPI _FLASH芯片W25Q16配置FATFS

一、SPI FLASH芯片能干啥有哪些种类 存放数据。SPI FLASH普遍比EEPROM大得多。所以容量SPI FLASH占优势。但是价格,EEPROM占优势. 1、IIC EEPROM------容量小,采用的是IIC通信协议;用于在掉电时,存系统配置参数,比如屏幕亮度等。常用芯片型号有 AT24C02、FM24C02、CAT24C02等,其常见的封装多为DIP8,SOP8,TSSOP8等; 2、SPI NorFlash------容量略大,采用的是SPI 通信协议;用于存放程序和数据。程序和数据可存放

“Struggle”的博客 1万+

高质量文献综述原来这么写!借助Gemini 3 Pro+四步法,手把手教你写出有逻辑深度的综述

总结与展望先总结现状,说明前人已经做到什么地步了,再指出缺口,前人没解决什么问题、方法有什么局限等等,最后再在这个缺口的基础上,提出你的未来研究方向。当你有个复杂的研究题目,但没办法拆解出关键词,就可以让Gemini 3 Pro来辅助帮你拆解,并帮你写专业的检索式,若是找英文文献,还能帮你将中文关键词翻译成地道的专业术语。做文献笔记,可以建立文献笔记矩阵,可以用Excel建个表格,横向是文献,纵向是关键要素,包括作者/年份、研究问题/假设、理论框架/模型、研究方法/数据来源、核心结论、局限性/Gap。

智能AI让学术科研更容易 992

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

weixin_45735391的博客 3万+

stm32 操作W25Q256 W25Q16 spi flash

stm32 操作W25Q256 W25Q16 spi flash

Car12 9245

C#上位机实战:Modbus RTU串口通信(CRC校验+超时重发完整实现)

在工业自动化上位机开发中,Modbus RTU是串口通信的事实标准协议,SerialPort是 .NET 平台操作串口的原生类,无需依赖第三方库即可实现基础通信。实际项目中,工控现场存在电磁干扰、串口丢包、设备响应延迟等问题,CRC 数据校验用于保证报文完整性,超时重发机制用于提升通信稳定性。本文从零封装一套可直接落地的 Modbus RTU 通信组件,包含完整的校验算法、超时控制、重发逻辑,并配套 WinForm 演示界面。本文基于 C# 原生SerialPort类,实现了一套生产可用。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 387

细说Flash存储芯片W25Q128FW和W25Q16BV

如果一次写入的数据超过页的边界,会再从页的起始位置开始写。W25Q128的操作指令由1字节或多字节组成,指令的第1个字节是指令码,其后跟随的是指令的参数或返回的数据。一定要注意,在没有完全搞清楚状态寄存器各个位的意义和用法之前,请勿随便修改状态寄存器的内容,因为有些位是非易失的,有些位还是一次性编程的,修改状态寄存器的内容可能改变器件的特性,甚至造成器件无法再使用。"写数据"指令的起始地址可以是任意地址,数据长度也可以小于256,但如果写的过程中地址超过页的边界,就会从页的起始地址开始继续写。

wenchm的博客 3881

2025华为杯第二十二届中国研究生数学建模竞赛D题:低空湍流监测及最优航路规划 - 完整解题分析+完整MATLAB源码!(下篇)

🎓 本文收录于 《滚雪球学数学建模》专栏,本专栏专注于从零基础出发,带你循序渐进掌握数学建模的核心方法与思维路径。通过“滚雪球式”学习法,从最简单的生活化案例到经典建模工具,再到省赛、国赛真题实战演练,逐步积累知识与技能,帮助你搭建完整的建模体系。无论你是刚接触建模的新生,还是希望提升科研与竞赛能力的学者与工程师,本专栏都将为你提供一条清晰、高效、可实操的建模成长路线,助力你快速进阶,突破难点,迈向数学建模竞赛与实际应用的更高峰 🚀!

**My Coding Family** 1622

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

嵌入式——Flash(W25Q64)

W25Q16、 W25Q32 和 W25Q64 支持标准的 SPl接口,传输速率最大 75 MHz,采用四线制,即4个引脚。① 串行 时钟引脚 (CLK)② 芯片 选择引脚 (CS)③ 串行数据 输出引脚(DO)④ 串行数据 输入 / 输出引脚(DIO):在普通情况下,该引脚是串行输入引脚(DI),当使用快读双输出指令时,该 引脚就变成了 输出引脚,在 这种情况下,芯片就有2个 DO引脚,所以称为双输出,其 通信速率 相当于翻了 一番,所以 传输速率更快。二、W25Q64特性。

CXDNW的博客 1万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Flash Rom存储器W25Q16/W25X16

认识Flash Rom FlashRom 是快速擦写只读存储器,也就是我们常说的“闪存”,单片机程序存储器就是Flash Rom,所谓“闪存”,就是一种非易失性的内存,属于EEPROM的改进产品。它的最大特点是必须按块对数据进行擦写操作,芯片容量大(W25Q16容量2M字节),而EEPROM则可以对单个字节进行操作,芯片容量较小(24c512容量65536字节)。前者容量是后者容量的32倍。另外F...

anny0884的博客 2万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

STM32学习开发记录:W25Q16(FLASH)——SPI

选用硬件:STM32F103 Nano开发板 板载有W25Q16 一、SPI协议简介 1、SPI的接线与数据 SPI:Serial Peripheral interface 串行外围设备接口 上图是SPI主机与从机设备间连线的关系,可以看出,主机主导了主机和从机的时序(SCLK),数据发送的流程是: 主机移位寄存器发送数据→MOSI→从机移位寄存器接收数据 从机移位寄存器发送数据→MISO→主机移位寄存器接收数据 两条线路发送数据是同步的。于是主机和从机的移位寄存器数据被交换。 只进行主机写入数据到从机时

Borton__的博客 1万+

细说STM32F407单片机轮询方式读写SPI FLASH W25Q16BV

本文旨在说明STM32F407单片机通过SPI1扩展FLASH W25Q16BV,对FLASH进行读ID、写操作、读操作、擦除操作。使用的是旺宝红龙开发板STM32F407ZGT6 KIT V1.0。使用开发板上的按键S2、S3、S4、S5、S6依此执行擦除芯片、擦除BLOCK0、写、读操作。使用开发板上的D2、D3、D4作为操作指示灯。通过串口USART3把操作状态显示到串口助手上。资源利用详见工程配置。工程里创建FLASH目录,包含w25flash.c、w25flash.h。

wenchm的博客 1858

Linux下SPI Flash-W25Q64驱动调试

   1 简介     W25Q64是华邦公司推出的大容量SPI FLASH产品,其容量为8M。该25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件。W25Q64将8M字节的容量分为128个块(block),每个块大小为64K字节,每个块又分为16个扇区(sector),每个扇区4K字节。W25Q64的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。所以,这需要给W25Q64开辟一...

weixin_40407893的博客 9291

W25Q64Flash芯片

W25Q64Flash芯片STM32操作 通讯方式:SPI通讯 大小:8M(Byte)   (128块(Block),每块64K字节,每块16个扇区(Sector),每个扇区4K字节,每个扇区16页,每页256个              字节) 特点:Flash芯片内的数据只能由1变0,不能由0变1。 引脚:  &nbs...

#elseif 1万+
上一篇: 【温酒笔记】SPI
下一篇: 【随手笔记】FLASH-W25Q16(四)
Long-Run
博客等级 码龄3年 4600粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值