利用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){}
}
大家帮忙看一下,为什么啊? 以前用硬件SPI时碰到过,好像是SPI模式3才能工作。建议看看SPI模式和时序! 状态寄存器读出来应该是什么值?
是不是对于at45db41b来说,5位到2位固定的为0111 其他位就看情况了?
我按楼上的把操作码改成改为d7H结果读出来还是0xff
-----此内容被weizhonghui于2007-07-10,09:30:57编辑过 此问题有待高人指点,我现在也遇到同样的问题,头都大了。 我可以读出状态码,但读产家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 我也遇到同样问题,而且at45db041d的状态寄存器读出来始终为0,为什么? 回复【5楼】bioe
-----------------------------------------------------------------------
我也是,读出来的全是FF ,楼上的几位,有已经解决这个问题的人么?帮帮忙啊 我也晕倒同样问题~~~~~~~~ 怎么没有人来解决这个问题啊!!!! 我用硬件的SPI可以的。 我也是读出全是0xff,不知道是哪里的问题,哪位高人给指点一下吧 SPI模式一定要和操作码对上,否则读出来的就不对! 回复【楼主位】weizhonghui
-----------------------------------------------------------------------
lz,你的at45db041 模拟弄出来了吗 ? 我也在弄 现在读出状态是0x80,不是ox9c啊, 有人能回答问题啊! -----------------------------------------------------------------------
回复【4楼】ahui2
-----------------------------------------------------------------------
你好,不知道你现在at45dbflash可调试好了,我状态一会儿读出来是0x80,一会儿是0x00,怎么回事 mark 还没有高手回答?? 我读出来的值全是0xff,不知道大家的问题解决了没? 解决了没?? 1、检查硬件单片机配置
2、初始化有没有错
3、看看那个寄存器支持读吗
4、查时序
页:
[1]