weizhonghui 发表于 2007-7-9 23:15:49

利用ATmega128通用IO软件模拟SPI读取AT45DB041B的状态寄存器,总是0xFF,为什么?

程序如下:

#include <mega128.h>



#define UCHAR unsigned char

#define UINT unsigned int



#define DF_Write                PORTD   //SPI port register

#define DF_Read                PIND    //Data PIN

#define DF_Direction_REG        DDRD    //Direction register



#define DF_CS_Write                PORTA        //SPI CS port register

#define DF_CS_Direction_REG        DDRA    //CS Direction register



#define SPI_DI_PIN                3        //DF_SI_PIN,MCU_SO_PIN

#define SPI_DO_PIN                2        //DF_SO_PIN,MCU_SI_PIN

#define SPI_CLK_PIN                 5        //DF_CLK_PIN,MCU_CLK_PIN

#define SPI_CS_PIN               3        //DF_CS_PIN



#define SPI_SI            DF_Write.SPI_DI_PIN

#define SPI_SO            DF_Read.SPI_DO_PIN

#define SPI_SCK             DF_Write.SPI_CLK_PIN

#define SPI_CS            DF_CS_Write.SPI_CS_PIN



void SPI_Port_Init(void)

{

   //Config ports

   DF_Direction_REG.SPI_DI_PIN=1;          //Set Pin DF_DI as Input, MCU pin as Output

   DF_Direction_REG.SPI_CLK_PIN=1;         //Set Pin DF_Clock as Input, MCU pin as Output

   DF_Direction_REG.SPI_DO_PIN=0;          //Set Pin DF_DO as Output, MCU pin as Input

   DF_CS_Direction_REG.SPI_CS_PIN=1;       //Set Pin DF_CS as Input,MCU pin as Output

   

   SPI_CS=1;                        //Set DF_Chip_Select to High, DATAFLASH Invalid.

}



unsigned char SPI_MCUReadByte(void)

{

      unsigned char i,rByte=0;



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

        {

                SPI_SCK=0;

                SPI_SCK=1;



                rByte<<=1;

                rByte|=SPI_SO;

        }

        return rByte;

}



void SPI_MCUWriteByte(unsigned char wByte)

{

        unsigned char i;



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

        {

                if((wByte<<i)&0x80){SPI_SI=1;}

                else{SPI_SI=0;}



                SPI_SCK=0;

                SPI_SCK=1;

        }

}



unsigned char AT45DB041B_StatusRegisterRead(void)

{

        unsigned char i;



        SPI_CS=0;

        SPI_MCUWriteByte(0x57);

        i=SPI_MCUReadByte();

        SPI_CS=1;



        return i;

}



void main(void)

{

        unsigned char status=0;



        SPI_Port_Init();

        status=AT45DB041B_StatusRegisterRead();



        while(1){}

}



大家帮忙看一下,为什么啊?

AuToCTRL 发表于 2007-7-10 08:42:11

以前用硬件SPI时碰到过,好像是SPI模式3才能工作。建议看看SPI模式和时序!

weizhonghui 发表于 2007-7-10 09:24:24

状态寄存器读出来应该是什么值?

是不是对于at45db41b来说,5位到2位固定的为0111 其他位就看情况了?

我按楼上的把操作码改成改为d7H结果读出来还是0xff
-----此内容被weizhonghui于2007-07-10,09:30:57编辑过

Tim_yao 发表于 2008-6-23 10:41:46

此问题有待高人指点,我现在也遇到同样的问题,头都大了。

ahui2 发表于 2008-7-28 00:36:09

我可以读出状态码,但读产家ID的时候总是0XFF,不知道是怎么回事,请指点一下

//AT45DB041D-SPI-16.c

#include <iom16v.h>
#include <macros.h>
#include <string.h>
#include "AT45DB041D-SPI-16.h"

/************************************************************
*AT45DB041D全局变量
************************************************************/
unsigned char Write_Buffer;
unsigned char Read_Buffer;
unsigned int Read_Buffer_Addr =0;
unsigned int Write_Buffer_Addr=0;
unsigned int Read_Buffer_Size =0;
unsigned int Write_Buffer_Size=0;
unsigned int Read_Page_Addr   =0;
unsigned int Write_Page_Addr=0;
/************************************************************
*SPI宏定义
************************************************************/
#defineSPI_DDR           DDRB
#defineSPI_PORT          PORTB
#defineSPI_PIN          PINB
#defineSS            4
#defineSCK             7
#defineMOSI            5
#defineMISO            6
#defineRESET         3
/************************************************************
*AT45DB041D宏定义
*RST由硬件实现(接WatchDog的复位脚)
************************************************************/
#defineEnable_DFLASH()   SPI_PORT&=~(1<<SS)   //使能DataFlash
#defineDisable_DFLASH()SPI_PORT|=(1<<SS)          //禁止DataFlash

/************************************************************
*Init SPI Port
************************************************************/
void SPI_Port_Init(void)
{
SPI_DDR|= ((1<<SS)|(1<<SCK)|(1<<MOSI));
//SPI_DDR&=~ (1<<MISO);
SPI_PORT |= ((1<<SS)|(1<<SCK))|(1<<MOSI);
//SPI_PORT &=~ ((1<<SCK)|(1<<MOSI));
SPI_DDR|=(1<<RESET);
}
/************************************************************
*初始化SPI
************************************************************/
void SPI_Init(void)
{
SPI_Port_Init();

// SPI中断禁止, SPI使能, master模式, MSB 前,SPI 模式 3, SCK频率Fcl/4
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA);//mode 3
//SPSR |= (1<<SPI2X);
}
/************************************************************
*DataFlash Init
************************************************************/
void DataFlash_Init(void)
{
SPI_Init();
}
/************************************************************
*SPI send a Byte
************************************************************/
void SPI_Write_Byte(unsigned char cData)
{
SPDR = cData;                //write data
while(!(SPSR & (1<<SPIF)));//wait write ok
}
/************************************************************
*SPI Read char
************************************************************/
unsigned char SPI_Read_Byte(unsigned char cData)
{
SPDR = cData;                //write data
while(!(SPSR & (1<<SPIF)));//wait receive ok
return SPDR;               //返回数据
}
/************************************************************

************************************************************/
unsigned char DF_Read_status_Register(void)
{
unsigned char rData=0;
Enable_DFLASH();

SPI_Write_Byte(Status_Register_Opcode);//write opcode

rData = SPI_Read_Byte(0x00);//read device's status
rData = SPI_Read_Byte(0x00);//read device's status
rData = SPI_Read_Byte(0x00);//read device's status
rData = SPI_Read_Byte(0x00);//read device's status

Disable_DFLASH();
PORTA=rData;
return rData;
}
/************************************************************
*check busy status
*返回1表示不忙,否则为忙
************************************************************/
void DF_Check_Busy_State(void)
{
unsigned char state;
while(1)
{
   state=DF_Read_status_Register();
       if(state & 0x80) //读取的最高位0时器件忙
       break;
}
PORTA=state;
}
/************************************************************
*该函数为了测试该芯片有没有正常运行,正常会返回0X1F
************************************************************/
unsigned char DF_Manufacturer_and_Device_ID(void)
{
unsigned char i;
unsigned char ID_Inf={0,0,0,0};
DF_Check_Busy_State();

Enable_DFLASH();

SPI_Write_Byte(Device_ID_Opcode);

for(i=0;i<4;i++)
{
    ID_Inf = SPI_Read_Byte(0);
}
for(i=0;i<4;i++)
{
    ID_Inf = SPI_Read_Byte(0);
}

Disable_DFLASH();

if(ID_Inf == 0x1F)return 1;//这里只判断产家ID

PORTA=ID_Inf;
return0;
}
/************************************************************

************************************************************/
void main_delay(unsigned int n);
void DF_Reset(void)
{
SPI_PORT&=~(1<<RESET);
main_delay(10);
SPI_PORT|=(1<<RESET);
main_delay(10);
}
/************************************************************

************************************************************/
void main_delay(unsigned int n)
{
unsigned int i;
unsigned int j;
for(i=0;i<n;i++)
{
    for(j=0;j<255;j++)
        {
          asm("nop");
        }
}
}
/************************************************************

************************************************************/
void main(void)
{
main_delay(1000);
DDRA =0XFF;
PORTA=0X88;

DataFlash_Init();
DF_Reset();

DF_Check_Busy_State();
while(1)
{
    DF_Manufacturer_and_Device_ID();
    main_delay(10);
}
}

//AT45DB041D-SPI-16.h


#ifndef _AT45DB041D_H
#define _AT45DB041D_H

//设置Page Size的大小
//芯片默认为264 bytes
#define Page_Size_264   //如果有定义Page_Size_264则AT45DB041D全部Page Size为264计算,
                        //否则以256计算
                                               
//AT45DB041D有两个缓冲区Buffer1和Buffer2 (SRAM)

#define Buffer1       1
#define Buffer2       2
#define ReadBuffer    1
#define WriteBuffer   2

/******************************
*opcode-操作码
******************************/
#define Status_Register_Opcode   0xD7
#define Device_ID_Opcode         0x9F
//Read from buffer
//#define Read_Data_from_Buffer10xD4
#define Read_Data_from_Buffer10xD1   //lower frequency
//#define Read_Data_from_Buffer20xD6
#define Read_Data_from_Buffer20xD3   //lower frequency

//Write to buffer
#define Write_Data_to_Buffer1   0x84
#define Write_Data_to_Buffer2   0x87

//Read page to buffer
#define Read_Page_to_Buffer1   0x53
#define Read_Page_to_Buffer2   0x55

//Write buffer to page
#define Write_Buffer1_to_Page_whin_Erase   0x83
#define Write_Buffer2_to_Page_whin_Erase   0x86

//Continuous Array Read

//Page to Buffer Compare
#define Page_to_Buffer1_Compare   0x60
#define Page_to_Buffer2_Compare   0x61

#endif

bioe 发表于 2009-10-3 15:29:30

我也遇到同样问题,而且at45db041d的状态寄存器读出来始终为0,为什么?

yifengxing 发表于 2010-1-12 11:20:15

回复【5楼】bioe
-----------------------------------------------------------------------
我也是,读出来的全是FF ,楼上的几位,有已经解决这个问题的人么?帮帮忙啊

149147213 发表于 2010-7-15 15:52:22

我也晕倒同样问题~~~~~~~~

pursuer99 发表于 2010-7-25 22:48:54

怎么没有人来解决这个问题啊!!!!

longsky1985 发表于 2010-7-26 08:35:24

我用硬件的SPI可以的。

pipige 发表于 2010-12-3 14:34:04

我也是读出全是0xff,不知道是哪里的问题,哪位高人给指点一下吧

673104326 发表于 2010-12-27 18:36:30

SPI模式一定要和操作码对上,否则读出来的就不对!

pursuer99 发表于 2011-4-28 14:07:10

回复【楼主位】weizhonghui
-----------------------------------------------------------------------

lz,你的at45db041 模拟弄出来了吗 ? 我也在弄 现在读出状态是0x80,不是ox9c啊,

pursuer99 发表于 2011-4-28 17:38:22

有人能回答问题啊!

pursuer99 发表于 2011-5-14 11:46:31

-----------------------------------------------------------------------

回复【4楼】ahui2
-----------------------------------------------------------------------

你好,不知道你现在at45dbflash可调试好了,我状态一会儿读出来是0x80,一会儿是0x00,怎么回事

dmdream 发表于 2011-7-5 16:46:47

mark

cljt 发表于 2011-7-5 17:59:08

还没有高手回答??

xy_echo 发表于 2011-8-8 15:22:50

我读出来的值全是0xff,不知道大家的问题解决了没?

Andrewz 发表于 2014-3-3 16:34:16

解决了没??

hhhhhhgggg 发表于 2017-8-5 07:45:57

1、检查硬件单片机配置
2、初始化有没有错
3、看看那个寄存器支持读吗
4、查时序
页: [1]
查看完整版本: 利用ATmega128通用IO软件模拟SPI读取AT45DB041B的状态寄存器,总是0xFF,为什么?