首页 > 其他分享 >CH58x\CH57x硬件SPI操作外部flash学习记录

CH58x\CH57x硬件SPI操作外部flash学习记录

时间:2023-06-07 16:00:15浏览次数:43  
标签:CH57x 12 Pin flash SPI0 uint8 SPI GPIO MasterSendByte

官方提供的58x的spi例程,spi主机模式下的发送方式有三种单字节发送,FIFO连续发送,DMA连续发送。本文分别对SPI0主机模式下三种发送模式进行使用。

本次使用的是CH582m做为主机,W25Q64FV作为从机。

一、单字节发送

本次调试中实现对W25Q64FVflas进行读id,擦除,写入,读取。

在进行主要操作的时候先理清代码逻辑。主机先将SCS总线拉低,保证能够开始接收数据。再通过W25Q64FV的手册我们知道在进行操作之前要判断当前是否在

忙碌状态。如果不在忙碌状态将进行下一步。通过手册我们可以知道通过发送对应的地址(0x05or0x35)进行判忙。

 程序中实现判断忙碌的操作可见如下:

void SPI_Flash_Wait_Busy(void)
{
    uint8_t busy;
    do
    {
        GPIOA_ResetBits(GPIO_Pin_12);
        SPI0_MasterSendByte(0x05);

        busy=SPI0_MasterRecvByte();
        GPIOA_SetBits(GPIO_Pin_12);

        PRINT("busy%02x\r\n",busy);
    }
    while((busy&0x01)==0x01);

}

接下来基本就按照需要使用的器件的手册进行读写等操作:

(1)、读ID:

读ID看是否能够读到正确的设备ID:

#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16
#define W25Q128 0XEF17

 

 我们读ID根据手册的提示需要对就相应的寄存器地址进行操作;程序演示如下所示:

void read_wq64_id(void)
{
    uint8_t ID1,ID2;
    GPIOA_ResetBits(GPIO_Pin_12);
    SPI0_MasterSendByte(0x90);
    SPI0_MasterSendByte(0x00);
    SPI0_MasterSendByte(0x00);
    SPI0_MasterSendByte(0x00);
    ID1=SPI0_MasterRecvByte();
    ID2=SPI0_MasterRecvByte();
    GPIOA_SetBits(GPIO_Pin_12);

    PRINT("%02x\r\n %02x\r\n ",ID1,ID2);

}

读取到的数据是EF16证明读取的ID没有问题。如果是其他的值可以在程序加判断直到是自己使用器件的ID再在进行下面的操作;

(2)、擦除扇区

在写之前要对对应的扇区进行擦除,

 从手册上可以看出是4k擦除,还要注意在指令之后有24bit地址的操作,写入20h后需要进行移位操作,详情可见程序

手册中有这样一句话:A Write Enable instruction must be executed before the device will accept the Sector Erase Instruction (Status Register bit WEL must equal 1)。在进行擦除操作之前需要写使能:

所以擦除之前需要进行写使能:对应时序操作如下

 代码实现:

void SPI_Write_Enable(void)
{
    GPIOA_ResetBits(GPIO_Pin_12);
    SPI0_MasterSendByte(0x06);
    GPIOA_SetBits(GPIO_Pin_12);

}

下面的则是擦除部分的代码:

void erase_sector(uint32_t SectorAddress)
{
    SectorAddress *= 4096;
    SPI_Write_Enable();
    SPI_Flash_Wait_Busy();
    GPIOA_ResetBits(GPIO_Pin_12);
    SPI0_MasterSendByte(0x20);

    SPI0_MasterSendByte((uint8_t)(SectorAddress>>16));
    SPI0_MasterSendByte((uint8_t)(SectorAddress>>8));
    SPI0_MasterSendByte((uint8_t)SectorAddress);
    GPIOA_SetBits(GPIO_Pin_12);

}

(3)读操作,

进行读操作的情况下;读的操作稍微方便一些不需要进行判忙写使能等操作

 在进行读操作的时,注意时序图中有一个Data Out 1,此时会有输出

void read_wq64_data(uint8_t instruction,uint32_t ReadAddr,uint16_t ReadByteNum,uint8_t *p_Buffer)
{
     uint16_t i;
     GPIOA_ResetBits(GPIO_Pin_12);
     SPI0_MasterSendByte(instruction);
     SPI0_MasterSendByte((uint8_t)(ReadAddr>>16));
     SPI0_MasterSendByte((uint8_t)(ReadAddr>>8));
     SPI0_MasterSendByte((uint8_t)ReadAddr);

     for(i = 0; i < ReadByteNum; i++)
     {
         p_Buffer[i] = SPI0_MasterRecvByte();

     }
     GPIOA_SetBits(GPIO_Pin_12);

}

(5)写操作;

本次写入是按页写入,写之前先看手册注意手册中需要操作的部分

 

 对应程序如下所示:

void  write_wq64_page_data(uint8_t *p_Buffer,uint32_t PageAddress,uint16_t WriteByteNum)
{
    SPI_Write_Enable();

    GPIOA_ResetBits(GPIO_Pin_12);
    SPI0_MasterSendByte(0x02);
    SPI0_MasterSendByte((uint8_t)(PageAddress>>16));
    SPI0_MasterSendByte((uint8_t)(PageAddress>>8));
    SPI0_MasterSendByte((uint8_t)PageAddress);
    if(WriteByteNum > 256)
    {
        WriteByteNum=256;
        PRINT("\r\n Err");
    }
    while(WriteByteNum--)
    {
        SPI0_MasterSendByte(*p_Buffer);
        p_Buffer++;
    }
    GPIOA_SetBits(GPIO_Pin_12);
    SPI_Flash_Wait_Busy();
}

差不多一个流程就是如此;可以在程序中加入打印或者使用逻辑分析仪等辅助工具对现象进行查看。

准备写入的数据__attribute__((aligned(4))) UINT8 spiBuff[] = {2, 2, 3, 3, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6};读出的结果如下

本次操作关键是对片选信号线的操作与对不同指令的读写操作,具体按照手册的时序的操作来即可。

 仅是个人学习分享;如有任何错漏敬请留言指正。

 

标签:CH57x,12,Pin,flash,SPI0,uint8,SPI,GPIO,MasterSendByte
From: https://www.cnblogs.com/frontier/p/17090216.html

相关文章

  • 将stm32 flash和栈相结合,将栈底位置设置成flash地址,可不可以?
      在使用stm32产生了一个疑问,可不可以将栈底位置设置成flash的某个具体位置,这样就可以将参数写入读取,于是便探寻可行性。 在STM32中,Flash存储器用于存放程序代码,而栈通常用于存放临时数据和变量。根据STM32架构设计,Flash和SRAM两者之间是相互独立的,Flash的写入和读取速度相......
  • STM32F429 Discovery开发板应用:实现SPI-SD Card文件写入(搭载FatFS文件系统)
    MCU:STM32F429ZIT6开发环境:STM32CubeMX+MDK5 外购了一个SPI接口的SDCard模块,想要实现SD卡存储数据的功能。首先需要打开STM32CubeMX工具。输入开发板MCU对应型号,找到开发板对应封装的MCU型号,双击打开(图中第三)。 此时,双击完后会关闭此界面,然后打开一个新界面。 ......
  • Spring 学习笔记(3)—— Spirng 配置概述
    Spring容器高层视图Spring启动时读取应用程序提供的Bean配置信息(XML配置文件),并在Spring容器(ApplicationContext)中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,为上层因公提供准备就绪的运行环境。Bean元数据信息在Spring容器......
  • spingboot maven 使用简化配置 将本地包加入classpath
    不是使用dependencyManagement<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version><relativePath......
  • spire.ocr 报错无法加载 DLL"spire_ocrsystem.dll"
    出现这个错误的时候,用以下2个步骤解决:第一,要检查类库的运行平台是否已经改成了x64,因为spire.ocr是基于64位平台的 第二,缺少VC运行库,安装VC运行库即可运行库的下载地址:https://pan.baidu.com/s/1lQwyqaS-Ba2ns0BRT5Z7Eg  提取码:wgja ......
  • Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解)..
    播放器版本11.2以后支持右键菜单屏蔽及自定义菜单1.更新播放器,11.2以上版本http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_3.swchttp://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_4.swchttp://download.macro......
  • 树莓派如果通过 raspi-config 关闭桌面模式 All In One
    树莓派如果通过raspi-config关闭桌面模式AllInOne树莓派设置启动模式:切换桌面模式和命令行模式DesktopCommandLineGUIvsCLI图形化界面vs命令行$sudoraspi-config$sudovim/boot/config.txt$sudoreboot$sudoshutdwon-hnowautologinde......
  • 要编译代码以控制其在Flash或SRAM中运行
    要编译代码以控制其在Flash或SRAM中运行,您需要在编译过程中进行一些配置。以下是一些建议:1.使用链接脚本链接脚本是在编译过程中使用的一种文件,用于控制程序代码和数据在内存中的布局。您可以在链接脚本中指定代码应存储在哪个内存区域(例如Flash或SRAM)。例如,在GNUGCC工具链中......
  • 嵌入式进阶之关于SPI通信的案例分享——基于全志科技T3与Xilinx Spartan-6处理器
    本文主要介绍基于全志科技T3与XilinxSpartan-6的通信案例。适用开发环境:Windows开发环境:Windows764bit、Windows1064bitLinux开发环境:Ubuntu18.04.464bit虚拟机:VMware15.1.0U-Boot:U-Boot-2014.07Kernel:Linux-3.10.65LinuxSDK:LinuxSDK_AA_BB_CC_DD(基于T3_LinuxSDK_V1.......
  • spinner自定义[转]
    转自:https://www.jianshu.com/p/7b03ade29091spinner_drop_down_shape的代码<?xmlversion="1.0"encoding="utf-8"?><layer-listxmlns:android="http://schemas.android.com/apk/res/android"><item><shap......