chennx0814 发表于 2007-8-13 22:58:28

求助:ATmega8对AT45DB161D访问的源代码的问题。

void Init_SPI(void)

{

        DDRB|=(1<<DDB2)|(1<<DDB3)|(1<<DDB5);

        PORTB &=~(1<<DDB5);

        PORTB |= (1<<PORTB2);///SS=1

        SPCR=(1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL);        //Enable SPI in Master mode, mode 3, Fosc/2;//使能SPI,SPI选择为主机

        SPSR=1;//SPI倍速,频率为外部时钟的一半(7.3728M/2)

}



void Write_SPI(unsigned char data)

{

        SPSR &= ~(1<<SPIF);

        SPDR = data;

        while (!(SPSR & 0x80));

}





//格式化主存储器(以扇区<0A,0B,1……15>为单位删除所有页数据)

//Flash_Num--选择决定选择哪一片FLASH

void DF_format(unsigned char Flash_Num)

{

        unsigned char i;

        DF_SPI_ON;

       

        DF_wait_busy(Flash_Num);

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(SECTOR_ERASE);//7ch

        Write_SPI(0x00);

        Write_SPI(0x00);

        Write_SPI(0x00);



        DF_wait_busy(Flash_Num);



        Write_SPI(SECTOR_ERASE);

        Write_SPI(0x00);

        Write_SPI(0x20);

        Write_SPI(0x00);



        for (i=1;i<16;i++)

        {

                DF_wait_busy(Flash_Num);

                Write_SPI(SECTOR_ERASE);

                Write_SPI(i << 2);

                Write_SPI(0x00);

                Write_SPI(0x00);

        }

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

        DF_SPI_OFF;

}





//擦除指定的主存储器页(地址范围0-4095)

//Flash_Num--选择决定选择哪一片FLASH

void DF_page_earse(unsigned int page,unsigned char Flash_Num)

{

        DF_SPI_ON;

        DF_wait_busy(Flash_Num);

       

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(PAGE_ERASE);//81h

        Write_SPI((unsigned char)(page >> 6));

        Write_SPI((unsigned char)(page << 2));

        Write_SPI(0x00);

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

        DF_SPI_OFF;

}





//将保存在数组DF_buffer[]中的一页数据写入第二缓冲区后送入主存储区

//(先擦除后写入模式,页地址范围0-4095)

//Flash_Num--选择决定选择哪一片FLASH

void DF_write_page(unsigned int page,unsigned char Flash_Num)

{

        unsigned int i;

        DF_SPI_ON;

       

        DF_wait_busy(Flash_Num);

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(BUFFER_2_WRITE); //87h

        Write_SPI(0x00);

        Write_SPI(0x00);

        Write_SPI(0x00);

        for (i=0;i<Buffer_Length;i++)

        {

                Write_SPI(DF_buffer);

        }

        //DF_DESELECT_1;

       

        if (page<4096)

        {

                //DF_SELECT_1;

                DF_wait_busy(Flash_Num);

                Write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);//86h

                Write_SPI((unsigned char)(page>>6));

                Write_SPI((unsigned char)(page<<2));

                Write_SPI(0x00);

                //DF_DESELECT_1;

        }

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

        DF_SPI_OFF;

}





//将指定主存储器页的数据转入第一缓冲区后读出,保存在DF_buffer[]数组中

//(页地址范围0-4095)

//Flash_Num--选择决定选择哪一片FLASH

void DF_read_page(unsigned int page,unsigned char Flash_Num)

{

        unsigned int i;

        DF_SPI_ON;

       

        //while(!(DF_STA_PORT & (1<< DF_STATE)));

        DF_wait_busy(Flash_Num);

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(MM_PAGE_TO_B1_XFER);//53h

        Write_SPI((unsigned char)(page >> 6));

    Write_SPI((unsigned char)(page << 2));

    Write_SPI(0x00);

        //DF_DESELECT_1;

       

        DF_wait_busy(Flash_Num);

        //DF_SELECT_1;

        Write_SPI(BUFFER_1_READ); //d4h

        Write_SPI(0x00);                        

        Write_SPI(0x00);   

        Write_SPI(0x00);      

        Write_SPI(0x00);

        for (i=0;i<Buffer_Length;i++)

        {

                Write_SPI(0xFF);

                DF_buffer = SPDR;

        }

        //DF_DESELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

       

       

        DF_SPI_OFF;

}





//以直接读取方式读取指定的主存储器页数据(页地址范围0-4095)

//Flash_Num--选择决定选择哪一片FLASH

void DF_MM_read_page(unsigned int page,unsigned char Flash_Num)

{

        unsigned int i;

        DF_SPI_ON;

       

        //while(!(DF_STA_PORT & (1<< DF_STATE)));

        DF_wait_busy(Flash_Num);

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(MAIN_MEMORY_PAGE_READ);//d2h

        Write_SPI((unsigned char)(page >> 6));

    Write_SPI((unsigned char)(page << 2));

    Write_SPI(0x00);

        Write_SPI(0x00);

        Write_SPI(0x00);

        Write_SPI(0x00);

        Write_SPI(0x00);

        for (i=0;i<Buffer_Length;i++)

        {

                Write_SPI(0xff);

                DF_buffer = SPDR;

        }

        //DF_DESELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

       

        DF_SPI_OFF;

}





//读取状态寄存器

//        bit7                bit6        bit6        bit6        bit6        bit6        bit6                bit6

//RDY/BUSY                COMP        1                0                1                1                PROTECT                PAGE SIZE

//Flash_Num--选择决定选择哪一片FLASH       

unsigned char DF_read_reg(unsigned char Flash_Num)

{

        unsigned char temp;

        DF_SPI_ON;

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(READ_STATE_REGISTER);//d7h

        Write_SPI(0xff);

        temp=SPDR;

        //DF_DESELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

        DF_SPI_OFF;

        return temp;

}





//检查状态寄存器最高位是否为忙,并等待空闲

//Flash_Num--选择决定选择哪一片FLASH

void DF_wait_busy(unsigned char Flash_Num)

{

        unsigned char state_reg=0x00;

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        Write_SPI(READ_STATE_REGISTER);//d7h



        Write_SPI(0xff);

        state_reg = SPDR ;

        while((state_reg&0x80) == 0)

        {

                Write_SPI(0xff);

                state_reg = SPDR ;

        }

        //DF_DESELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

}





//将指定主存储器页的数据转入指定缓冲区

//Flash_Num--选择决定选择哪一片FLASH

void DF_mm_to_buf(unsigned char buffer,unsigned int page,unsigned char Flash_Num)

{

        DF_SPI_ON;

        DF_wait_busy(Flash_Num);

        //DF_SELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        if (buffer==1)

                Write_SPI(MM_PAGE_TO_B1_XFER);//53h

        else

                Write_SPI(MM_PAGE_TO_B2_XFER);//55h

        Write_SPI((unsigned char)(page >> 6));

    Write_SPI((unsigned char)(page << 2));

    Write_SPI(0x00);

        //DF_DESELECT_1;

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }

        DF_SPI_OFF;

}





//读取指定缓冲区指定单元的数据,保存在DF_buffer[]数组中

//Flash_Num--选择决定选择哪一片FLASH

unsigned char DF_read_buf(unsigned char buffer,unsigned int start_address,

                                                                unsigned int length,unsigned char Flash_Num)

{

        unsigned int i;

        if (((Buffer_Length-1)-start_address)>=length)

        {

                DF_SPI_ON;

                DF_wait_busy(Flash_Num);

                //DF_SELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_DESELECT_1;break;

                        case 2:DF_DESELECT_2;break;

                        case 3:DF_DESELECT_3;break;

                        case 4:DF_DESELECT_4;break;

                        default:break;

                }

                if (buffer==1)

                        Write_SPI(BUFFER_1_READ); //d4h

                else

                        Write_SPI(BUFFER_2_READ);

                Write_SPI(0x00);                        

                Write_SPI((unsigned char)(start_address >> 8));   

                Write_SPI((unsigned char)start_address);      

                Write_SPI(0x00);

                for (i=0;i<length;i++)

                {

                        Write_SPI(0xFF);

                        DF_buffer = SPDR;

                }

                //DF_DESELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_DESELECT_1;break;

                        case 2:DF_DESELECT_2;break;

                        case 3:DF_DESELECT_3;break;

                        case 4:DF_DESELECT_4;break;

                        default:break;

                }

                DF_SPI_OFF;

                return 1;

        }

        else

                return 0;

}





//将DF_buffer[]数组中指定长度的数据写入指定缓冲区

//Flash_Num--选择决定选择哪一片FLASH

unsigned char DF_write_buf(unsigned char buffer,unsigned int start_address,

                                                        unsigned int length,unsigned char Flash_Num)

{

        unsigned int i;

        if(((Buffer_Length-1)-start_address)>=length)

        {

                DF_SPI_ON;

                DF_wait_busy(Flash_Num);

                //DF_SELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_SELECT_1;break;

                        case 2:DF_SELECT_2;break;

                        case 3:DF_SELECT_3;break;

                        case 4:DF_SELECT_4;break;

                        default:break;

                }

                if (buffer==1)

                        Write_SPI(BUFFER_1_WRITE);

                else

                        Write_SPI(BUFFER_2_WRITE);

                Write_SPI(0x00);

                Write_SPI((unsigned char)(start_address >> 8));   

                Write_SPI((unsigned char)start_address);

                for (i=0;i<length;i++)

                {

                        Write_SPI(DF_buffer);

                }

                //DF_DESELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_DESELECT_1;break;

                        case 2:DF_DESELECT_2;break;

                        case 3:DF_DESELECT_3;break;

                        case 4:DF_DESELECT_4;break;

                        default:break;

                }

                DF_SPI_OFF;

                return 1;

        }

        else

        {

                DF_SPI_OFF;

                return 0;

        }

}





//将指定缓冲区中的数据写入主存储区的指定页(擦除模式)

//Flash_Num--选择决定选择哪一片FLASH

void DF_buf_to_mm(unsigned char buffer,unsigned int page,unsigned char Flash_Num)

{

        DF_SPI_ON;

        DF_wait_busy(Flash_Num);

        if (page<4096)

        {

                //DF_SELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_SELECT_1;break;

                        case 2:DF_SELECT_2;break;

                        case 3:DF_SELECT_3;break;

                        case 4:DF_SELECT_4;break;

                        default:break;

                }

                if (buffer==1)

                        Write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);

                else

                        Write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);

                Write_SPI((unsigned char)(page>>6));

                Write_SPI((unsigned char)(page<<2));

                Write_SPI(0x00);

                //DF_DESELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_DESELECT_1;break;

                        case 2:DF_DESELECT_2;break;

                        case 3:DF_DESELECT_3;break;

                        case 4:DF_DESELECT_4;break;

                        default:break;

                }

        }

        DF_SPI_OFF;

}

//将指定缓冲区中的数据写入主存储区的指定页(没有擦除)

//Flash_Num--选择决定选择哪一片FLASH

void DF_buf_to_mm_Without_Erase(unsigned char buffer,unsigned int page,unsigned char Flash_Num)

{

        DF_SPI_ON;

        DF_wait_busy(Flash_Num);

        if (page<4096)

        {

                //DF_SELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_SELECT_1;break;

                        case 2:DF_SELECT_2;break;

                        case 3:DF_SELECT_3;break;

                        case 4:DF_SELECT_4;break;

                        default:break;

                }

                if (buffer==1)

                        Write_SPI(B1_TO_MM_PAGE_PROG);

                else

                        Write_SPI(B2_TO_MM_PAGE_PROG);

                Write_SPI((unsigned char)(page>>6));

                Write_SPI((unsigned char)(page<<2));

                Write_SPI(0x00);

                //DF_DESELECT_1;

                switch(Flash_Num)

                {

                        case 1:DF_DESELECT_1;break;

                        case 2:DF_DESELECT_2;break;

                        case 3:DF_DESELECT_3;break;

                        case 4:DF_DESELECT_4;break;

                        default:break;

                }

        }

        DF_SPI_OFF;

}



//比较缓冲器1和DF_buffer数组的大小,

//如果相等,返回1,否则返回0;

//Flash_Num--选择决定选择哪一片FLASH

unsigned char Compare_Tow_Buffer(unsigned char Flash_Num)

{

        unsigned char Mid_Reg_CMP = 0;

        unsigned int Buffer_Address = 0;

        DF_SPI_ON;

        switch(Flash_Num)

        {

                case 1:DF_SELECT_1;break;

                case 2:DF_SELECT_2;break;

                case 3:DF_SELECT_3;break;

                case 4:DF_SELECT_4;break;

                default:break;

        }

        for(Buffer_Address=0; Buffer_Address<528; Buffer_Address++)

        {

                DF_wait_busy(Flash_Num);

                Write_SPI(BUFFER_1_READ);        // 0xD4                                        // 读取第一缓冲区

                Write_SPI(0x00);

                Write_SPI((unsigned char)(Buffer_Address>>8));

                Write_SPI((unsigned char) (Buffer_Address<<2));       

                Write_SPI(0x00);



                Write_SPI(0xff);

                Mid_Reg_CMP = SPDR;       



                if(Mid_Reg_CMP != DF_buffer)

                {

                        return 0;

                }       

        }               

        switch(Flash_Num)

        {

                case 1:DF_DESELECT_1;break;

                case 2:DF_DESELECT_2;break;

                case 3:DF_DESELECT_3;break;

                case 4:DF_DESELECT_4;break;

                default:break;

        }



        DF_SPI_OFF;

        return 1;

}

chennx0814 发表于 2007-8-13 23:00:33

请高手帮忙看看,这些源代码问题出在哪里,我调试了好几天没有调好。谢谢

machao 发表于 2007-8-14 17:45:26

你先一点一点来吧。



先写一个字节到AT45DB161中,再读出来看看是否写对了。

chennx0814 发表于 2007-8-14 18:51:52

不对哦

chennx0814 发表于 2007-8-15 22:56:53

读状态是对的,其它都不对。

mirrorok 发表于 2008-2-19 15:55:05

参考一下http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=919414&bbs_page_no=1&bbs_id=1000

mirrorok 发表于 2008-2-21 14:16:29

4.1测试at45DB161D


#ifndef AT45DB161D_H
#define AT45DB161D_H
#include<global.h>
#include<iom128v.h>
#include<macros.h>
#include "at45db161d_commands.h"

#ifndef SPI

#define DATAOUT   11

#define DATAIN      12

#define SPICLOCK    13

#define SLAVESELECT 10

#define RESET      8

#define WP         7

/*
#define DF_CS_inactive digitalWrite(SLAVESELECT,HIGH)

#define DF_CS_active   digitalWrite(SLAVESELECT,LOW)
*/
/*
#define DF_CS_inactive    PORTB|=_BV(DDB0)

#define DF_CS_active      PORTB&=~_BV(DDB0)
*/
#define DF_CS_inactive    PORTB|=1
#define DF_CS_active      PORTB&=0xfe

#endif /* SPI */

#define READY_BUSY 0x80

#define COMPARE 0x40

#define PROTECT 0x02

#define PAGE_SIZE 0x01

#define DEVICE_DENSITY 0x2C

struct ATD45DB161D_ID
{
uint8_t manufacturer;      
uint8_t device;         
uint8_t extendedInfoLength;
};

void ATD45DB161D_Init(void);

uint8_t ReadStatusRegister(void);

void ReadManufacturerAndDeviceID(struct ATD45DB161D_ID *id);
               
void ReadMainMemoryPage(uint16_t page, uint16_t offset);

void ContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low);

voidBufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low);

voidBufferWrite(uint8_t bufferNum, uint16_t offset);
               
voidBufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase);            

voidPageToBuffer(uint16_t page, uint8_t bufferNum);

voidPageErase(uint16_t page);
               
voidBlockErase(uint16_t block);

voidSectoreErase(uint8_t sector);

voidChipErase(void);

voidBeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum);
               
voidEndAndWait(void);

int8_tComparePageToBuffer(uint16_t page, uint8_t bufferNum);

voidDeepPowerDown(void);

voidResumeFromDeepPowerDown(void);


#endif /* AT45DB161D_H */


#ifndef AT45DB161D_COMMANDS_H
#define AT45DB161D_COMMANDS_H

#define AT45DB161D_PAGE_READ 0xD2

#define AT45DB161D_CONTINUOUS_READ_LOW_FREQ 0x03

#define AT45DB161D_CONTINUOUS_READ_HIGH_FREQ 0x0B

#define AT45DB161D_BUFFER_1_READ_LOW_FREQ 0xD1

#define AT45DB161D_BUFFER_2_READ_LOW_FREQ 0xD3

#define AT45DB161D_BUFFER_1_READ 0xD4

#define AT45DB161D_BUFFER_2_READ 0xD6

#define AT45DB161D_BUFFER_1_WRITE 0x84

#define AT45DB161D_BUFFER_2_WRITE 0x87

#define AT45DB161D_BUFFER_1_TO_PAGE_WITH_ERASE 0x83

#define AT45DB161D_BUFFER_2_TO_PAGE_WITH_ERASE 0x86

#define AT45DB161D_BUFFER_1_TO_PAGE_WITHOUT_ERASE 0x88

#define AT45DB161D_BUFFER_2_TO_PAGE_WITHOUT_ERASE 0x89

#define AT45DB161D_PAGE_ERASE 0x81

#define AT45DB161D_BLOCK_ERASE 0x50

#define AT45DB161D_SECTOR_ERASE 0x7C

#define AT45DB161D_CHIP_ERASE_0 0xC7
#define AT45DB161D_CHIP_ERASE_1 0x94
#define AT45DB161D_CHIP_ERASE_2 0x80
#define AT45DB161D_CHIP_ERASE_3 0x9A

#define AT45DB161D_PAGE_THROUGH_BUFFER_1 0x82

#define AT45DB161D_PAGE_THROUGH_BUFFER_2 0x85

#ifdef AT45DB161D_EXPERT_MODE
/* Use the following commands at your own risk ! */
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_0 0x3D
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_1 0x2A
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_2 0x7F
#define AT45DB161D_ENABLE_SECTOR_PROTECTION_3 0xA9

#define AT45DB161D_DISABLE_SECTOR_PROTECTION_0 0x3D
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_1 0x2A
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_2 0x7F
#define AT45DB161D_DISABLE_SECTOR_PROTECTION_3 0x9A

#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x3D
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x2A
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0x7F
#define AT45DB161D_ERASE_SECTOR_PROTECTION_REGISTER_0 0xCF

#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_0 0x3D
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_1 0x2A
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_2 0x7F
#define AT45DB161D_PROGRAM_SECTOR_PROTECTION_REGISTER_3 0xFC

#define AT45DB161D_SECTOR_LOCKDOWN_0 0X3D
#define AT45DB161D_SECTOR_LOCKDOWN_1 0x2A
#define AT45DB161D_SECTOR_LOCKDOWN_2 0x7F
#define AT45DB161D_SECTOR_LOCKDOWN_3 0x30

#define AT45DB161D_PROGRAM_SECURITY_REGISTER_0 0x9B
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_1 0x00
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_2 0x00
#define AT45DB161D_PROGRAM_SECURITY_REGISTER_3 0x00
#endif /* AT45DB161D_EXPERT_MODE */

#define AT45DB161D_READ_SECTOR_PROTECTION_REGISTER 0x32

#define AT45DB161D_READ_SECTOR_LOCKDOWN_REGISTER 35H

#define AT45DB161D_READ_SECURITY_REGISTER 0x77

#define AT45DB161D_TRANSFER_PAGE_TO_BUFFER_1 0x53

#define AT45DB161D_TRANSFER_PAGE_TO_BUFFER_2 0x55

#define AT45DB161D_COMPARE_PAGE_TO_BUFFER_1 0x60

#define AT45DB161D_COMPARE_PAGE_TO_BUFFER_2 0x61

#define AT45DB161D_AUTO_PAGE_REWRITE_THROUGH_BUFFER_1 0x58

#define AT45DB161D_AUTO_PAGE_REWRITE_THROUGH_BUFFER_2 0x59

#define AT45DB161D_DEEP_POWER_DOWN 0xB9

#define AT45DB161D_RESUME_FROM_DEEP_POWER_DOWN 0xAB

#define AT45DB161D_STATUS_REGISTER_READ 0xD7

#define AT45DB161D_READ_MANUFACTURER_AND_DEVICE_ID 0x9F

#define AT45DB161D_BUFFER_1_READ_LEGACY 0X54

#define AT45DB161D_BUFFER_2_READ_LEGACY 0x56

#define AT45DB161D_PAGE_READ_LEGACY 0x52

#define AT45DB161D_CONTINUOUS_READ_LEGACY 0x68

#define AT45DB161D_STATUS_REGISTER_READ_LEGACY 0x57

#endif /* AT45DB161D_COMMANDS_H */

at45db161d.c原程序

#include "at45db161d.h"
#include<iom128v.h>
#include<macros.h>
#include<delay.h>

//#define DF_CS_inactive    PORTB|=1
//#define DF_CS_active      PORTB&=0xfe

uint8_t spi_transfer(uint8_t data)
{
      SPDR = data;
      while(!(SPSR & (1 << SPIF))) ;
      return SPDR;
}
void ATD45DB161D_Init(void)
{
      uint8_t clr;
      
      /* Initialize pinout */
      /*pinMode(DATAOUT, OUTPUT);
      pinMode(DATAIN, INPUT);
      pinMode(SPICLOCK, OUTPUT);
      pinMode(SLAVESELECT, OUTPUT);
      pinMode(DATAIN, INPUT);
                */
      //DDRB|=(1<<DDB2)|(1<<DDB1)|(1<<DDB0);
                //设置SS,SCK,MOSI为输出,MIOS为输入
                DDRB&=0XF7;
                DDRB|=0X07;
                  
      /* Disable device */
      DF_CS_inactive;

      /* Setup SPI 主机模式空闲时为高,采样结束沿采样 1/4主频率*/
      SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA);

      /* Cleanup registers */
      clr = SPSR;
      clr = SPDR;
}

uint8_tReadStatusRegister(void)
{
      uint8_t status;

      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

    /* Send status read command */
      spi_transfer(AT45DB161D_STATUS_REGISTER_READ);
      /* Get result with a dummy write */
      status = spi_transfer(0x00);

      return status;
}

voidReadManufacturerAndDeviceID(struct ATD45DB161D_ID *id)
{
      
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

    /* Send status read command */
      spi_transfer(AT45DB161D_READ_MANUFACTURER_AND_DEVICE_ID);

      /* Manufacturer ID */
      id->manufacturer = spi_transfer(0xff);
      /* Device ID (part 1) */
      id->device = spi_transfer(0xff);
      /* Device ID (part 2) */
      id->device = spi_transfer(0xff);
      /* Extended Device Information String Length */
      id->extendedInfoLength = spi_transfer(0xff);
      
}

voidReadMainMemoryPage(uint16_t page, uint16_t offset)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer(AT45DB161D_PAGE_READ);
      
      /* Address (page | offset)*/
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
      spi_transfer((uint8_t)(offset & 0xff));
      
      /* 4 "don't care" bytes */
      spi_transfer(0x00);
      spi_transfer(0x00);
      spi_transfer(0x00);
      spi_transfer(0x00);
}

voidContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer( low ? AT45DB161D_CONTINUOUS_READ_LOW_FREQ :
                            AT45DB161D_CONTINUOUS_READ_HIGH_FREQ );

      /* Address (page | offset)*/
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
      spi_transfer((uint8_t)(offset & 0xff));
}


voidBufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      if(bufferNum == 1)
      {
                spi_transfer(low ? AT45DB161D_BUFFER_1_READ_LOW_FREQ :
                                 AT45DB161D_BUFFER_1_READ);
      }
      else
      {
                spi_transfer(low ? AT45DB161D_BUFFER_2_READ_LOW_FREQ :
                                 AT45DB161D_BUFFER_2_READ);

      }
      
      /* 14 "Don't care" bits */
      spi_transfer(0x00);
      /* Rest of the "don't care" bits + bits 8,9 of the offset */
      spi_transfer((uint8_t)(offset >> 8));
      /* bits 7-0 of the offset */
      spi_transfer((uint8_t)(offset & 0xff));
}

voidBufferWrite(uint8_t bufferNum, uint16_t offset)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_WRITE :
                                       AT45DB161D_BUFFER_2_WRITE);
      
      /* 14 "Don't care" bits */
      spi_transfer(0x00);
      /* Rest of the "don't care" bits + bits 8,9 of the offset */
      spi_transfer((uint8_t)(offset >> 8));
      /* bits 7-0 of the offset */
      spi_transfer((uint8_t)(offset & 0xff));
}

voidBufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Opcode */
      if(erase)
      {
                spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITH_ERASE :
                                             AT45DB161D_BUFFER_2_TO_PAGE_WITH_ERASE);
      }
      else
      {
                spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITHOUT_ERASE :
                                             AT45DB161D_BUFFER_2_TO_PAGE_WITHOUT_ERASE);
      }
      
      /*
         * 3 address bytes consist of :
         *   - 2 don’t care bits
         *   - 12 page address bits (PA11 - PA0) that specify the page in
         *       the main memory to be written
         *   - 10 don’t care bits
         */
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)(page << 2));
      spi_transfer(0x00);
      
      DF_CS_inactive;/* Start transfer */
      DF_CS_active;    /* If erase was set, the page will first be erased */

      /* Wait for the end of the transfer */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidPageToBuffer(uint16_t page, uint8_t bufferNum)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer((bufferNum == 1) ? AT45DB161D_TRANSFER_PAGE_TO_BUFFER_1 :
                                        AT45DB161D_TRANSFER_PAGE_TO_BUFFER_2);

      /*
         * 3 address bytes consist of :
         *   - 2 don’t care bits
         *   - 12 page address bits (PA11 - PA0) that specify the page in
         *       the main memory to be written
         *   - 10 don’t care bits
         */
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)(page << 2));
      spi_transfer(0x00);
               
      DF_CS_inactive;/* Start page transfer */
      DF_CS_active;

      /* Wait for the end of the transfer */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidPageErase(uint16_t page)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer(AT45DB161D_PAGE_ERASE);
      
      /*
         * 3 address bytes consist of :
         *   - 2 don’t care bits
         *   - 12 page address bits (PA11 - PA0) that specify the page in
         *       the main memory to be written
         *   - 10 don’t care bits
         */
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)(page << 2));
      spi_transfer(0x00);
               
      DF_CS_inactive;/* Start block erase */
      DF_CS_active;

      /* Wait for the end of the block erase operation */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidBlockErase(uint16_t block)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer(AT45DB161D_BLOCK_ERASE);
      
      /*
         * 3 address bytes consist of :
         *   - 2 don’t care bits
         *   - 9 block address bits (PA11 - PA3)
         *   - 13 don’t care bits
         */
      spi_transfer((uint8_t)(block >> 3));
      spi_transfer((uint8_t)(block << 5));
      spi_transfer(0x00);
               
      DF_CS_inactive;/* Start block erase */
      DF_CS_active;

      /* Wait for the end of the block erase operation */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidSectoreErase(uint8_t sector)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer(AT45DB161D_SECTOR_ERASE);
      
      /*
         * 3 address bytes consist of :
         */
      if((sector == 0x0a) || (sector == 0x0b))
      {
                /*
               *- 11 don’t care bits
               *-
               *- 12 don’t care bits
               */
                spi_transfer(0x00);
                spi_transfer(((sector & 0x01) << 4));
                spi_transfer(0x00);
      }
      else
      {
                /*
               *- 2 don't care bits
               *- 4 sector number bits
               *- 18 don't care bits
               */
                spi_transfer(sector << 1);
                spi_transfer(0x00);
                spi_transfer(0x00);
      }
                              
      DF_CS_inactive;/* Start block erase */
      DF_CS_active;

      /* Wait for the end of the block erase operation */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidChipErase(void)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send chip erase sequence */
      spi_transfer(AT45DB161D_CHIP_ERASE_0);
      spi_transfer(AT45DB161D_CHIP_ERASE_1);
      spi_transfer(AT45DB161D_CHIP_ERASE_2);
      spi_transfer(AT45DB161D_CHIP_ERASE_3);
                              
      DF_CS_inactive;/* Start chip erase */
      DF_CS_active;

      /* Wait for the end of the chip erase operation */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

voidBeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer((bufferNum == 1) ? AT45DB161D_PAGE_THROUGH_BUFFER_1 :
                                        AT45DB161D_PAGE_THROUGH_BUFFER_2);

      /* Address */
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
      spi_transfer((uint8_t)offset);
}

voidEndAndWait(void)
{
      DF_CS_inactive;/* End current operation */
      DF_CS_active;    /* Some internal operation may occur
                        * (buffer to page transfer, page erase, etc... ) */

      /* Wait for the chip to be ready */
      while(!(ReadStatusRegister() & READY_BUSY))
      {}
}

int8_tComparePageToBuffer(uint16_t page, uint8_t bufferNum)
{
      uint8_t status;
      
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */

      /* Send opcode */
      spi_transfer((bufferNum == 1) ? AT45DB161D_COMPARE_PAGE_TO_BUFFER_1 :
                                        AT45DB161D_COMPARE_PAGE_TO_BUFFER_2);
      
      /* Page address */
      spi_transfer((uint8_t)(page >> 6));
      spi_transfer((uint8_t)(page << 2));
      spi_transfer(0x00);
      
      DF_CS_inactive;/* Start comparaison */
      DF_CS_active;

      /* Wait for the end of the comparaison and get the result */
      while(!((status = ReadStatusRegister()) & READY_BUSY))
      {}
               
      return ((status & COMPARE) == COMPARE);
}

voidDeepPowerDown(void)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */
      
      /* Send opcode */
      spi_transfer(AT45DB161D_DEEP_POWER_DOWN);
      
      /* Enter Deep Power-Down mode */
      DF_CS_inactive;
      
      /* Safety delay */
         delay_ms(100);
}

voidResumeFromDeepPowerDown(void)
{
      DF_CS_inactive;    /* Make sure to toggle CS signal in order */
      DF_CS_active;      /* to reset Dataflash command decoder   */
      
      /* Send opcode */
      spi_transfer(AT45DB161D_RESUME_FROM_DEEP_POWER_DOWN);
      
      /* Resume device */
      DF_CS_inactive;
      
      /* The CS pin must stay high during t_RDPD microseconds before the device
         * can receive any commands.
         * On the at45db161D t_RDPD = 35 microseconds. But we will wait 100
         * (just to be sure). */
         delay_ms(100);
}

测试程序1

voidATD45DB161D_test(void)
{
struct ATD45DB161D_ID *id1;
sendstring1("now test ATD45DB161D dataflash !\n");
sendstring1("1.ReadStatusRegister\n");
// sendchar1(char2hex(ReadStatusRegister()));
sendinthex1(ReadStatusRegister());
sendstring1("\n");
sendstring1("2. ReadManufacturerAndDeviceID\n");
ReadManufacturerAndDeviceID(id1);
/* Manufacturer ID */
sendstring1("id1->manufacturer=");
// sendchar1(char2hex(id1->manufacturer));
sendinthex1(id1->manufacturer);
sendstring1("\n");
/* Device ID (part 1) */
sendstring1("id1->device=");
//sendchar1(char2hex(id1->device));
sendinthex1(id1->device);
sendstring1("\n");
/* Device ID (part 2) */
sendstring1("id1->device=");
//sendchar1(char2hex(id1->device));
sendinthex1(id1->device);
sendstring1("\n");
/* Extended Device Information String Length */
sendstring1("id1->extendedInfoLength=");
//sendchar1(char2hex(id1->extendedInfoLength));
sendinthex1(id1->extendedInfoLength);
sendstring1("\n");

sendstring1("3.ChipErase test\n");
sendstring1("now ChipErase begin\n");
ChipErase();
sendstring1("now ChipErase end\n");


}

这个是串口的输出
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217295.jpg

1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217296.jpg

mirrorok 发表于 2008-2-21 14:16:54

MEGA128与AT45DB161D的硬件连接
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217315.jpg
2http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217316.jpg
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_217317.jpg

ecgjiang 发表于 2011-9-8 09:32:23

持续关注中
页: [1]
查看完整版本: 求助:ATmega8对AT45DB161D访问的源代码的问题。