野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15798|回复: 4

分享一个软件模拟SPI读写Flash-W25Q16的程序文件

[复制链接]
发表于 2018-10-16 22:07:11 | 显示全部楼层 |阅读模式
软件模拟SPI 读写flash W25Q16 mode 0 3 可以正确读写;mode2似乎也可以:

main.c 代码如下;
#include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
//#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_systick.h"
//#include "cycle_queue.h"
#include "bsp_spi_soft_flash.h"
#include "stdio.h"

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

/* 获取缓冲区的长度 */
#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define RxBufferSize1   (countof(TxBuffer1) - 1)
#define countof(a)      (sizeof(a) / sizeof(*(a)))
#define  BufferSize (countof(Tx_Buffer)-1)

#define  FLASH_WriteAddress     0x000000
#define  FLASH_ReadAddress      FLASH_WriteAddress
#define  FLASH_SectorToErase    FLASH_WriteAddress


/* 发送缓冲区初始化 */
//uint8_t Tx_Buffer[] = "感谢您选用秉火stm32开发板\r\n";


//  NUM : 100
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRST\r\n";

//  NUM : 127
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu\r\n";


//  NUM : 128
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv\r\n";


//  NUM : 255
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRS\r\n";

//  NUM : 256
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\r\n";

// NUM : 258
//uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUV\r\n";

// NUM : 514
uint8_t Tx_Buffer[] = "abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUVabcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNOPQRSTUV\r\n";

//uint8_t Tx_Buffer[] = "\
//零一二三四五六七八九十百千万亿兆\
//零一二三四五六七八九十百千万亿兆\
//\r\n";
#if 0              //  write 4096 BYTE include /r/n   
uint8_t Tx_Buffer[] = "\
我有一个梦想我没有梦想\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿兆\
零一二三四五六七八九十百千万亿\
\r\n";
#endif
uint8_t Rx_Buffer[5000];

__IO uint32_t DeviceID = 0;
__IO uint32_t FlashID = 0;
__IO TestStatus TransferStatus1 = FAILED;

// 函数原型声明
void Delay(__IO uint32_t nCount);
TestStatus Buffercmp(uint8_t* pBuffer1,uint8_t* pBuffer2, uint16_t BufferLength);


extern uint8_t Usart_data_Test[] = "0123abc";

int main(void)
{
        uint16_t i;
        uint8_t Udata[30] = "012345678a";
        USART1_GPIO_Config();

        Dms(1000);
        USART_Send_String(USART1, Udata);
        printf("\n 2Mbyte SPI flash W25Q16 实验 \n");
       
        /* 2M串行flash W25Q16初始化 */
        SPI_soft_FLASH_Init();
       
        /* 获取 Flash Device ID */
        DeviceID = SPI_soft_FLASH_ReadDeviceID();
        Delay( 200 );       
        /* 获取 SPI Flash ID */
        FlashID = SPI_soft_FLASH_ReadID();       
        printf("\n FlashID is 0x%X,        Manufacturer Device ID is 0x%X\n", FlashID, DeviceID);
       
        /* 检验 SPI Flash ID */
        if (FlashID == sFLASH_ID)
        {       
                printf("\n found flash W25Q16 !\n");
               
                /* 擦除将要写入的 SPI FLASH 扇区,FLASH写入前要先擦除 */
                // 这里擦除4K,即一个扇区,擦除的最小单位是扇区
                //SPI_FLASH_SectorErase(FLASH_SectorToErase);         
                SPI_soft_FLASH_SectorErase(0x000000);        // sector 0
                SPI_soft_FLASH_SectorErase(0x001000);        // sector 1
//                SPI_FLASH_BulkErase();
//                SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
//                printf("\n read data from flash!\n");
//                printf("  %s  \n", Rx_Buffer);
               
//                SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, 4096);
//                for(i=0;i<4096;i++)
//                printf("num = %d 擦除后的扇区数据为:%d\n",i,Rx_Buffer[i]);
//               
                /* 将发送缓冲区的数据写到flash中 */
                // 这里写一页,一页的大小为256个字节
#if 1
                SPI_soft_FLASH_BufferWrite(Tx_Buffer, 0x000ff8,BufferSize);
                printf("\n 写入的数据长度为:%d\n", BufferSize);
//                printf("\n  写入的数据为: %s\n", Tx_Buffer);
               
                /* 将刚刚写入的数据读出来放到接收缓冲区中 */
                SPI_soft_FLASH_BufferRead(Rx_Buffer, 0x000ff8,BufferSize);
//                printf("\n read data from flash!\n");/*  flash!后面只有一个空格时(或者是奇数个空格,这个情况应该是和汉字编码有关,汉字编码一个汉字占2个字节)
//                后面答应的Rx_Buffer会出现乱码;前后空格的原因导致乱码; */
//                printf("  %s  \n", Rx_Buffer);
                for(i=0;i<BufferSize;i++)
                printf("num =%4d->%.2c  ",i,Tx_Buffer[i]);
                printf("\n");
                for(i=0;i<BufferSize;i++)
                printf("num =%4d->%.2c  ",i,Rx_Buffer[i]);
                printf("\n");
//                                SPI_FLASH_BufferRead(Rx_Buffer, 0x000000,1024);
//                                SPI_FLASH_BufferFastRead(Rx_Buffer, 0x000000, 1024);
//                                                for(i=0;i<1024;i++)
//                                                printf("num =%4d->%.2c  ",i,Rx_Buffer[i]);
#endif
//                USART_Send_String(USART1,"\n read data from flash!\n");
//                printf("\n 读出的数据为:\n");

//                printf("\r\n er读出的数据为:\r\n");
//                USART_Send_String(USART1,Rx_Buffer);
                /* 检查写入的数据与读出的数据是否相等 */
                TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
               
                if( PASSED == TransferStatus1 )
                {
                        printf("\n 2M spi soft flash W25Q16  测试成功!\n");
                }
                else
                {        
                        printf("\n 2M spi soft flash W25Q16  测试失败!\n");
                }
               
               
//                SPI_soft_FLASH_BufferRead(Rx_Buffer, 0x000ff8,1024);
//                for(i=0;i<1024;i++)
//                printf("num =%4d->%.2c  ",i,Rx_Buffer[i]);
               
               
        }// if (FlashID == sFLASH_ID)
        else// if (FlashID == sFLASH_ID)
        {
                printf("\n connot found W25Q16 ID!\n");
        }
       
       
       
        while(1)
        {               
                Dms(20000);
                printf("  hello \n");
        }
}



/*
* 函数名:Buffercmp
* 描述  :比较两个缓冲区中的数据是否相等
* 输入  :-pBuffer1     src缓冲区指针
*         -pBuffer2     dst缓冲区指针
*         -BufferLength 缓冲区长度
* 输出  :无
* 返回  :-PASSED pBuffer1 等于   pBuffer2
*         -FAILED pBuffer1 不同于 pBuffer2
*/
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }

    pBuffer1++;
    pBuffer2++;
  }
  return PASSED;
}

void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}
/*********************************************END OF FILE**********************/





spi_soft_flash.rar

5.36 KB, 下载次数: 107

回复

使用道具 举报

发表于 2018-10-17 08:51:39 | 显示全部楼层
谢谢分享
回复

使用道具 举报

发表于 2020-2-11 09:35:33 | 显示全部楼层
感谢分享,去试试
回复 支持 反对

使用道具 举报

发表于 2020-2-11 15:29:38 | 显示全部楼层
貌似是不行啊,
读不出来FLASH ID,
代码看着似乎没问题,
回复 支持 反对

使用道具 举报

发表于 2020-2-11 21:37:32 | 显示全部楼层
代码可以运行,至少模式3可以。个人代码其它地方犯低级错误了,折腾多半天,
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-7 09:36 , Processed in 0.041194 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表