#include <c8051f120.h>
#include <stdio.h>
#include <stdlib.h>
#include "SPI.h"
#include "Global.h"
extern void Delay();
#define WEnable 0x06
#define WDisable 0x04
#define RStReg 0x05
#define WStReg 0x01
#define RData 0x03
#define FRData 0x0b
#define FRDouOut 0x3b
#define PagePro 0x02
#define BlockErase 0xd8
#define SectorErase 0x20
#define ChipErase 0xc7
#define PWRDown 0xb9
#define DevID 0xab
#define MFID 0x90
#define JEDECID 0x9f
sbit FramCS = P0^7;
typedef struct
{
unsigned char RBytes; // 读字节数
unsigned char WBytes; // 写字节数
unsigned char WRFlag; // 0为写 1 为 读
unsigned char *pWBuf; // 指向读写的缓冲区,用于写操作或者在读操作中写命令,字节地址等操作
unsigned char *pRbuf; // 指向读出数据缓冲区
unsigned char ST; // 总线状态 0 为空闲,1为忙
unsigned char FirstR; // 用于第1字节的假写
unsigned char FaultST; // 0 WCOL 1
}TST_SPI0CB;
TST_SPI0CB tstSPI0CB = {0,0,0,0,0,0,0,0};
unsigned char SPIRData[5] ={0,0,0,0,0};
void SPI0Init()
{
FramCS = 1; // 片选初始化为高电平
SFRPAGE = SPI0_PAGE;
SPI0CFG = 0x70; //主方式,空闲电平为高,第2边沿采样数据
SPI0CKR = (unsigned char)(SYSCLK/2/1000000L-1) ; //时钟 1000K
SPI0CN = 0x01; // 三线主或从方式 并使能SPI
// SPIF = 0;
EIE1 =0x01; // 使能SPI0中断
EA = 1;
}
void SPI0Write(unsigned char *pWBuf,unsigned char WBytes)
{
SFRPAGE = SPI0_PAGE;
while( tstSPI0CB.ST ); // 等待SPI空闲
// Delay();
if(tstSPI0CB.ST == 0) // 当前总线空闲
{
FramCS = 0 ;
tstSPI0CB.FaultST = 0;
tstSPI0CB.ST = 1 ; // 当前设备忙
tstSPI0CB.pWBuf = pWBuf;
tstSPI0CB.WRFlag = 0; // 当前为写
tstSPI0CB.WBytes = WBytes - 1;
tstSPI0CB.pRbuf = 0;
tstSPI0CB.RBytes = 0;
SPI0DAT = *tstSPI0CB.pWBuf; // 发送第一个字节
while( tstSPI0CB.ST ); // 等待写操作完毕!
}
}
void SPI0Read(unsigned char *pWBuf,unsigned char WBytes,unsigned char *pRBuf,unsigned char RBytes)
{
SFRPAGE = SPI0_PAGE;
while( tstSPI0CB.ST ); // 等待SPI空闲
// Delay();
if(tstSPI0CB.ST == 0) // 当前总线空闲
{
FramCS = 0 ;
tstSPI0CB.FaultST = 0;
tstSPI0CB.ST = 1 ; // 当前设备忙
tstSPI0CB.pWBuf = pWBuf;
tstSPI0CB.WBytes = WBytes - 1;
tstSPI0CB.WRFlag = 1; // 当前为读
tstSPI0CB.pRbuf = pRBuf;
tstSPI0CB.RBytes = RBytes;
tstSPI0CB.FirstR = 0;
// NOP ;
SPI0DAT = *tstSPI0CB.pWBuf; // 启动发送
while( tstSPI0CB.ST ); // 等待读操作完毕!
}
}
void ISR_SPI (void) interrupt 6
{
if(WCOL)
{
WCOL = 0;
tstSPI0CB.FaultST = 1;
return ;
}
else if(MODF)
{
MODF = 0;
tstSPI0CB.FaultST = 2;
return ;
}
if(SPIF)
{
SPIF = 0;
if(tstSPI0CB.WRFlag == 0) // 当前为写
{
if(tstSPI0CB.WBytes > 0)
{
tstSPI0CB.WBytes-- ;
tstSPI0CB.pWBuf++;
SPI0DAT = *tstSPI0CB.pWBuf;
}
else if(tstSPI0CB.WBytes == 0)
{
FramCS = 1 ; // CS变为高电平
tstSPI0CB.ST = 0; // 设备为空闲
// return ;
}
}
else if(tstSPI0CB.WRFlag == 1) // 当前为读
{
if(tstSPI0CB.WBytes > 0)
{
tstSPI0CB.pWBuf++;
tstSPI0CB.WBytes--;
SPI0DAT = *tstSPI0CB.pWBuf;
}
else // 命令或地址写完
{
if(tstSPI0CB.FirstR == 0)
{
tstSPI0CB.FirstR = 1;
SPI0DAT = 0xff; // 假写
return ;
}
else
{
if(tstSPI0CB.RBytes > 0)
{
*tstSPI0CB.pRbuf = SPI0DAT;
tstSPI0CB.pRbuf++;
tstSPI0CB.RBytes--;
SPI0DAT = 0xff;
}
else
{
FramCS = 1 ; // CS变为高电平
tstSPI0CB.ST = 0; // 设备为空闲
tstSPI0CB.FirstR = 0;
// return ;
}
}
}
}
}
}
//************************************Fram******************************************************//
void FramWEnable()
{
unsigned char pbuf[1];
pbuf[0] = WEnable ;
SPI0Write(pbuf,1);
}
void FramWDisable()
{
unsigned char pbuf[1];
pbuf[0] = WDisable ;
SPI0Write(pbuf,1);
}
unsigned char FramRSTReg()
{
unsigned char pbuf[1];
pbuf[0] = RStReg ;
SPI0Read(pbuf,1,SPIRData,1);
// while(tstSPI0CB.ST);
return SPIRData[0];
}
void FramWSTReg(unsigned char STData)
{
unsigned char pbuf[2];
pbuf[0] = WStReg ;
pbuf[1] = STData ;
SPI0Write(pbuf,2);
}
unsigned char FramWriteBytes(unsigned char *pwbuf,unsigned char nBytes)
{
unsigned char i;
unsigned char *pbuf ;
pbuf = (unsigned char *)malloc(4+nBytes);
if(pbuf == NULL)
return 0xff;
*pbuf = PagePro;
for(i=0;i<(nBytes+4);i++)
{
*(pbuf+i+1) = *(pwbuf+i);
}
SPI0Write(pbuf,nBytes+4);
free(pbuf); // 释放内存
return 0x11 ;
}
unsigned char FramReadBytes(unsigned char *pRArr,unsigned char *prbuf,unsigned char nBytes)
{
unsigned char i;
unsigned char *pbuf ;
pbuf = (unsigned char *)malloc(4);
if(pbuf == NULL)
return 0xff;
*pbuf = RData;
for(i=0;i<3;i++)
{
*(pbuf+i+1) = *(pRArr+i);
}
SPI0Read(pbuf,4,prbuf,nBytes);
free(pbuf);
return 0x11;
}
void FramSectorErase()
{
unsigned char erase[4];
erase[0] = SectorErase;
erase[1] = 0x01;
erase[2] = 0;
erase[3] = 0x34;
SPI0Write(erase,4);
}
void FramBlockErase()
{
}
void FramChipErase()
{
unsigned char pbuf[1];
pbuf[0] = ChipErase ;
SPI0Write(pbuf,1);
}
void ReadDevID()
{
unsigned char pbuf[4];
pbuf[0] = DevID ;
pbuf[1] = 0xff ;
pbuf[2] = 0xff ;
pbuf[3] = 0xff ;
SPI0Read(pbuf,4,SPIRData,1);
} |