• 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++;    }
    }

     以上测试正确

  • 相关阅读:
    PAT-乙级-1008 数组元素循环右移问题
    PAT-乙级-1007 素数对猜想
    PAT-乙级-1006 换个格式输出整数
    PAT-乙级-1005 继续(3n+1)猜想
    PAT-乙级-1003 我要通过!
    PAT-乙级-1004 成绩排名
    PAT-乙级-1002 写出这个数
    PAT-乙级-1001 害死人不偿命的(3n+1)猜想
    PAT-甲级-1002-A+B for Polynomials
    【windows】共享文件夹设置
  • 原文地址:https://www.cnblogs.com/scdyxcc/p/2870470.html
Copyright © 2020-2023  润新知