⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialize.c

📁 M25P20 flash SPI口驱动程序。。。。。。。。。。。。。
💻 C
📖 第 1 页 / 共 2 页
字号:
#define SPI_SCK  P1_5	        //串行时钟
#define SPI_MOSI P1_6			//串行数据主输出从输入
#define SPI_MISO P1_7			//串行数据主输入从输出
#define SPI_NSS  P1_4			//从选择
#define SPI_WP   P1_3			//写保护


/*--------------------------------------------------------------------------------*/

   #define EXPECTED_DEVICE (0x8012)      /* Device code for the M25PE20 */
   #define FLASH_SIZE (0x040000)	 /* Total device size in Bytes */
   #define FLASH_PAGE_COUNT (0x0400)	 /* Total device size in Pages */
   #define FLASH_SECTOR_COUNT (0x04)     /* Total device size in Sectors */
   #define FLASH_WRITE_BUFFER_SIZE 0x100 /* Write Buffer = 256 bytes */
   #define FLASH_MWA 1                   /* Minimum Write Access */


#define ManufacturerID		0x20		//厂商ID
#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define High  1
#define Low   0

//spiflash指令
#define WREN        0x06        //写使能
#define WRDI        0x04        //写禁止
#define RDID        0x9F        //读ID
#define RDSR        0x05        //读状态寄存器
#define WRSR        0x01        //写状态寄存器
#define READ        0x03        //读数据
#define FAST_READ   0x0B        //快速读
#define PP          0x02        //页编程
#define SE          0xD8        //扇区擦除

unsigned char pre_treat(void);
unsigned char now_is_writing = 0;
//-------SPIBus operation Function-----------------------
void SPI_SendOneByte(unsigned char ch)  //发送一个字节
{
    unsigned char n;
    n = 8;
    while(n)
    {
        if(ch&0x80)
          SPI_MOSI = High;
        else
          SPI_MOSI = Low;
        SPI_SCK = High;
        ch = ch << 1;
        n--;
        SPI_SCK =  Low;
    }
}
unsigned char SPI_ReceiveOneByte(void)          //接受一个字节
{
    unsigned char ch,n;
    ch = 0;
    n = 8;
    while(n)
    {
        SPI_SCK = High;
        ch = ch<<1;
        if(SPI_MISO)
            ch|=0x01;
        SPI_SCK = Low;
        n--;
    }
    return ch;
}

void SPIFlashWriteEnable(void)
{
    SPI_WP  = Low;
    SPI_NSS = Low;  //选择从器件
    SPI_SendOneByte(WREN);
    SPI_NSS = High;
    SPI_WP  = High;
}

unsigned char SPIFlashReadStatusReg(void)    //读SPIFlash的状态寄存器
{
    unsigned char ch1;
    SPI_WP  = Low;
    SPI_NSS = Low;
    SPI_SendOneByte(RDSR);
    ch1 = SPI_ReceiveOneByte();
    SPI_NSS = High;
    SPI_WP  = High;
    return ch1;
}

unsigned char SPIFlashWriteStatusReg(unsigned char value)   //写SPIFlash的状态寄存器
{
    if(pre_treat()) return FALSE;

    SPIFlashWriteEnable();

    SPI_WP  = Low;
    SPI_NSS = Low;
    SPI_SendOneByte(WRSR);
    SPI_SendOneByte(value);
    SPI_NSS = High;
    SPI_WP  = High;

    now_is_writing = 1;

    return TRUE;
}

unsigned char SPIFlashPageWrite(unsigned long addr, unsigned char *wbuf, unsigned char wlen)
{
    if(pre_treat()) return FALSE;

    SPIFlashWriteEnable();

    SPI_WP  = Low;
    SPI_NSS = Low;

    SPI_SendOneByte(PP);
    SPI_SendOneByte(addr>>16);
    SPI_SendOneByte(addr>>8);
    SPI_SendOneByte(addr);

    while(wlen)
    {
        wlen--;
        SPI_SendOneByte(*wbuf);
        wbuf++;
    }

    SPI_NSS = High;
    SPI_WP  = High;

    now_is_writing = 1;

    return TRUE;
}

unsigned char pre_treat(void)       //return 1--fail
{
    unsigned long cc;

    if(!now_is_writing)
        return 0;

    cc = COUNT_FOR_WRITE_DELAY;
    while(cc)
    {
        cc--;
        if(SPIFlashReadStatusReg()&0x01)
            continue;
        else
        {
            now_is_writing = 0;
            return 0;
        }
    }

    return 1;
}

unsigned char SPIFLASH_init(void)
{
    unsigned char ch;

    ch = SPIFlashReadStatusReg();

    if((ch&0x61)!=0x00)
        return FALSE;

    if((ch&0x9c)!=0x9c)
        SPIFLASH_protect();



    return TRUE;
}

unsigned char SPIFLASH_protect(void)    //   硬件保护SPIFlash
{
    if(pre_treat()) return FALSE;

    SPI_WP = Low;
    SPIFlashWriteEnable();

    SPIFlashWriteStatusReg(0x9C);
    SPI_WP = High;

    now_is_writing = 1;

    return TRUE;
}

unsigned char SPIFLASH_unProtect(void)      //   解保护
{
    if(pre_treat()) return FALSE;

    SPI_WP = High;
    SPIFlashWriteEnable();

    SPIFlashWriteStatusReg(0x00);

    now_is_writing = 1;

    return TRUE;
}

unsigned char SPIFLASH_erase_sector(unsigned char sectorNo)
{
    if(sectorNo >= FLASH_SECTOR_COUNT)
        return  FALSE;

    if(pre_treat()) return FALSE;

    SPIFlashWriteEnable();

    SPI_NSS = Low;
    SPI_WP  = Low;
    SPI_SendOneByte(SE);
    SPI_SendOneByte(sectorNo);         //sectorNo 0  address  00000~0ffff
    SPI_SendOneByte(0x00);             //要发3字节的指令
    SPI_SendOneByte(0x00);

    SPI_NSS = High;
    SPI_WP  = High;
    now_is_writing = 1;

    return TRUE;
}

unsigned char SPIFLASH_read(unsigned long addr, unsigned char *rbuf, unsigned char rlen)
{
    if(addr + rlen > FLASH_SIZE)
        return FALSE;

    if(pre_treat()) return FALSE;

    SPI_NSS = Low;
    SPI_WP  = Low;

    SPI_SendOneByte(READ);
    SPI_SendOneByte(addr>>16);
    SPI_SendOneByte(addr>>8);
    SPI_SendOneByte(addr);

    while(rlen)
    {
        *rbuf = SPI_ReceiveOneByte();
        rbuf++;
        rlen--;
    }

    SPI_NSS = High;
    SPI_WP  = High;

    return TRUE;
}

unsigned char SPIFLASH_write(unsigned long addr, unsigned char *wbuf, unsigned char wlen) // 写数据
{
    unsigned char PageMargin;

    if((addr + wlen) >= FLASH_SIZE)              //要写入的数据最后是否超出容量
        return FALSE;

    PageMargin =(unsigned char)(~addr) + 1;

    if((wlen>PageMargin) && (PageMargin!=0) )
    {
        if(!SPIFlashPageWrite(addr,wbuf,PageMargin))
            return FALSE;

        wlen -= PageMargin;
        wbuf += PageMargin;
        addr += PageMargin;
    }

    return SPIFlashPageWrite(addr,wbuf,wlen);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -