#include <reg52.h>
#include <spi.h>
#include <intrins.h>
sbit scl = P2^0;
sbit miso = P2^2;
sbit mosi = P2^1;
sbit cs = P2^3;
void delay(uchar t) //延时
{
uchar i,j;
for(i = t;i > 0;i --)
for(j =0 ;j < 10;j ++)
{;;}
}
// system init
void init()
{
cs = 1;
// miso = 0;
mosi = 1;
scl = 1;
}
//write commend enable or disable signal
void spi_wren(uchar wren_com) //write enable wren_com=0x06
{
uchar i;
cs=0; //select chip,when cs=0
for(i=0;i<8;i++) //
{
scl = 0; //cycle move left a bit,when the scl full edge event
wren_com = (wren_com << 1);
mosi = CY;
scl = 1; //the data send to mosi port,when scl rise edge event
_nop_();
}
_nop_();
mosi = 0; //mosi=0,scl=0,when 8 bit data move over
scl = 0;
cs = 1;
}
void spi_wrdi(uchar wrdis_com) //write disable wr_com=0x04
{
uchar i;
cs = 0;
for(i = 0;i < 8;i ++)
{
scl = 0;
wrdis_com = (wrdis_com << 1);
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
mosi = 0;
cs = 1;
}
//write status
void spi_wrsr(uchar wrsr_com,uchar wrsr_dat)
{
uchar i;
cs = 0;
for(i = 0;i < 8;i ++) //write status instruction is 0x01
{
scl = 0;
wrsr_com = wrsr_com << 1;
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
for(i = 0;i < 8;i ++) //write status register data is 0x02
{
scl = 0;
wrsr_dat = wrsr_dat << 1;
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
mosi = 0;
cs = 1;
check_wip();
}
// page erase only used to 512K EEPROM spi
void spi_page_erase(uchar page_erase_com,uint wr_addr)
{
uchar i;
uint j;
cs = 0;
for(i = 0;i < 8;i ++) //write status instruction is 0x01
{
scl = 0;
page_erase_com = page_erase_com << 1;
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
for(j = 0;j < 16;j ++) //write address high 16 bit 0x0000
{
scl = 0;
wr_addr = (wr_addr << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
cs = 1;
check_wip();
}
//sector erase
void spi_sector_erase(uchar sector_erase_com,uint wr_addr)
{
uchar i;
uint j;
cs = 0;
for(i = 0;i < 8;i ++) //write status instruction is 0x01
{
scl = 0;
sector_erase_com = sector_erase_com << 1;
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
for(j = 0;j < 16;j ++) //write address high 16 bit 0x0000
{
scl = 0;
wr_addr = (wr_addr << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
cs = 1;
check_wip();
}
//chip erase
void spi_chip_erase(uchar chip_com)
{
uchar i;
cs = 0;
for(i = 0;i < 8;i ++) //write status instruction is 0x01
{
scl = 0;
chip_com = chip_com << 1;
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
cs = 1;
check_wip();
}
//set deep power down mode
void spi_deep_power_down_mode(uchar dpd_com)
{
uchar i;
cs = 0;
for(i = 0;i < 8;i ++) //write status instruction is 0x01
{
scl = 0;
dpd_com = dpd_com << 1;
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
cs = 1;
delay(100);
}
//byte write
void spi_byte_write(uchar wr_byte_com,uint wr_addr,uchar wr_dat) //write 1 btye data
{
uchar i;
uint j;
cs=0;
for(i=0;i<8;i++) // output instruction code "0x02"
{
scl = 0;
wr_byte_com = (wr_byte_com<<1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
_nop_();
for(j = 0;j < 16;j ++) //write address high 16 bit 0x0000
{
scl = 0;
wr_addr = (wr_addr << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
_nop_();
for(i=0;i<8;i++) //write 8 bit data 0x55
{
scl = 0;
wr_dat = (wr_dat << 1);
mosi = CY;
scl = 1;
_nop_();
}
_nop_();
scl = 0;
mosi=0;
cs=1;
check_wip();
}
//page write
void spi_page_write(uchar wr_page_com,uint wr_addr,uchar pwr_dat[]) //write 8 btye data
{
uchar i;
uint j;
// uchar *q;
uchar n,string_dat;
cs=0;
for(i=0;i<8;i++) // output instruction code "0x02"
{
scl = 0;
mosi = wr_page_com & 0x80;
wr_page_com = (wr_page_com << 1);
scl = 1;
_nop_();
}
scl = 0;
_nop_();
for(j=0;j<16;j++) //write address 16 bit
{
scl = 0;
mosi = wr_addr & 0x8000;
wr_addr = (wr_addr << 1);
scl = 1;
_nop_();
}
scl = 0;
_nop_();
for(n = 0;n < 8;n++) //send data
{
string_dat = pwr_dat[n]; //define a temp variable area is string_dat
for(i = 0;i < 8;i ++) //write 8 bit data
{
scl = 0;
string_dat = string_dat << 1;
mosi= CY;
scl = 1;
_nop_();
}
scl = 0;
}
scl = 0;
mosi = 0;
cs = 1;
check_wip();
}
//read status
uchar spi_rdsr(uchar wdsr_com)
{
uchar read_status=0,i;
cs=0;
for(i=0;i<8;i++) // first write instruction to mosi 0x05
{
scl = 0;
wdsr_com = (wdsr_com<<1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
_nop_();
mosi = 0;
for(i=0;i<8;i++) // second data from status register
{
scl = 1;
_nop_();
read_status = read_status << 1;
scl = 0;
read_status|=miso;
_nop_();
}
_nop_();
scl = 0;
mosi = 0;
cs = 1;
return read_status;
}
// check status register wip bit
void check_wip(void)
{
uchar temp,wip;
do{
temp=spi_rdsr(rdsr);
wip = temp & 0x01;
}while(wip);
}
//read a byte data
uchar spi_byte_read(uchar read_com,uint read_addr)
{
uchar read_dat,i;
uint j;
// miso=0;
cs=0;
for(i = 0;i < 8;i ++) // write instruction 0x03 to status register
{
scl = 0;
read_com = (read_com << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
_nop_();
mosi = 0;
for(j = 0;j < 16;j ++) // write 16 bit address
{
scl = 0;
read_addr = (read_addr << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
for(i=0;i<8;i++) // data out
{
scl = 1;
_nop_();
read_dat = read_dat << 1;
scl = 0;
read_dat |= miso;
_nop_();
}
mosi=0;
_nop_();
scl = 0;
cs = 1;
return read_dat;
}
// page read
void spi_page_read(uchar read_com,uint wr_addr)
{
uchar rd_page_dat,i,n,read_dat[8];
uint j;
// miso=0;
cs=0;
for(i = 0;i < 8;i ++) // write instruction 0x03 to status register
{
scl = 0;
read_com = (read_com << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
_nop_();
mosi = 0;
for(j = 0;j < 16;j ++) // write 16 bit address
{
scl = 0;
wr_addr = (wr_addr << 1);
mosi = CY;
scl = 1;
_nop_();
}
scl = 0;
mosi = 0;
for(n = 0;n < 8;n ++)
{
rd_page_dat = read_dat[n];
for(i = 0;i < 8;i ++) // data out
{
scl = 1;
_nop_();
rd_page_dat = rd_page_dat << 1;
scl = 0;
rd_page_dat |= miso;
_nop_();
}
P1 = rd_page_dat;
}
mosi=0;
_nop_();
scl = 0;
cs = 1;
}