|
我现在在调试一个w25x40的这个芯片,但是现在读单字节,读出来的数据时0xff,连续读是0x00,不知道什么原因,程序如下:
请大侠们帮我看看,问题出在哪里了?????????
单片机:stc12le5a60s2 (1t , 3.3v)
晶振:33MHz
#include<stc12c5a60s2.h>
#include<intrins.h>
#include<string.h> //strlen
typedef unsigned char uchar;
typedef unsigned int uint;
unsigned char mama320240[256]=
{
0xfa,0xfe,0xb5 ...........
};
unsigned char spi_nByte[256];
sbit SPI_CS = P2^3;
sbit SPI_CK = P2^1;
sbit SPI_DI = P2^0;
sbit SPI_DO = P3^4;
sbit SPI_WP = P3^5;
sbit SPI_HOLD = P2^2;
#define SPI_WP_H SPI_WP=1 //写保护关闭
#define SPI_WP_L SPI_WP=0 //写保护开启
#define SPI_CS_H SPI_CS=1
#define SPI_CS_L SPI_CS=0
#define SPI_CK_H SPI_CK=1
#define SPI_CK_L SPI_CK=0
#define SPI_DI_H SPI_DI=1
#define SPI_DI_L SPI_DI=0
#define SPI_DO_H SPI_DO=1
#define SPI_DO_L SPI_DO=0
#define SPI_WP_H SPI_WP=1
#define SPI_WP_L SPI_WP=0
#define SPI_HOLD_H SPI_HOLD=1
#define SPI_HOLD_L SPI_HOLD=0
#define WriteEnable 0x06 //写使能,设置状态寄存器
#define WriteDisable 0x04 //写禁止
#define ReadStatusRegister 0x05 //读状态寄存器
#define WriteStatusRegister 0x01 //写状态寄存器
#define Read_Data 0x03 //读取存储器数据
#define FastReadData 0x0B //快速读取存储器数据
#define FastReadDualOutput 0x3B //快速双端口输出方式读取存储器数据
#define Page_Program 0x02 //页面编程--写数据
#define BlockErace 0xD8 //块擦除,64kb
#define SectorErace 0x20 //扇区擦除 ,4kb
#define ChipErace 0xC7 //片擦除
#define Power_Down 0xB9 //掉电模式
#define ReleacePowerDown 0xAB //退出掉电模式
#define ReadDeviceID 0xAB //获取设备ID信息
#define ReadDeviceID 0xAB //退出掉电模式、设备ID信息
#define ReadManuIDDeviceID 0x90 //读取制造厂商ID信息和设备ID信息
#define ReadJedec_ID 0x9F //JEDEC的ID信息
#define FLASH_WriteAddress 0x700700
#define FLASH_ReadAddress FLASH_WriteAddress
#define FLASH_SectorToErase FLASH_WriteAddress
#define M25P64_FLASH_ID 0xEF0000
#define BufferSize (countof(Tx_Buffer)-1)
#define countof(a) (sizeof(a) / sizeof(*(a)))
#define Dummy_Byte 0xA5
#define SPI_FLASH_PageSize 256
void Spi_init();
void Spi_send_byte(unsigned char byte);
unsigned char Spi_get_byte();
unsigned char Spi_read_StatusRegister();
void Spi_wait_busy();
void Spi_write_StatusRegister(unsigned char byte);
void Spi_Write_Enable();
void Spi_Write_Disable();
unsigned char Spi_Read_Byte(unsigned long addr);
void Spi_Read_nByte(unsigned long addr,unsigned int nByte,unsigned char *p);
unsigned char Spi_FasttRead_Byte(unsigned long addr);
void spi_FasttRead_nByte(unsigned long addr,unsigned int nByte,unsigned char *p);
void Spi_Write_Byte(unsigned long addr,unsigned char dat);
void Spi_Write_PageByte(unsigned long addr,unsigned char *dat,unsigned int nByte);
void Spi_Write_Buffrer(unsigned long addr,unsigned char *dat,unsigned int nByte);
void Spi_Erase_Chip();
void Spi_Erase_Sector(unsigned long addr);
void Spi_Erase_Block(unsigned long addr);
void Spi_init()
{
SPI_CK_L; /* set clock to low initial state for SPI operation mode 0 */
// SPI_CK_H; /* set clock to low initial state for SPI operation mode 3 */
// SPI_HOLD_H;
SPI_WP_H;
SPI_CS_H;
Spi_Write_Disable();
}
void Spi_send_byte(unsigned char byte)
{
uchar i=0;
SPI_CS_L;
for(i=0;i<8;i++)
{
if(byte & 0x80) /* check if MSB is high */
SPI_DI_H;
else
SPI_DI_L;
SPI_CK_H;
byte <<= 1;
delay_us(10);
SPI_CK_L;
}
}
unsigned char Spi_get_byte()
{
uchar i=0,dat=0,temp=0;
SPI_CS_L;
for(i=0;i<8;i++)
{
dat <<= 1;
temp = SPI_DO;
SPI_CK_H;
if(temp)
dat |= 0x01;
SPI_CK_L;
}
return dat;
}
unsigned char Spi_read_StatusRegister()
{
uchar StatusRegister=0;
SPI_CS_L;
Spi_send_byte(ReadStatusRegister);
StatusRegister = Spi_get_byte();
SPI_CS_H;
return StatusRegister;
}
void Spi_wait_busy()
{
/* waste time until not busy WEL & Busy bit all be 1 (0x03). */
while(Spi_read_StatusRegister() == 0x03)
Spi_read_StatusRegister();
}
void Spi_write_StatusRegister(unsigned char byte)
{
Spi_Write_Enable();
SPI_CS_L;
Spi_send_byte(WriteStatusRegister); /* select write to status register */
Spi_send_byte(byte); /* data that will change the status(only bits 2,3,7 can be written) */
SPI_CS_H;
Spi_Write_Disable();
}
void Spi_Write_Enable()
{
SPI_CS_L;
Spi_send_byte(WriteEnable); /* select write to status register */
SPI_CS_H;
}
void Spi_Write_Disable()
{
SPI_CS_L;
Spi_send_byte(WriteDisable); // select write to status register
SPI_CS_H;
}
/*------------------------------------------------------
从芯片内读出一个字节的数据
addr是读取数据的地址
------------------------------------------------------*/
unsigned char Spi_Read_Byte(unsigned long addr)
{
unsigned char temp=0;
SPI_CS_L;
Spi_send_byte(Read_Data);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
temp = Spi_get_byte();
SPI_CS_H;
return temp;
}
void Spi_Read_nByte(unsigned long addr,unsigned int nByte,unsigned char *p)
{
unsigned char temp=0;
SPI_CS_L;
Spi_send_byte(Read_Data);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
for(temp=0;temp<nByte;temp++,*p++)
*p = Spi_get_byte();
SPI_CS_H;
}
unsigned char Spi_FasttRead_Byte(unsigned long addr)
{
unsigned char temp=0;
SPI_CS_L;
Spi_send_byte(FastReadData);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
Spi_send_byte(0xff); //dummy byte
temp = Spi_get_byte();
SPI_CS_H;
return temp;
}
/*----------------------------------
void spi_FasttRead_nByte(unsigned long addr,unsigned int nByte,unsigned char *p)
{
unsigned char temp=0;
SPI_CS_L;
Spi_send_byte(FastReadData);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
Spi_send_byte(0xff); //dummy byte
for(temp=0;temp<nByte;temp++,*p++)
*p = Spi_get_byte();
SPI_CS_H;
}
-----------------------------------------*/
/*------------------------------------------------------
写一个字节的数据
addr是写入数据的地址
dat 是写入的数据
------------------------------------------------------*/
void Spi_Write_Byte(unsigned long addr,unsigned char dat)
{
Spi_Write_Enable();
// Spi_wait_busy();
// SPI_CS_L;
Spi_send_byte(Page_Program);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
Spi_send_byte(dat);
SPI_CS_H;
Spi_Write_Disable();
}
/*------------------------------------------------------
写多字节的数据
addr是写入数据的地址
dat 是写入的数据
特别注意,此函数无法写超出地址之外的page页,如果超出则地址指针将在此page中将翻转
到0,最多写入256个byte,预先确认此page已经全部擦除为0xff
------------------------------------------------------*/
void Spi_Write_PageByte(unsigned long addr,unsigned char *dat,unsigned int nByte)
{
unsigned int i;
Spi_Write_Enable();
Spi_wait_busy();
Spi_send_byte(Page_Program);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
for(i=0;i<nByte;i++,*dat++)
Spi_send_byte(*dat);
SPI_CS_H;
Spi_Write_Disable();
}
void Spi_Write_Buffrer(unsigned long addr,unsigned char *dat,unsigned int nByte)
{
unsigned char Num0fPage=0,Num0fSingle=0,Addr=0,count=0,temp=0;
Addr = addr % SPI_FLASH_PageSize;
count = SPI_FLASH_PageSize - Addr;
Num0fPage = nByte / SPI_FLASH_PageSize;
Num0fSingle = nByte % SPI_FLASH_PageSize;
Spi_Write_Enable();
if(Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */
{
if(Num0fPage == 0) /* nByte < SPI_FLASH_PageSize */
{
Spi_Write_PageByte(addr,dat,nByte);
}
else /* nByte > SPI_FLASH_PageSize */
{
while(Num0fPage--)
{
Spi_Write_PageByte(addr,dat,SPI_FLASH_PageSize);
addr += SPI_FLASH_PageSize;
dat += SPI_FLASH_PageSize;
}
Spi_Write_PageByte(addr,dat,Num0fSingle);
}
}
else /* addr is not SPI_FLASH_PageSize aligned */
{
if(Num0fPage == 0) /* nByte < SPI_FLASH_PageSize */
{
if(Num0fSingle > count) /* (nByte + addr) > SPI_FLASH_PageSize */
{
temp = Num0fSingle - count;
Spi_Write_PageByte(addr,dat,count);
addr += count;
dat += count;
Spi_Write_PageByte(addr,dat,temp);
}
else
{
Spi_Write_PageByte(addr,dat,nByte);
}
}
else /* nByte > SPI_FLASH_PageSize */
{
nByte -= count;
Num0fPage = nByte / SPI_FLASH_PageSize;
Num0fSingle = nByte % SPI_FLASH_PageSize;
Spi_Write_PageByte(addr,dat,count);
addr += count;
dat += count;
while(Num0fPage--)
{
Spi_Write_PageByte(addr,dat,SPI_FLASH_PageSize);
addr += SPI_FLASH_PageSize;
dat += SPI_FLASH_PageSize;;
}
if(Num0fSingle != 0)
{
Spi_Write_PageByte(addr,dat,Num0fSingle);
}
}
}
SPI_CS_H;
Spi_Write_Disable();
}
void Spi_Erase_Chip()
{
Spi_Write_Enable();
// Spi_wait_busy();
// SPI_CS_L;
Spi_send_byte(ChipErace);
SPI_CS_H;
Spi_Write_Disable();
}
/*******************************************************************************
* Function Name : Spi_Erase_Sector
* Description : Erases the specified FLASH sector.
* Input : addr: address of the sector to erase.(24位的bit地址)
* Output : None
* Return : None
*******************************************************************************/
void Spi_Erase_Sector(unsigned long addr)
{
Spi_Write_Enable();
Spi_send_byte(SectorErace);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
SPI_CS_H;
Spi_Write_Disable();
}
/*******************************************************************************
* Function Name : Spi_Erase_Block
* Description : Erases the entire FLASH.
* Input : addr:Bulk的地址(24位的bit地址)
* Output : None
* Return : None
*******************************************************************************/
void Spi_Erase_Block(unsigned long addr)
{
Spi_Write_Enable();
Spi_wait_busy();
SPI_CS_L;
Spi_send_byte(BlockErace);
Spi_send_byte((addr & 0xff0000) >> 16);
Spi_send_byte((addr & 0xff00) >> 8);
Spi_send_byte(addr & 0xff);
SPI_CS_H;
Spi_Write_Disable();
}
void main()
{
uchar spi_dat=0;
Uart0_Init(); //串口初始化
Spi_init();
Spi_Erase_Chip(); //擦出芯片
Spi_Write_Byte(0,0xfb);
spi_dat = Spi_Read_Byte(0);
printexp("spi_dat",spi_dat,16); //读出来的数据通过串口发送到电脑上,此时的数据是0xff
Spi_Write_PageByte(1,mama320240,256);
Spi_Read_nByte(1,256,spi_nByte);
for(i=0;i<256;i++)
{
printexp("spi_nByte",spi_nByte,16); //此时的数据时0X00,不知道是什么原因??????那个16表示的是以16进制输出数据
}
for(;;)
{
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|