原创 at25f4096驱动程序

2009-8-9 04:09 2622 3 6 分类: 软件与OS

https://static.assets-stash.eet-china.com/album/old-resources/2009/7/29/7fa23c9f-aada-4a2d-be9f-2ea9cbb55951.rar       at25f4096驱动程序。通过proteus7.4仿真,可以学习spi接口的时序驱动及程序编写。我用的是avr的芯片,用io口模拟spi的时序。


点击看大图


 


///////////////////////////////////////////////////////////////////////////////////////


unsigned char SPI_HostReadByte(void) //下降沿
{
    uchar i,RecData = 0;
    for(i=0;i<8;i++)
    {            
        RecData <<= 1;
        if(PINB&0X08)RecData += 1;
                       
        SCK_high;              


        SCK_low; 
 
    } 
    return (RecData);  
}


///////////////////////////////////////////////////////////////////////////////////////


void SPI_HostWriteByte(unsigned char wByte) //上升沿
{
    unsigned char i;
    for(i = 0; i < 8; i++)
    {
    if((wByte << i) & 0x80)
    {
        MOSI_high;
    }
    else
    {
        MOSI_low;
    }
                   
    SCK_high; 

    SCK_low; 
                       


    }     
}


///////////////////////////////////////////////////////////////////////////////////////


在proteus7.4仿真如下:


点击看大图


 


以下是针对at25f4096的驱动程序:


 


#include "includes.h"


#define  CS         PB0
#define  SCK      PB1
#define  MOSI    PB2
#define  MISO    PB3


#define SCK_high   PORTB|=BIT(SCK);  DDRB|=BIT(SCK);
#define SCK_low    PORTB&=~BIT(SCK); DDRB|=BIT(SCK);


#define MOSI_high  PORTB|=BIT(MOSI);
#define MOSI_low   PORTB&=~BIT(MOSI);


#define MISO_high  PORTB|=BIT(MISO);
#define MISO_low   PORTB&=~BIT(MISO);


#define CS_high    PORTB|=BIT(CS);
#define CS_low     PORTB&=~BIT(CS); 


/* Instruction Codes */
#define WREN                       0x06
#define WRDI                        0x04
#define RDSR                        0x05
#define WRSR                       0x01
#define READ                        0x03
#define PROGRAM               0x02
#define SECTOR_ERASE     0x52
#define CHIP_ERASE           0x62
#define RDID                        0x15


unsigned char buffer[256];


/******************************************************************************
//void SPI_Init(void)
******************************************************************************/
void SPI_Init(void)
{
    DDRB|=0X07;
    DDRB&=0XF7;
    CS_high;
    SCK_low;
    MOSI_low;
    MISO_high;


}
/******************************************************************************
//unsigned char SPI_HostReadByte(void)
******************************************************************************/
unsigned char SPI_HostReadByte(void) //下降沿
{
/*      
    uchar i,RecData = 0;
    for(i=0;i<8;i++)
    {     
        SCK_low;
        SCK_low; 
                   
        RecData <<= 1;
        if(PINB&0X08)RecData += 1; 
        SCK_high; 
        SCK_high;                               
    } 
     
    return (RecData); 
*/  
 
    uchar i,RecData = 0;
    for(i=0;i<8;i++)
    {            
        RecData <<= 1;
        if(PINB&0X08)RecData += 1;
                       
        SCK_high; 
        SCK_high;                  


        SCK_low;
        SCK_low;       
    } 
    return (RecData);  
 
 
}
/******************************************************************************
//void SPI_HostWriteByte(unsigned char wByte)
******************************************************************************/
void SPI_HostWriteByte(unsigned char wByte) //上升沿
{
/*  unsigned char i;
    for(i = 0; i < 8; i++)
    { 
        SCK_low;
        SCK_low;
          
        if((wByte << i) & 0x80)
            {
            MOSI_high;
        }
        else
        {
            MOSI_low;
        }
                   
        SCK_high;
        SCK_high;                         
    }
 */     
  
    unsigned char i;
    for(i = 0; i < 8; i++)
    {
    if((wByte << i) & 0x80)
    {
        MOSI_high;
    }
    else
    {
        MOSI_low;
    }
                   
    SCK_high;
    SCK_high;
      
    SCK_low;
    SCK_low;                          


    }     
   
}
//=====================================================================================//
//unsigned char read_status_register(void)
//=====================================================================================//
unsigned char read_status_register(void)
{
 unsigned char status;
 CS_low;  
   SPI_HostWriteByte(RDSR);
   status = SPI_HostReadByte();
   CS_high;
 return status;  
}


//=====================================================================================//
//void SPI_WREN()
//写命令使能(很重要,如果忘记写,读状态一直是忙)
//=====================================================================================//
void SPI_WREN()
{
    while((read_status_register()&0x01)==1);//读取状态寄存器,判断是否为忙
           
    CS_low;     
    SPI_HostWriteByte(WREN);
    CS_high;
}
//=====================================================================================//
//unsigned int get_mem_id()
//正常时 i="0x1f"; j="0x64";否则程序出错
//=====================================================================================//
unsigned int get_mem_id()
{
    unsigned int i,j;
 
    while((read_status_register()&0x01)==1);//读取状态寄存器,判断是否为忙
    
    CS_low;                                      /* Enable AT25F512 Chip Select (L) */
    SPI_HostWriteByte(RDID);                     /* transmit the SECTOR_ERASE op_code */
    i="SPI"_HostReadByte();                        /* receive the manufacturing code */
    j= SPI_HostReadByte();                       /* receive the ID code */
    CS_high;                                     /* Disable AT25F512A Chip Select (H) */
    return i+j<<8;  
  


//=====================================================================================//
// void write_status_register(unsigned char status_register)
// Description: Write Status Register (WRSR) 
//=====================================================================================//
void write_status_register(unsigned char status_register)
{
 
    while((read_status_register()&0x01)==1); //读取状态寄存器最高位,判断是否为忙
    SPI_WREN();                              //you must write
    while((read_status_register()&0x01)==1); //读取状态寄存器最高位,判断是否为忙   


    CS_low;          
    SPI_HostWriteByte(WRSR);                                     /* transmit the WRSR op_code */
    SPI_HostWriteByte(status_register); //                       /* transmit the status register value */
    CS_high;
                     
}
//=====================================================================================//
//void program_at25f4096(uint32 address_write_to_4096, uchar *point_to_databuffer, int num_of_data_writeto4096)
//=====================================================================================//
void program_at25f4096(uint32 address_write_to_4096, uchar *point_to_databuffer, int num_of_data_writeto4096)
{


 uchar *pdata_to_be_write = point_to_databuffer; 
        unsigned int i = 0; 
          
        char  data_buffer[3];//last_address_of_4096赋值给data_buffer 高位在前
 data_buffer[0] = (uint8)(address_write_to_4096>>16);
 data_buffer[1] = (uint8)(address_write_to_4096>>8);
 data_buffer[2] = (uint8)address_write_to_4096;       


        while((read_status_register()&0x01)==1); //读取状态寄存器,判断是否为忙           
        SPI_WREN();
        while((read_status_register()&0x01)==1); //读取状态寄存器,判断是否为忙         



        CS_low;
        SPI_HostWriteByte(PROGRAM);          
        SPI_HostWriteByte(data_buffer[0]);
        SPI_HostWriteByte(data_buffer[1]);
        SPI_HostWriteByte(data_buffer[2]);
 for(i=0;i<num_of_data_writeto4096;i++)
 { 
            SPI_HostWriteByte(pdata_to_be_write);
 }
        CS_high;  
}
//=====================================================================================//
//unsigned char read_from_at25f4096(uint32 address_read_from_at25f4096, uint8 *point_to_databuffer, int num_of_data_readfrom4096)
//=====================================================================================//   
void  read_from_at25f4096(uint32 address_read_from_at25f4096, uint8 *point_to_databuffer, int num_of_data_readfrom4096)
{
 int i;
 uint8 *pdata_get_from_4096 = point_to_databuffer;
 char  data_buffer[3];//要读的储存器的首地址赋给data_buffer 高位在前
       
 data_buffer[0] = (uint8)(address_read_from_at25f4096>>16);
 data_buffer[1] = (uint8)(address_read_from_at25f4096>>8);
 data_buffer[2] = (uint8)address_read_from_at25f4096;
       
        while((read_status_register()&0x01)==1);           
        SPI_WREN();
        while((read_status_register()&0x01)==1); 
                  
        CS_low;
        {
        SPI_HostWriteByte(READ);
       
        SPI_HostWriteByte(data_buffer[0]);
        SPI_HostWriteByte(data_buffer[1]);
        SPI_HostWriteByte(data_buffer[2]);


        for(i=0;i<num_of_data_readfrom4096;i++)
        { 
            pdata_get_from_4096= SPI_HostReadByte();
        }
       
        }
        CS_high;
 
}
//=====================================================================================//
//void chip_erase(void)
//=====================================================================================//
void chip_erase(void)
{
        while((read_status_register()&0x01)==1);           
        SPI_WREN();
        while((read_status_register()&0x01)==1); 
        CS_low;          
        SPI_HostWriteByte(CHIP_ERASE);                                     /* transmit the WRSR op_code */ 
        CS_high;             
 
}


//========================================================================================
//void sector_erase(uint32 address)
//address 为要察的sector里面的任何一个字节的地址
//========================================================================================
void sector_erase(uint32 address)//address 为要察的sector里面的任何一个字节的地址
{
  
        uint8 transfer_buffer[4];
 uint32 address_of_erase = address;


        while((read_status_register()&0x01)==1);//读取状态寄存器,判断是否为忙            
        SPI_WREN();
        while((read_status_register()&0x01)==1);//读取状态寄存器,判断是否为忙  
        
 transfer_buffer[2] = (uint8)address_of_erase;
 transfer_buffer[1] = (uint8)(address_of_erase>>8);
 transfer_buffer[0] = (uint8)(address_of_erase>>16);
       
        CS_low;
        {
        SPI_HostWriteByte(CHIP_ERASE);
        SPI_HostWriteByte(transfer_buffer[0]);
        SPI_HostWriteByte(transfer_buffer[1]);
        SPI_HostWriteByte(transfer_buffer[2]);
        }
        CS_high;


}


//========================================================================================
//  level        area                  array addesses locked out
//
//   0            8                               NONE
//   1            7                          070000-07FFFF
//   2            6                          060000-07FFFF
//   3            4                          040000-07FFFF
//   4            0                          000000-07FFFF
//                      参考芯片pdf第八页 Table4
//========================================================================================
void set_write_protected_area(unsigned char area)//Set Write Protected Area
{
        while((read_status_register()&0x01)==1);//读取状态寄存器,判断是否为忙  
        switch(area)
        {
       
        case 8:
            write_status_register(0b00000010);//全部保护
        break;       
       
        case 7:
            write_status_register(0b00000110);//保护000000-06FFFF地址上数据              
        break;


        case 6:
            write_status_register(0b00001010);//保护000000-05FFFF地址上数据          
        break;
       
        case 4:
            write_status_register(0b00001110);//保护000000-03FFFF地址上数据                  
        break;


        case 0:
            write_status_register(0b00010010);//不保护地址上数据                 
        break;        
       
        default :
            write_status_register(0b00000010);//全部保护              
        break;


        }      


}


//========================================================================================
//void demo()
//测试函数
//========================================================================================
void demo()//读写测试
{
    uint ii;
    long count="0";
    for(ii=0;ii<256;ii++)
    buffer[ii]=ii;
     
    SPI_Init(); 
    sector_erase(0);            //擦除sector 0 
    chip_erase();               //整个芯片擦除 
    set_write_protected_area(0);//Set Write Protected Area
    get_mem_id();
  
//    for(count=0;count<1;count++)//写芯片
    for(count=0;count<(256*8);count++)//写芯片     
    { 
        long addr;
        addr="256"*count;
        program_at25f4096(addr,buffer,256);    
    }
    set_write_protected_area(8);//Set Write Protected Area



//    for(count=0;count<1;count++)//写芯片
    for(count=0;count<(256*8);count++)//写芯片
    {
        for(ii=0;ii<256;ii++)
            buffer[ii]=ii;    
        read_from_at25f4096(256*count,buffer,256);
    }
        
    while(1);


}
//========================================================================================


//========================================================================================
void main()
{
    demo();


}

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户377235 2014-12-25 11:06

谢谢楼主

用户1592348 2011-4-14 21:39

谢谢楼主,下来看看。

用户1586933 2011-4-9 17:55

学习....
相关推荐阅读
用户78924 2012-07-03 14:26
1
未保存截图_24                      ...
用户78924 2011-03-25 18:53
为人处世
我总是太顾及别人感受不知道如何拒绝别人 悬赏分:20 | 解决时间:2009-6-26 18:06 | 提问者:匿名 我总是太顾及别人感受,觉得拒绝别人会很不好意思,特别是不熟的人。 比如我同租的...
用户78924 2011-03-25 12:06
逻辑思维 摘要
不是你逻辑思维不行,而是你的思维方式不一样。碰到一个问题,你的思维方式可能和熟练程序员的思维方式不一样。还有就是你的基础知识不够好,不要以为编程只要会C++,JAVA就可以了,这只是很小而且很不重要的...
用户78924 2011-03-19 10:21
关于严密思维
                                                    程序员应当有这样的严密思维 某日,老师在课堂上想看看一学生智商有没有问题,问他 >   &...
用户78924 2011-02-23 11:42
没有找到MFC80UD.DLL
vs2005/8 没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题 在vs2005 sp1中文版中,在“解决方案资源管理器”中的项目上右击,选择“属性”,找...
用户78924 2010-11-06 19:36
(转)不再害怕指针
前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优...
EE直播间
更多
我要评论
3
3
关闭 站长推荐上一条 /3 下一条