标题:C51 单片机与spiflash连接只能读,不能写,麻烦各位看看
只看楼主
zcl2013c
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2013-10-28
结帖率:60%
 问题点数:0 回复次数:0 
C51 单片机与spiflash连接只能读,不能写,麻烦各位看看
程序代码:
#include "REG51.h"
#include "intrins.h"
#include <stdio.h>
#include <string.h>
#include "spi.c"    

#define uchar  unsigned char

//typedef bit BOOL;
//typedef unsigned char BYTE;
//typedef unsigned short WORD;
//typedef unsigned long DWORD;




#define SF_WREN        0x06 //Flash命令 
#define SF_WRDI        0x04
#define SF_RDSR        0x05
#define SF_WRSR        0x01
#define SF_READ        0x03
#define SF_FASTREAD    0x0B
#define SF_RDID        0x90
#define SF_PAGEPROG    0x02
//#define SF_RDCR        0xA1
//#define SF_WRCR        0xF1
#define SF_SECTORER    0x20
#define SF_BLOCKER1    0x52   //32KB
#define SF_BLOCKER2    0xD8   //64KB
#define SF_CHIPER      0xC7


//#define NULL            0
//#define FALSE           0
//#define TRUE            1

#define BUFFER_SIZE     256                    //缓冲区大小
#define TEST_ADDR       512                       //Flash测试地址

uchar idflag;
//uchar m=256;
uchar g_Buffer[BUFFER_SIZE];

/*
void waitsend();
void UART_Initial();
void send_char( uchar ch);
void spi_write(unsigned char spi_dat);
unsigned char spi_read();
//BYTE SpiShift(BYTE dat);
 FlashCheckID();
void FlashBusy();
void FlashWriteEnable();
void FlashErase();
void FlashChipErase();
void FlashSectorErase();
void FlashBlockErase();

void FlashRead( addr,  size,unsigned char  *buffer);
void FlashWrite( addr,  size,unsigned char  *buffer);
*/







 void waitsend()
{
     TI = 0;
     ES = 0;
     while(!TI)
     {
     };
     TI = 0;
     ES = 1;
}



 void delay(long i)
 {
   long  j;
   for(j=0;j<i;j++)
     {
       SomeNOP();
       SomeNOP();
      }
 }



 void delay1ms(long  i)
 {
   long  j;
   for(j=0;j<i;j++)
     {
       delay(70);
      }
 }



// UART 
void UART_Initial()   
{
    SCON = 0x50; //串口方式1,允许接收
    TMOD = 0x20; //定时计数器1方式2
    TH1 = 0xFD;    //9600 波特率 FD
    TL1 = 0xFD;
    EA=1;      
    ES=1;      
    TR1 = 1;
}

//向串口发送一个字符 
void send_char( uchar ch)
{
    SBUF=ch;
    //delay1ms(1);
    //while (TI==0);
    //TI=0;
}

/************************************************
使用SPI方式与Flash进行数据交换
入口参数:
    dat : 准备写入的数据
出口参数:
    从Flash中读出的数据
************************************************
BYTE SpiShift(BYTE dat)
{
    SPDAT = dat;                                //触发SPI发送
    while (!(SPSTAT & SPIF));                   //等待SPI数据传输完成
    SPSTAT = SPIF | WCOL;                       //清除SPI状态
   
    return SPDAT;
}
*/



/************************************************
检测FlashID
 W25Q16:0XEF14

************************************************/
unsigned char FlashCheckID()
{
    uchar dat1,dat2;
    uchar flag=0;
   
    spi_cs = 0;
    spi_write(SF_RDID);                         //发送读取ID命令
    spi_write(0x00);                             //空读3个字节
    spi_write(0x00);
    spi_write(0x00);
    dat1 = spi_read();                      //读取制造商ID1
    dat2 = spi_read();                      //读取制造商ID2
    spi_cs = 1;
    flag = ((dat1==0xef)&&(dat2==0x14));                                              
    return flag;
}

/************************************************
检测Flash的忙状态读状态寄存器1
入口参数: 无
出口参数:
    0 : Flash处于空闲状态
    1 : Flash处于忙状态

************************************************/
 FlashBusy(void)
{
    uchar dat;
   
    spi_cs = 0;
    spi_write(SF_RDSR);                         //发送读取状态命令
    dat = spi_read();                          //读取状态
    spi_cs = 1;   
    return (dat & 0x01);                        //状态值的Bit0即为忙标志
}

/************************************************
使能Flash写命令
入口参数: 无
出口参数: 无

************************************************/
void FlashWriteEnable()
{
   // while (FlashBusy());                      //Flash忙检测
    spi_cs = 0;
    spi_write(SF_WREN);                         //发送写使能命令
    spi_cs = 1;
    //delay1ms(10);
}

/************************************************
擦除整片Flash
入口参数: 无
出口参数: 无

************************************************/
void FlashChipErase()
{
   
   
        FlashWriteEnable();                     //使能Flash写命令
        spi_cs = 0;
        spi_write(SF_CHIPER);                   //发送擦除命令
        spi_cs = 1;
   
}


/************************************************
擦除扇区Flash
入口参数: addr
出口参数: 无

************************************************/
void FlashSectorErase(unsigned long addr)
{
   
   
        FlashWriteEnable();                     //使能Flash写命令
        spi_cs = 0;
        spi_write(SF_SECTORER);                   //发送擦除命令
        spi_write(addr>>16 & 0xff);           //设置起始地址
        spi_write(addr>>8 & 0xff);
        spi_write(addr & 0xff);
        spi_cs = 1;
   
}

/************************************************
擦除BlockFlash(64KB)
入口参数: 无
出口参数: 无

************************************************/
void FlashBlockErase()
{
   
   
        FlashWriteEnable();                     //使能Flash写命令
        spi_cs = 0;
        spi_write(SF_BLOCKER2);                   //发送擦除命令
        spi_cs = 1;
   
}


/************************************************
从Flash中读取数据fastread
入口参数:
    addr   : 地址参数
    size   : 数据块大小
    buffer : 缓冲从Flash中读取的数据
出口参数:
    无
   
************************************************/
void FlashRead(unsigned long addr,unsigned long size, unsigned char *buffer)
{       
        while (FlashBusy());                  //Flash忙检测
        spi_cs = 0;
        spi_write(SF_FASTREAD);                 //使用快速读取命令
        spi_write(addr>>16 & 0xff);           //设置起始地址
        spi_write(addr>>8 & 0xff);
        spi_write(addr & 0xff);
        spi_write(0x00);                            //需要空读一个字节
        while (size)
        {
            *buffer = spi_read();              //自动连续读取并保存
            addr++;
            buffer++;
            size--;
        }
        spi_cs = 1;   
}

/************************************************
写数据到Flash中
入口参数:
    addr   : 地址参数
    size   : 数据块大小
    buffer : 缓冲需要写入Flash的数据
出口参数: 无
************************************************/
void FlashWrite(  unsigned long addr,unsigned long size, unsigned char *buffer)
{
    //while (FlashBusy());
    while (size)
    {
        //uchar i;
        FlashWriteEnable();                     //使能Flash写命令
        spi_cs = 0;
        spi_write(SF_PAGEPROG);                 //发送页编程命令
        spi_write(addr>>16 & 0xff);           //设置起始地址
        spi_write(addr>>8 & 0xff);
        spi_write(addr & 0xff);
        //for (i=0; i<0x100; i++)
        //{
            //spi_write(*buffer);
            //size--;
            //buffer++;
        //}
       
        while (size)
        {
            spi_write(*buffer);                  //连续页内写
            buffer++;
            addr++;
            //buffer++;
            size--;
            if ((addr & 0xff) == 0) break;
        }
        //send_char(addr>>16);
        //send_char(addr>>8);
        //send_char(addr);
        spi_cs = 1;
    }
}


void main()
{
    int i;
    for (i=0; i<BUFFER_SIZE; i++)
    {
    g_Buffer[i]=i;
    }
   
    //初始化Flash状态
    //g_fFlashOK = FALSE;
   
    //初始化串口
    UART_Initial();
    delay1ms(2);
    FlashSectorErase(TEST_ADDR);
    delay1ms(200);
    while(1)
    {

        //for (i=0; i<BUFFER_SIZE; i++)
        //{
            //send_char(g_Buffer[i]),waitsend();
            //delay1ms(100);
        //}
        //i=0;
        //检测Flash状态
        idflag = FlashCheckID();
        send_char(idflag),waitsend();
        delay1ms(1000);
        //send_char(0x01), waitsend();
  
        //将缓冲区的数据写到Flash中
        FlashWrite(TEST_ADDR, BUFFER_SIZE, g_Buffer);
        //send_char(addr);
        delay1ms(100);
        //读取测试地址的数据
        FlashRead(TEST_ADDR, BUFFER_SIZE, g_Buffer);
        delay1ms(100);
        //发送到串口
        for (i=0; i<BUFFER_SIZE; i++)
        {   
            send_char(g_Buffer[i]),waitsend();
            delay1ms(100);
        }
    /*
    //擦除Flash
    FlashErase();
    //读取测试地址的数据
    FlashRead(TEST_ADDR, BUFFER_SIZE, g_Buffer);
    //发送到串口
    for (i=0; i<BUFFER_SIZE; i++) SendUart(g_Buffer[i]);
   
    //修改置缓冲区
    for (i=0; i<BUFFER_SIZE; i++) g_Buffer[i] = i>>2;
    //将缓冲区的数据写到Flash中
    FlashWrite(TEST_ADDR, BUFFER_SIZE, g_Buffer);
   
    //读取测试地址的数据
    FlashRead(TEST_ADDR, BUFFER_SIZE, g_Buffer);
    //发送到串口
    for (i=0; i<BUFFER_SIZE; i++) SendUart(g_Buffer[i]);
   
    FlashErase();
    //读取测试地址的数据
    FlashRead(TEST_ADDR, BUFFER_SIZE, g_Buffer);
    //发送到串口
    for (i=0; i<BUFFER_SIZE; i++) SendUart(g_Buffer[i]);
   
    //修改置缓冲区
    for (i=0; i<BUFFER_SIZE; i++) g_Buffer[i]= 255-(i>>2);
    //将缓冲区的数据写到Flash中
    FlashWrite(TEST_ADDR, BUFFER_SIZE, g_Buffer);
   
    //读取测试地址的数据
    FlashRead(TEST_ADDR, BUFFER_SIZE, g_Buffer);
    //发送到串口
    for (i=0; i<BUFFER_SIZE; i++) SendUart(g_Buffer[i]);
    */
    }

}
flash是w25q16
搜索更多相关主题的帖子: include 单片机 Flash 
2014-02-18 15:03



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-427398-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.295294 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved