搜索
bottom↓
回复: 8

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

[复制链接]

出0入0汤圆

发表于 2007-8-13 22:58:28 | 显示全部楼层 |阅读模式
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[Buffer_Address])

                {

                        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;

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2007-8-13 23:00:33 | 显示全部楼层
请高手帮忙看看,这些源代码问题出在哪里,我调试了好几天没有调好。谢谢

出0入0汤圆

发表于 2007-8-14 17:45:26 | 显示全部楼层
你先一点一点来吧。



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

出0入0汤圆

 楼主| 发表于 2007-8-14 18:51:52 | 显示全部楼层
不对哦

出0入0汤圆

 楼主| 发表于 2007-8-15 22:56:53 | 显示全部楼层
读状态是对的,其它都不对。

出0入0汤圆

发表于 2008-2-19 15:55:05 | 显示全部楼层
参考一下http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=919414&bbs_page_no=1&bbs_id=1000

出0入0汤圆

发表于 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[2];         
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);

void  BufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low);

void  BufferWrite(uint8_t bufferNum, uint16_t offset);
               
void  BufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase);            

void  PageToBuffer(uint16_t page, uint8_t bufferNum);

void  PageErase(uint16_t page);
               
void  BlockErase(uint16_t block);

void  SectoreErase(uint8_t sector);

void  ChipErase(void);

void  BeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum);
               
void  EndAndWait(void);

int8_t  ComparePageToBuffer(uint16_t page, uint8_t bufferNum);

void  DeepPowerDown(void);

void  ResumeFromDeepPowerDown(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_t  ReadStatusRegister(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;
}

void  ReadManufacturerAndDeviceID(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[0] = spi_transfer(0xff);
        /* Device ID (part 2) */
        id->device[1] = spi_transfer(0xff);
        /* Extended Device Information String Length */
        id->extendedInfoLength = spi_transfer(0xff);
        
}

void  ReadMainMemoryPage(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);
}

void  ContinuousArrayRead(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));
}


void  BufferRead(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));
}

void  BufferWrite(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));
}

void  BufferToPage(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))
        {}
}

void  PageToBuffer(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))
        {}
}

void  PageErase(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))
        {}
}

void  BlockErase(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))
        {}
}

void  SectoreErase(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))
        {}
}

void  ChipErase(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))
        {}
}

void  BeginPageWriteThroughBuffer(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);
}

void  EndAndWait(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_t  ComparePageToBuffer(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);
}

void  DeepPowerDown(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);
}

void  ResumeFromDeepPowerDown(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

void  ATD45DB161D_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[0]=");
//sendchar1(char2hex(id1->device[0]));
sendinthex1(id1->device[0]);
sendstring1("\n");
/* Device ID (part 2) */
sendstring1("id1->device[1]=");
//sendchar1(char2hex(id1->device[1]));
sendinthex1(id1->device[1]);
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");


}

这个是串口的输出
1

1

出0入0汤圆

发表于 2008-2-21 14:16:54 | 显示全部楼层
MEGA128与AT45DB161D的硬件连接
1
2
1

出0入0汤圆

发表于 2011-9-8 09:32:23 | 显示全部楼层
持续关注中
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 02:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表