W25X16测试程序

平台:stc12le5a60+W25X16+keil

W25X16.H

W25X.H
 1 #ifndef _W25X_H_
 2  #define  _W25X_H_
 3 
 4 #include <REG52.H>
 5 
 6 #define    uint8    unsigned char
 7 #define    uint16    unsigned int
 8 #define    uchar    unsigned char
 9 #define    uint    unsigned int
10 #define    uint32    unsigned long
11 
12 sbit    W25X_HOLD= P1^2;
13 sbit    W25X_WP    = P1^3;
14 sbit    W25X_CS    = P1^4;
15 sbit    W25X_DI    = P1^5;
16 sbit    W25X_DO    = P1^6;
17 sbit    W25X_CLK= P1^7;
18 
19 #define nop() _nop_()
20 
21 #define W25X_WriteEnable        0x06    //写使能  备注:xcc
22 #define W25X_WriteDisable        0x04     //写禁能
23 #define W25X_ReadStatusReg        0x05    //读状态寄存器
24 #define W25X_WriteStatusReg        0x01       //写状态寄存器
25 #define W25X_ReadData            0x03       //读数据
26 #define W25X_FastReadData        0x0B      //读数据
27 #define W25X_FastReadDual        0x3B      //快读双输出
28 #define W25X_PageProgram        0x02     //页编程
29 #define W25X_BlockErase            0xD8     //块擦除
30 #define W25X_SectorErase        0x20     //扇区擦除
31 #define W25X_ChipErase            0xC7     //芯片擦除
32 #define W25X_PowerDown            0xB9     //掉电
33 #define W25X_ReleasePowerDown    0xAB     //释放掉电
34 #define W25X_DeviceID            0xAB      //器件ID
35 #define W25X_ManufactDeviceID    0x90      //制造/器件ID
36 #define W25X_JedecDeviceID        0x9F      //JEDEC ID
37 
38 
39 
40 uchar    SPI_Read_StatusReg();
41 void    SPI_Write_StatusReg(byte);
42 void    SPI_Write_Enable();
43 void    SPI_Write_Disable();
44 uchar    SPI_Read_ID1();
45 uint    SPI_Read_ID2(uchar ID_Addr);
46 uint    SPI_Read_ID3();
47 uchar    SPI_Read_Byte(uint32 Dst_Addr); 
48 void    SPI_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128);
49 uchar    SPI_FastRead_Byte(uint32 Dst_Addr); 
50 void    SPI_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128);
51 void    SPI_Write_Byte(uint32 Dst_Addr, uchar byte);
52 void    SPI_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128);
53 void    SPI_Erase_Chip();
54 void    SPI_Erase_Sector(uint32 Dst_Addr);
55 void    SPI_Wait_Busy();
56 void    SPI_PowerDown();
57 void    SPI_ReleasePowerDown();
58 void    SPI_init();
59 void    SPI_Send_Byte(uchar out);
60 uchar    SPI_Get_Byte();
61 void    delay_nms(uchar i);
62 void    delay(uchar tt);
63   
64 #endif

W25X.C

W25X.C
  1 #include <W25X.H>
  2 #include <REG52.H>                                    
  3 #include <intrins.h>
  4 
  5 extern    uint8 upper_128[16];
  6 extern    uint8 tx_buff[16];
  7                                     
  8 void    delay_nms(uchar i)
  9 {    uchar  j;
 10     i=i*2;
 11     for(;i>0;i--)    {   j = 246;    while(--j);    }
 12 }
 13 void    delay(uchar tt)
 14 {    while(tt--);}
 15 //=================================================================================================
 16 //SPI_Read_StatusReg        Reads the status register of the serial flash
 17 //SPI_Write_StatusReg        Performs a write to the status register
 18 //SPI_Write_Enable            Write enables the serial flash
 19 //SPI_Write_Disable            Write disables the serial flash
 20 //SPI_Read_ID1                Reads the device ID using the instruction 0xAB
 21 //SPI_Read_ID2                Reads the manufacturer ID and device ID with 0x90
 22 //SPI_Read_ID3()            Reads the JedecDevice ID
 23 //SPI_Read_Byte                Reads one byte from the serial flash and returns byte(max of 20 MHz CLK frequency)
 24 //SPI_Read_nBytes            Reads multiple bytes(max of 20 MHz CLK frequency)
 25 //SPI_FastRead_Byte            Reads one byte from the serial flash and returns byte(max of 33 MHz CLK frequency)
 26 //SPI_FastRead_nBytes        Reads multiple bytes(max of 33 MHz CLK frequency)
 27 //SPI_Write_Byte            Program one byte to the serial flash
 28 //SPI_Write_nBytes            Program n bytes to the serial flash, n<=256
 29 //SPI_Erase_Chip            Erases entire serial flash
 30 //SPI_Erase_Sector            Erases one sector (64 KB) of the serial flash
 31 //SPI_Wait_Busy                Polls status register until busy bit is low
 32 //=================================================================================================
 33 uchar    SPI_Read_StatusReg()            //读状态寄存器  备注:Xcc
 34 {    uchar byte = 0;
 35     W25X_CS = 0;                            //    enable device
 36     SPI_Send_Byte(W25X_ReadStatusReg);        //    send Read Status Register command
 37     byte = SPI_Get_Byte();                    //    receive byte
 38     W25X_CS = 1;                            //    disable device    
 39     return byte;
 40 }
 41 void    SPI_Write_StatusReg(byte)         //写状态寄存器
 42 {    W25X_CS = 0;                            //    enable device
 43     SPI_Send_Byte(W25X_WriteStatusReg);        //    select write to status register
 44     SPI_Send_Byte(byte);                    //    data that will change the status(only bits 2,3,7 can be written)
 45     W25X_CS = 1;                            //    disable the device
 46 }
 47 void    SPI_Write_Enable()                   //写使能
 48 {    W25X_CS = 0;                            //    enable device
 49     SPI_Send_Byte(W25X_WriteEnable);        //    send W25X_Write_Enable command
 50     W25X_CS = 1;                            //    disable device
 51 }
 52 void    SPI_Write_Disable()                   //写禁能
 53 {    W25X_CS = 0;                            //    enable device
 54     SPI_Send_Byte(W25X_WriteDisable);        //    send W25X_WriteW25X_DIsable command
 55     W25X_CS = 1;                            //    disable device
 56 }
 57 uchar    SPI_Read_ID1()                        //释放掉电/器件ID
 58 {    uchar byte;
 59     W25X_CS = 0;                            //    enable device
 60     SPI_Send_Byte(W25X_DeviceID);            //    send read device ID command (ABh)
 61     SPI_Send_Byte(0);                        //    send address
 62     SPI_Send_Byte(0);                        //    send address
 63     SPI_Send_Byte(0);                        //    send 3_Dummy address
 64     byte = SPI_Get_Byte();                    //    receive Device ID byte    
 65     W25X_CS  = 1;                            //    disable device
 66     delay(4);                                //    remain CS high for tRES2 = 1.8uS
 67     return byte;
 68 }
 69 uint    SPI_Read_ID2(uchar ID_Addr)             //制造/器件ID
 70 {    uint IData16;
 71     W25X_CS = 0;                            //    enable device
 72     SPI_Send_Byte(W25X_ManufactDeviceID);    //    send read ID command (90h)
 73     SPI_Send_Byte(0x00);                    //    send address
 74     SPI_Send_Byte(0x00);                    //    send address
 75     SPI_Send_Byte(ID_Addr);                    //    send W25Pxx selectable ID address 00H or 01H
 76     IData16 = SPI_Get_Byte()<<8;            //    receive Manufature or Device ID byte
 77     IData16 |= SPI_Get_Byte();                //    receive Device or Manufacture ID byte
 78     W25X_CS = 1;                            //    disable device    
 79     return IData16;
 80 }
 81 uint    SPI_Read_ID3()                           //读JEDEC ID
 82 {    uint IData16;
 83     W25X_CS = 0;                            //    enable device
 84     SPI_Send_Byte(W25X_JedecDeviceID);        //    send read ID command (9Fh)
 85     IData16 = SPI_Get_Byte()<<8;            //    receive Manufature or Device ID byte
 86     IData16 |= SPI_Get_Byte();                //    receive Device or Manufacture ID byte
 87     tx_buff[2] = SPI_Get_Byte();    
 88     W25X_CS = 1;                            //    disable device    
 89     return IData16;
 90 }
 91 uchar    SPI_Read_Byte(uint32 Dst_Addr)                //读某地址 数据
 92 {    uchar byte = 0;    
 93     W25X_CS = 0;                                        //    enable device
 94     SPI_Send_Byte(W25X_ReadData);                        //    read command
 95     SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));//    send 3 address bytes
 96     SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFF) >> 8));
 97     SPI_Send_Byte((uchar)(Dst_Addr & 0xFF));
 98     byte = SPI_Get_Byte();
 99     W25X_CS = 1;                                        //    disable device    
100     return byte;                                        //    return one byte read
101 }
102 void    SPI_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128)    //读某地址起nBytes_128字节以内内容
103 {    uint32 i = 0;    
104     W25X_CS = 0;                                        //    enable device
105     SPI_Send_Byte(W25X_ReadData);                        //    read command
106     SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));        //    send 3 address bytes
107     SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
108     SPI_Send_Byte(Dst_Addr & 0xFF);
109     for (i = 0; i < nBytes_128; i++)                    //    read until no_bytes is reached
110         upper_128[i] = SPI_Get_Byte();                    //    receive byte and store at address 80H - FFH
111     W25X_CS = 1;                                        //    disable device
112 }
113 uchar    SPI_FastRead_Byte(uint32 Dst_Addr)                  //快读 某地址 数据
114 {    uchar byte = 0;
115     W25X_CS = 0;                                        //    enable device
116     SPI_Send_Byte(W25X_FastReadData);                    //    fast read command
117     SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));        //    send 3 address bytes
118     SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
119     SPI_Send_Byte(Dst_Addr & 0xFF);
120     SPI_Send_Byte(0xFF);                                //    dummy byte
121     byte = SPI_Get_Byte();
122     W25X_CS = 1;                                        //    disable device    
123     return byte;                                        //    return one byte read
124 }
125 void    SPI_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128)      //快读 某地址 nBytes_128 个字节数据
126 {    uchar i = 0;    
127     W25X_CS = 0;                                        //    enable device
128     SPI_Send_Byte(W25X_FastReadData);                    //    read command
129     SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));        //    send 3 address bytes
130     SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
131     SPI_Send_Byte(Dst_Addr & 0xFF);
132     SPI_Send_Byte(0xFF);                                //    dummy byte
133     for (i = 0; i < nBytes_128; i++)                    //    read until no_bytes is reached
134         upper_128[i] = SPI_Get_Byte();                    //    receive byte and store at address 80H - FFH
135     W25X_CS = 1;                                        //    disable device
136 }
137 void    SPI_Write_Byte(uint32 Dst_Addr, uchar byte)          //页编程
138 {    W25X_CS = 0;                                    //    enable device
139     SPI_Write_Enable();                                //    set WEL
140     SPI_Wait_Busy();    
141     W25X_CS = 0;    
142     SPI_Send_Byte(W25X_PageProgram);                //    send Byte Program command
143     SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));    //    send 3 address bytes
144     SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
145     SPI_Send_Byte(Dst_Addr & 0xFF);
146     SPI_Send_Byte(byte);                            //    send byte to be programmed
147     W25X_CS = 1;                                    //    disable device
148 }
149 void    SPI_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128)         //页编程 128个字节
150 {    
151     uchar i, byte;    
152     W25X_CS = 0;                    /* enable device */
153     SPI_Write_Enable();                /* set WEL */
154     W25X_CS = 0;
155     SPI_Send_Byte(W25X_PageProgram);         /* send Byte Program command */
156     SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));    /* send 3 address bytes */
157     SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
158     SPI_Send_Byte(Dst_Addr & 0xFF);
159     
160     for (i = 0; i < nBytes_128; i++)
161     {
162         byte = upper_128[i];
163         SPI_Send_Byte(byte);        /* send byte to be programmed */
164     }    
165     W25X_CS = 1;                /* disable device */
166 }
167 void    SPI_Erase_Chip()                     //擦除芯片
168 {
169     W25X_CS = 0;                                        //    enable device
170     SPI_Write_Enable();                                    //    set WEL
171     W25X_CS = 0;
172     SPI_Wait_Busy();
173     W25X_CS = 0;
174     SPI_Send_Byte(W25X_ChipErase);                        //    send Chip Erase command
175     W25X_CS = 1;                                        //    disable device
176 }
177 void    SPI_Erase_Sector(uint32 Dst_Addr)                //扇区擦除
178 {    W25X_CS = 0;                                        //    enable device
179     SPI_Write_Enable();                                    //    set WEL
180     W25X_CS = 0;
181     SPI_Send_Byte(W25X_SectorErase);                    //    send Sector Erase command
182     SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));//    send 3 address bytes
183     SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFF) >> 8));
184     SPI_Send_Byte((uchar)Dst_Addr & 0xFF);
185     W25X_CS = 1;                                        //    disable device
186 }
187 void    SPI_Wait_Busy()                                 //等待忙结束
188 {    while (SPI_Read_StatusReg() == 0x03)
189         SPI_Read_StatusReg();                //    waste time until not busy WEL & Busy bit all be 1 (0x03)
190 }
191 void    SPI_PowerDown()
192 {    W25X_CS = 0;                            //    enable device
193     SPI_Send_Byte(W25X_PowerDown);            //    send W25X_PowerDown command 0xB9
194     W25X_CS = 1;                            //    disable device
195     delay(6);                                //    remain CS high for tPD = 3uS
196 }
197 void    SPI_ReleasePowerDown()
198 {    W25X_CS = 0;                            //    enable device
199     SPI_Send_Byte(W25X_ReleasePowerDown);    //    send W25X_PowerDown command 0xAB
200     W25X_CS = 1;                            //    disable device
201     delay(6);                                //    remain CS high for tRES1 = 3uS
202 }
203 
204 
205 
206 #ifdef    SST_SPI
207 void    SPI_init()
208 {    P1 = 0xFF;
209     SPCR = 0x50;
210 }
211 void    SPI_Send_Byte(uchar out)
212 {    unsigned char temp;
213     SPDR = out;
214     do    {    temp = SPSR & 0x80;    }    while (temp != 0x80);
215     SPSR = SPSR & 0x7F;
216 }
217 uchar    SPI_Get_Byte()
218 {    unsigned char temp;
219     SPDR = 0x00;
220     do    {    temp = SPSR & 0x80;    }    while (temp != 0x80);
221     SPSR = SPSR & 0x7F;
222     return SPDR;
223 }
224 #endif
225 
226 #ifndef    SST_SPI
227 void    SPI_init()
228 {    W25X_CLK = 0;                            //    set clock to low initial state for SPI operation mode 0
229 //    W25X_CLK = 1;                            //    set clock to High initial state for SPI operation mode 3
230 //    _hold = 1;
231     W25X_WP = 1;
232     W25X_CS = 1;    
233     SPI_Write_Disable();    
234 }
235 void    SPI_Send_Byte(uchar out)
236 {    uchar i = 0;    
237     for (i = 0; i < 8; i++)
238     {    if ((out & 0x80) == 0x80)            //    check if MSB is high
239             W25X_DI = 1;
240         else
241             W25X_DI = 0;                    //    if not, set to low
242         W25X_CLK = 1;                        //    toggle clock high
243         out = (out << 1);                    //    shift 1 place for next bit
244         nop();nop();nop();nop();
245         W25X_CLK = 0;                        //    toggle clock low
246     }
247 }
248 uchar    SPI_Get_Byte()
249 {    uchar i = 0, in = 0, temp = 0;    
250     for (i = 0; i < 8; i++)
251     {    in = (in << 1);                        //    shift 1 place to the left or shift in 0
252         temp = W25X_DO;                        //    save input
253         W25X_CLK = 1;                        //    toggle clock high
254         if (temp == 1)                        //    check to see if bit is high
255             in |= 0x01;                        //    if high, make bit high
256         W25X_CLK = 0;                        //    toggle clock low
257     }    
258     return in;
259 }
260 #endif

MAIN.C

MAIN.C
#include <REG52.H>
#include <intrins.h>
#include <W25X.H>
    



#define    uint8    unsigned char
#define    uint16    unsigned int
#define    uchar    unsigned char
#define    uint    unsigned int
#define    uint32    unsigned long


void    init_cpu(void);
void    delay(uchar tt);
void    trace(uchar *str,uchar len);
void    test_page(uchar addr);
void    read_page(uchar addr);
void    Verify(uchar byte, uchar cor_byte);

uint8    Rxtemp;
bit        MYTI;
uint8    tx_buff[16];
uint8    upper_128[16];
bit        rx_ok;

void main(void)
{    uint i;
    W25X_HOLD= 1;
    init_cpu();    
    SPI_init();

    tx_buff[0]='O';
    tx_buff[1]='K';
    trace(tx_buff,2);

    for(;;)
    {    if(rx_ok == 1)
        {    rx_ok = 0;
            switch(Rxtemp)
            {    case 0x01:
                    Rxtemp = 0;
                    tx_buff[0] = SPI_Read_ID1();
                    trace(tx_buff,1);
                    break;
                case 0x02:
                    i = SPI_Read_ID2(0x00);
                    tx_buff[1] = (uchar)i;
                    tx_buff[0] = (uchar)(i>>8);
                    trace(tx_buff,2);
                    break;
                case 0x03:
                    i = SPI_Read_ID3();
                    tx_buff[1] = (uchar)i;
                    tx_buff[0] = (uchar)(i>>8);
                    trace(tx_buff,3);
                    break;
                case 0x04:
                    tx_buff[0] = SPI_Read_Byte(0x00000000);
                    trace(tx_buff,1);
                    break;
                case 0x05:
                    tx_buff[0] = 0x55;
                    SPI_Write_Byte(0x00000000,0xa5);          
                    trace(tx_buff,1);
                    break;
                case 0x06:
                    tx_buff[0] = SPI_Read_StatusReg();
                    trace(tx_buff,1);
                    break;
                case 0x07:
                    SPI_Write_Enable();    
                    break;
                case 0x08:
                    upper_128[0]=0x01;upper_128[1]=0x02;upper_128[2]=0x03;upper_128[3]=0x04;
                    SPI_Write_nBytes(0x00000000,4);
                    break;
                case 0x09:
                    SPI_Erase_Chip();
                    break;
                case 0x0a:
                    SPI_Erase_Sector(0x000ff000);
                    while(1)
                    {    tx_buff[0] = SPI_Read_StatusReg();
                        if(tx_buff[0] == 0)
                        {    trace(tx_buff,1);
                            break;
                        }
                    }
                    break;
                case 0x0b:
                    test_page(0x00);
                    break;
                case 0x0c:
                    read_page(0x00);
                    break;
                default:
                    break;
            }            
        }            
    }
}

void init_cpu(void)
{    TMOD = 0x21;            
    PCON = PCON | 0x80;        //波特率加倍
    SCON  = 0x50;            //异步、10位、波特率可变,无校验位
    TH1   = 0xf4;            //在11.0592M晶振下,波特率是9600,
    TL1   = 0xf4;            
    TR1   = 1;              //T1 timer run
    ES    = 1;                //uart interrupt enable    
    EA = 1;                    //all interrupt enable
}

//串口中断程序
void UART_isr(void) interrupt 4
{ 
    if(RI)
    {
        RI = 0;
        Rxtemp = SBUF;   //接收
        //SBUF = Rxtemp;      //发送
        rx_ok = 1;
        return;
    }
    if(TI)
    {
        TI = 0;
        MYTI = 1;        
     }
}
void test_page(uchar addr)
{    uint i; uchar byte;
    uint32 Dst_Addr;    
    W25X_CS = 0;                                            //    enable device
    SPI_Write_Enable();                                        //    set WEL
    W25X_CS = 0;
    Dst_Addr = (uint32)addr*256;
    Dst_Addr = 0x0ff000;//(uint32)addr*256;
    SPI_Send_Byte(W25X_PageProgram);                        //    send Byte Program command
    SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));    //    send 3 address bytes
    SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFF) >> 8));
    SPI_Send_Byte((uchar)(Dst_Addr & 0xFF));
    
    for (i = 0; i < 256; i++)                                //    send byte to be programmed
        SPI_Send_Byte(i);
    W25X_CS = 1;    
    
    delay_nms(5);
    
    W25X_CS = 0;
    while(1)
    {    tx_buff[0] = SPI_Read_StatusReg();
        trace(tx_buff,1);
        if(tx_buff[0] == 0)    break;
    }
    Dst_Addr = 0x0ff000;
    for (i = 0; i < 256; i++)
    {    byte = SPI_Read_Byte(Dst_Addr+i);
        ES = 0;
        SBUF = byte;
        while (TI == 0);
        TI = 0;
        ES = 1;
    }
    W25X_CS = 1;
}
//=================================================================================================
void read_page(uchar addr)
{    uint i;
    uchar byte;
    uint32 Dst_Addr;
    Dst_Addr = addr*256;
    Dst_Addr = 0x0ff000;
    W25X_CS = 0;
    for (i = 0; i < 256; i++)
    {    byte = SPI_Read_Byte(Dst_Addr+i);
        ES = 0;
        SBUF = byte;
        while (TI == 0);
        TI = 0;
        ES = 1;
    }
    W25X_CS = 1;
}
//=================================================================================================
void Verify(uchar byte, uchar cor_byte)
{    if (byte != cor_byte)
    {    while(1);
            //LED_Error = 0; /* display to view error on LED. */            
    }
}
//=================================================================================================
void myputchar(uchar c)
{    
    ES = 0;
    SBUF = c;
    while (TI == 0);
    TI = 0;
    ES = 1;
}
//=================================================================================================
void trace(uchar *str,uchar len)
{    uint i;
    for(i=0;i<len;i++)    {    myputchar(*str);    str++;    }
}

 以上测试正确

原文地址:https://www.cnblogs.com/scdyxcc/p/2870470.html