#include "N76E003.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "Common.h"
#include "Delay.h"
#define SPI_CLOCK 0
#define SS_PIN P15
#define WRITE_ENABLE 0x06
#define WRITE_DISABLE 0x04
#define READ_DATA 0x03
#define PAGE_PROGRAM 0x02
#define CHIP_ERASE 0xC7
#define READ_STATUS1 0x05
//-----------------------------------------------------------------------------------------------------------
void SPI_Error(void)
{
printf ("\n* SPI Error, please check the connection between MCU and SPI Flash");
while(1);
}
//-----------------------------------------------------------------------------------------------------------
void SPI_Initial(void)
{
#if SPI_CLOCK == 0
clr_SPR1;
clr_SPR0; //时钟除频
#elif SPI_CLOCK == 1
clr_SPR1;
set_SPR0;
#elif SPI_CLOCK == 2
set_SPR1;
clr_SPR0;
#elif SPI_CLOCK == 3
set_SPR1;
set_SPR0;
#endif
/* /SS General purpose I/O ( No Mode Fault ) */
set_DISMODF;
clr_SSOE;
/* SPI in Master mode */
set_MSTR;
/* MSB first */
clr_LSBFE;
clr_CPOL;
clr_CPHA;
/* Enable SPI function */
set_SPIEN;
}
//-----------------------------------------------------------------------------------------------------------
void Read_MID_DID(UINT8 *pu8MID,UINT8 *pu8DID)
{
SS_PIN = 0;
SPDR = 0x90;
while((SPSR&0x80)==0x00); //前面发的应该是指令,打开的是MID/DID的指令 ,90h 指令以/CS 拉低开始,然后通过DI传输指令代码90H和24位的地址(全为000000H)。这之后,WINBOND 的ID
// (EFH)和芯片ID将在时钟的下降沿以高位在前的方式传出。关于W25Q128BV 的芯片和制造商ID,在图29中列出。如果24位地址传输的是000001H,那么芯片ID将首先被传出,然后紧接着的是制造商ID。这两个是连续读出来的。该指令以/CS拉高结束。
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00); //24位地址(0x00,0x00,0x00)
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0xFF; //连续读数据
while((SPSR&0x80)==0x00);
*pu8MID = SPDR;//把SPDR的值发给pu8MID
clr_SPIF;
SPDR = 0xFF; //连续读数据
while((SPSR&0x80)==0x00);
*pu8DID = SPDR; //把SPDR的值发给pu8DID
clr_SPIF;
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Write_Enable(void) //写使能,06H
{
SS_PIN = 0;
SPDR = WRITE_ENABLE; //06
while((SPSR&0x80)==0x00);
clr_SPIF;
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Write_Disable(void) //禁止写,04H
{
SS_PIN = 0;
SPDR = WRITE_DISABLE; //04
while((SPSR&0x80)==0x00);
clr_SPIF;
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Chip_Erase(void) //全片擦除,C7H/60H
{
SS_PIN = 0;
SPDR = CHIP_ERASE; //0xC7
while((SPSR&0x80)==0x00);
clr_SPIF;
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Read_Status(void) //读状态寄存器1,05H
{
UINT8 u8Status;
SS_PIN = 0;
do{
SPDR = READ_STATUS1; // 0x05,开始读状态寄存器1
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0xFF; //连续写数据,把数据写入到SPDR,读到的数据为状态寄存器1
while((SPSR&0x80)==0x00);
u8Status = SPDR;//01h为写状态寄存器
clr_SPIF;
}while((u8Status&0x01)==0x01);
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Erase_Verify(void) // flash 擦除证明
{
UINT16 u16CNT;
UINT8 u8Data;
SS_PIN = 0;
SPDR = READ_DATA;// 0x03 ,读数据
while((SPSR&0x80)==0x00);
clr_SPIF;
/* 24-bit Address */
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
for(u16CNT=0;u16CNT<256;u16CNT++)
{
SPDR = 0x00; // ???
while((SPSR&0x80)==0x00);
u8Data = SPDR;
clr_SPIF;
if(u8Data != 0xFF)
{
SPI_Error();
}
}
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Program(void)
{
UINT16 u16CNT;
SS_PIN = 0;
SPDR = PAGE_PROGRAM; // 0x02
while((SPSR&0x80)==0x00);
clr_SPIF;
/* 24-bit Address */
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
/* Send the data to SPI_Flash buffer */
for(u16CNT=0;u16CNT<256;u16CNT++)
{
SPDR = (UINT8)u16CNT;
while((SPSR&0x80)==0x00);
clr_SPIF;
}
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void Flash_Program_Verify(void)
{
UINT16 u16CNT;
UINT8 u8Data;
SS_PIN = 0;
SPDR = READ_DATA;
while((SPSR&0x80)==0x00);
clr_SPIF;
/* 24-bit Address */
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
SPDR = 0x00;
while((SPSR&0x80)==0x00);
clr_SPIF;
for(u16CNT=0;u16CNT<256;u16CNT++)
{
SPDR = 0x00; //???
while((SPSR&0x80)==0x00);
u8Data = SPDR;
clr_SPIF;
if(u8Data != (UINT8)u16CNT)
{
SPI_Error();
}
}
SS_PIN = 1;
}
//-----------------------------------------------------------------------------------------------------------
void main(void)
{
UINT8 u8MID,u8DID;
/* Note
MCU power on system clock is HIRC (22.1184MHz), so Fsys = 22.1184MHz
*/
Set_All_GPIO_Quasi_Mode;
InitialUART0_Timer3(115200); /* 9600 Baud Rate*/
SPI_Initial();
Read_MID_DID(&u8MID,&u8DID);
if((u8MID != 0xEF)&&(u8DID != 0x14)) //manufacturer id=MID ,Device ID=DID
{
SPI_Error();
}
/* The procedure of SPI Flash at erase mode */
Flash_Write_Enable();
Flash_Chip_Erase();
Flash_Read_Status();
Flash_Write_Disable();
Flash_Erase_Verify();
/* The procedure of SPI Flash at program mode */
Flash_Write_Enable();
Flash_Program();
Flash_Read_Status();
Flash_Write_Disable();
/* Program verify */
Flash_Program_Verify();
printf("\nFinished the SPI Demo Code and test pass!!!\n");
while(1);
}
//-----------------------------------------------------------------------------------------------------------
问题我在程序中用红色标出来了,SPDR=0X00,这个应该是指令,可是代表什么指令我查了半天资料还是不懂,麻烦大神帮忙给我解释一下吗,谢谢。
|