STM32下AT45DB161D驱动代码---模拟SPI(模式0)

AT45DB161D.c文件内容

 

#include "AT45DB161D.h"

/*
作者:    毕小乐
日期:2018-09-21
版本:V1.00
简介:
            1.实现AT45DB161D主内存的连续读、写、整片擦除操作,可以像使用EEPROM一样使用AT45DB161D FLASH存储器。
            2.使用模拟SPI模式(模式0),方便移植到其他平台。
            3.移植简单,只需要修改H文件的管脚对应关系即可,无需修改C文件。
*/

void AT45DB161D_Init_Pin(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(AT45DB161D_CS_CLK | AT45DB161D_CLK_CLK
    | AT45DB161D_MOSI_CLK | AT45DB161D_MISO_CLK, ENABLE);

    /* CS CLK MOSI in output pushpull mode */
    GPIO_InitStructure.GPIO_Pin = AT45DB161D_CS_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(AT45DB161D_CS_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = AT45DB161D_CLK_PIN;
    GPIO_Init(AT45DB161D_CLK_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = AT45DB161D_MOSI_PIN;
    GPIO_Init(AT45DB161D_MOSI_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = AT45DB161D_MISO_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(AT45DB161D_MISO_PORT, &GPIO_InitStructure);
    
    AT45DB161D_CS_HIGH;
}

static void AT45DB161D_Delay_uS(int tick)
{
    int i;
    while(tick>0)
    {
        tick--;
        for(i=0;i<10;i++)
        __nop();
    }
}

char AT45DB161D_SendByte(char Dat)
{
    int i;
    char receive=0;
    
    AT45DB161D_CS_LOW;
    
    for(i=0;i<8;i++)
    {
        AT45DB161D_CLK_LOW;
        AT45DB161D_Delay_uS(5);
        if((Dat<<i)&0x80)
        {
            AT45DB161D_MOSI_HIGH;
        }
        else
        {
            AT45DB161D_MOSI_LOW;
        }
        AT45DB161D_Delay_uS(1);
        AT45DB161D_CLK_HIGH;
        AT45DB161D_Delay_uS(1);
        
        if(AT45DB161D_MISO)
        {
            receive |= 0x01<<(7-i);
        }            
        else
        {
            receive |= 0x00<<(7-i);
        }
        AT45DB161D_Delay_uS(4);
    }
    
    AT45DB161D_CLK_LOW;
    AT45DB161D_Delay_uS(10);
    
//    AT45DB161D_CS_HIGH;
    
    return receive;
}

//0BH(操作码)+3Byte (地址)+1Byte(dummy)+n个SCK时钟+ CS电平跳变(从低到高)
void AT45DB161D_Read(unsigned int Add,char* buf,unsigned int Len)
{
    char Add_Buf[3],i;
    int Page_Add,Buffer_Add,Add_Value;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0x0B);
    
    Page_Add = (Add / 528) << 10;
    Buffer_Add = Add % 528;
    Add_Value = Page_Add | Buffer_Add;        
    
    Add_Buf[0] = (char)((Add_Value & 0x3FFFFF)>>16);
    Add_Buf[1] = (char)((Add_Value & 0x3FFFFF)>>8);
    Add_Buf[2] = (char)((Add_Value & 0x3FFFFF)>>0);
    
    for(i=0;i<3;i++)
    {
        AT45DB161D_SendByte(Add_Buf[i]);
    }
    
    AT45DB161D_SendByte(0x00);
    
    while(Len--)
    {
        *buf++ = AT45DB161D_SendByte(0x00);
    }
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    return;
}
//D4H或D1H(操作码 缓冲区1)+3Byte (地址)+1Byte(don’t care)+n个SCK时钟+ CS电平跳变(从低到高)
void Read_Buffer(unsigned int Add,char* buf,unsigned int Len)
{
    char Add_Buf[3],i;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0xD1);
    
    Add_Buf[0] = (char)((Add & 0x03FF)>>16);
    Add_Buf[1] = (char)((Add & 0x03FF)>>8);
    Add_Buf[2] = (char)((Add & 0x03FF)>>0);
    
    for(i=0;i<3;i++)
    {
        AT45DB161D_SendByte(Add_Buf[i]);
    }
    
    AT45DB161D_SendByte(0x00);
    
    while(Len--)
    {
        *buf++ = AT45DB161D_SendByte(0x00);
    }
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    return;
}
//84H(操作码 缓冲区1)+3Byte(地址)+要发送的数据
void Write_Buffer(unsigned int Add,char* buf,unsigned int Len)
{
    char Add_Buf[3],i;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0x84);
    
    Add_Buf[0] = (char)((Add & 0x03FF)>>16);
    Add_Buf[1] = (char)((Add & 0x03FF)>>8);
    Add_Buf[2] = (char)((Add & 0x03FF)>>0);
    
    for(i=0;i<3;i++)
    {
        AT45DB161D_SendByte(Add_Buf[i]);
    }
        
    while(Len--)
    {
        AT45DB161D_SendByte(*buf++);
    }
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    return;
}
//D7H(操作码)+1Byte(状态字节)
char Read_Status_Register(void)
{
    char Status;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0xD7);

    Status = AT45DB161D_SendByte(0x00);
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);

    return Status;
}

void Page_To_Buffer(unsigned int Add)
{
    char Add_Buf[3],i;
    char Status;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0x53);
    
    Add = (Add/528)<<10;
    
    Add_Buf[0] = (char)((Add & 0x3FFC00)>>16);
    Add_Buf[1] = (char)((Add & 0x3FFC00)>>8);
    Add_Buf[2] = (char)((Add & 0x3FFC00)>>0);
    
    for(i=0;i<3;i++)
    {
        AT45DB161D_SendByte(Add_Buf[i]);
    }    
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    
    Status = (Read_Status_Register() & 0x80)>>7;
    while(Status == 0x00)
    {
        Status = (Read_Status_Register() & 0x80)>>7;
    }
    return;
}
/*
    Add:写缓冲区开始地址
    buf:待写入数据的指针
    Len:待写入数据的长度,不能大小当前地址能够写入的最大字节数

    通过缓冲区写主内存(相当于写缓冲区命令+缓冲区到主内存页编程使用内建擦除命令)
    82H(操作码 缓冲区1)+3Byte(地址)+N Byte(数据)+CS电平跳变(从低到高)
*/
void Buffer_To_Page(unsigned int Add,char* buf,unsigned int Len)
{
    char Add_Buf[3],i;
    char Status;
    int Page_Add,Buffer_Add,Add_Value;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0x82);
    
    Page_Add = (Add / 528) << 10;
    Buffer_Add = Add % 528;
    Add_Value = Page_Add |     Buffer_Add;
    
    Add_Buf[0] = (char)((Add_Value & 0x3FFFFF)>>16);
    Add_Buf[1] = (char)((Add_Value & 0x3FFFFF)>>8);
    Add_Buf[2] = (char)((Add_Value & 0x3FFFFF)>>0);
    
    for(i=0;i<3;i++)
    {
        AT45DB161D_SendByte(Add_Buf[i]);
    }
        
    while(Len--)
    {
         AT45DB161D_SendByte(*buf++);
    }
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    
    Status = (Read_Status_Register() & 0x80)>>7;
    while(Status == 0x00)
    {
        Status = (Read_Status_Register() & 0x80)>>7;
    }
    return;
}

/*
        1.将当前地址所对应内存页内容读取到缓冲区中。
        2.使用缓冲区到内存写命令,修改缓冲区内容,将缓冲区写到内存页中。
*/
void AT45DB161D_Write(unsigned int Add,char* buf,unsigned int Len)
{
    int Available_Byte,Write_Num;
    
    while(Len)
    {
        Page_To_Buffer(Add);        //将内存页中的数据拷贝到缓冲区中

        Available_Byte = 528-Add%528;
        if(Available_Byte >= Len)
        {
            Write_Num = Len;
        }
        else
        {
            Write_Num = Available_Byte;
        }
        Buffer_To_Page(Add,buf,Write_Num);
        buf += Write_Num;
        Len -= Write_Num;
        Add += Write_Num;
    }
    
    return;
}
//C7H(操作码)+94H(操作码)+80H(操作码)+9AH(操作码)+CS电平跳变(从低到高)
void AT45DB161D_Chip_Erase(void)
{
    char Status;
    
    AT45DB161D_CS_LOW;
    AT45DB161D_SendByte(0xC7);
    AT45DB161D_SendByte(0x94);
    AT45DB161D_SendByte(0x80);
    AT45DB161D_SendByte(0x9A);
    
    AT45DB161D_CS_HIGH;
    AT45DB161D_Delay_uS(10);
    
    Status = (Read_Status_Register() & 0x80)>>7;
    while(Status == 0x00)
    {
        Status = (Read_Status_Register() & 0x80)>>7;
    }
    return;
}

 

AT45DB161D.h文件内容

 

 1 #ifndef AT45DB161D_H
 2 #define AT45DB161D_H
 3 
 4 #include "stm32f10x.h"
 5 
 6 /*
 7 CLK        PB13
 8 CS        PC7
 9 MOSI    PB15
10 MISO    PB14
11 */
12 
13 #define AT45DB161D_CS_PORT        GPIOC
14 #define AT45DB161D_CLK_PORT        GPIOD
15 #define AT45DB161D_MOSI_PORT    GPIOD
16 #define    AT45DB161D_MISO_PORT    GPIOD
17 
18 #define AT45DB161D_CS_PIN            GPIO_Pin_12
19 #define AT45DB161D_CLK_PIN        GPIO_Pin_3
20 #define AT45DB161D_MOSI_PIN        GPIO_Pin_4
21 #define    AT45DB161D_MISO_PIN        GPIO_Pin_2
22 
23 #define AT45DB161D_CS_CLK            RCC_APB2Periph_GPIOC
24 #define AT45DB161D_CLK_CLK        RCC_APB2Periph_GPIOD
25 #define AT45DB161D_MOSI_CLK        RCC_APB2Periph_GPIOD
26 #define    AT45DB161D_MISO_CLK        RCC_APB2Periph_GPIOD
27 
28 #define    AT45DB161D_CS_LOW            GPIO_ResetBits(AT45DB161D_CS_PORT,AT45DB161D_CS_PIN)
29 #define    AT45DB161D_CS_HIGH        GPIO_SetBits(AT45DB161D_CS_PORT,AT45DB161D_CS_PIN)
30 #define    AT45DB161D_CLK_LOW        GPIO_ResetBits(AT45DB161D_CLK_PORT,AT45DB161D_CLK_PIN)
31 #define    AT45DB161D_CLK_HIGH        GPIO_SetBits(AT45DB161D_CLK_PORT,AT45DB161D_CLK_PIN)
32 #define    AT45DB161D_MOSI_LOW        GPIO_ResetBits(AT45DB161D_MOSI_PORT,AT45DB161D_MOSI_PIN)
33 #define    AT45DB161D_MOSI_HIGH    GPIO_SetBits(AT45DB161D_MOSI_PORT,AT45DB161D_MOSI_PIN)
34 
35 #define AT45DB161D_MISO                GPIO_ReadInputDataBit(AT45DB161D_MISO_PORT,AT45DB161D_MISO_PIN)
36 
37 extern void AT45DB161D_Init_Pin(void);
38 extern void AT45DB161D_Read(unsigned int Add,char* buf,unsigned int Len);
39 extern void AT45DB161D_Write(unsigned int Add,char* buf,unsigned int Len);
40 extern void AT45DB161D_Chip_Erase(void);
41 
42 #endif

 

转载于:https://www.cnblogs.com/csjl2010/p/9685407.html

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值