📄 spidrv_p1.c
字号:
/****************************************************************************/
/* 深圳恒森微电子有限公司 (华邦单片机香港及中国区代理商) */
/* 香港恒森科技有限公司 (华邦单片机香港及中国区代理商) */
/* 陈文 email:chenwen@hengsen.cn (有 bug 请提交) */
/****************************************************************************/
/* 文件名: spidrv.c */
/* 版本 1.0 */
/* 创建日期: 2007-10-29 10:58 */
/* 概述: 本文件为 w79e823 读写 SPI flash程序 */
/*--------------------------------------------------------------------------*/
/* 历史修改记录: */
/* 名字 日期 注释 */
/* 陈文 2007.10.28 ver 1.0 */
/****************************************************************************/
#include <SST89x5xxRD2.H>
#include <intrins.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define uchar unsigned char
#define uint unsigned int
#define uint32 unsigned long
sbit W25X_WP = P1^3;
sbit W25X_CS = P1^4;
sbit W25X_DO = P1^5;
sbit W25X_DI = P1^6;
sbit W25X_CLK= P1^7;
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
void init_cpu(void);
void delay(uchar tt);
void trace(uchar *str,uchar len);
void test_page(uchar addr);
void read_page(uchar addr);
void Verify(uchar byte, uchar cor_byte);
void SPI_init();
void SPI_Send_Byte(uchar out);
uchar SPI_Get_Byte();
void SPI_Wait_Busy();
uchar SPI_Read_StatusReg();
void SPI_Write_StatusReg(byte);
void SPI_Write_Enable();
void SPI_PowerDown();
void SPI_ReleasePowerDown();
uchar SPI_Read_Byte(uint32 Dst_Addr);
void SPI_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128);
uchar SPI_FastRead_Byte(uint32 Dst_Addr);
void SPI_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128);
void SPI_Write_Byte(uint32 Dst_Addr, uchar byte);
void SPI_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128);
void SPI_WriteW25X_Disable();
void SPI_Erase_Chip();
void SPI_Erase_Sector(uint32 Dst_Addr);
uchar SPI_Read_ID1();
uint SPI_Read_ID2(uchar ID_Addr);
uint SPI_Read_ID3();
uint8 Rxtemp;
bit MYTI;
uint8 tx_buff[16];
uint8 upper_128[16];
bit rx_ok;
#define nop() _nop_()
void delay_nms(uchar i)
{ uchar j;
i=i*2;
for(;i>0;i--) { j = 246; while(--j); }
}
void main(void)
{ uint i;
init_cpu();
SPI_init();
tx_buff[0]='O';
tx_buff[1]='K';
trace(tx_buff,2);
for(;;)
{ if(rx_ok == 1)
{ rx_ok = 0;
switch(Rxtemp)
{ case 0x01:
Rxtemp = 0;
tx_buff[0] = SPI_Read_ID1();
trace(tx_buff,1);
break;
case 0x02:
i = SPI_Read_ID2(0x00);
tx_buff[1] = (uchar)i;
tx_buff[0] = (uchar)(i>>8);
trace(tx_buff,2);
break;
case 0x03:
i = SPI_Read_ID3();
tx_buff[1] = (uchar)i;
tx_buff[0] = (uchar)(i>>8);
trace(tx_buff,3);
break;
case 0x04:
tx_buff[0] = SPI_Read_Byte(0x00000000);
trace(tx_buff,1);
break;
case 0x05:
tx_buff[0] = 0x55;
SPI_Write_Byte(0x00000000,0xa5);
trace(tx_buff,1);
break;
case 0x06:
tx_buff[0] = SPI_Read_StatusReg();
trace(tx_buff,1);
break;
case 0x07:
SPI_Write_Enable();
break;
case 0x08:
upper_128[0]=0x01;upper_128[1]=0x02;upper_128[2]=0x03;upper_128[3]=0x04;
SPI_Write_nBytes(0x00000000,4);
break;
case 0x09:
SPI_Erase_Chip();
break;
case 0x0a:
SPI_Erase_Sector(0x000ff000);
while(1)
{ tx_buff[0] = SPI_Read_StatusReg();
if(tx_buff[0] == 0)
{ trace(tx_buff,1);
break;
}
}
break;
case 0x0b:
test_page(0x00);
break;
case 0x0c:
read_page(0x00);
break;
default:
break;
}
}
}
}
void init_cpu(void)
{ TMOD = 0x21;
PCON = PCON | 0x80; //波特率加倍
SCON = 0x50; //异步、10位、波特率可变,无校验位
TH1 = 0xfd; //在11.0592M晶振下,波特率是9600,
TL1 = 0xfd;
TR1 = 1; //T1 timer run
ES = 1; //uart interrupt enable
EA = 1; //all interrupt enable
}
//串口中断程序
void UART_isr(void) interrupt 4
{
if(RI)
{
RI = 0;
Rxtemp = SBUF; //接收
//SBUF = Rxtemp; //发送
rx_ok = 1;
return;
}
if(TI)
{
TI = 0;
MYTI = 1;
}
}
void SPI_Send_Byte(uchar out)
{
uchar i = 0;
W25X_CS = 0;
for (i = 0; i < 8; i++)
{
if ((out & 0x80) == 0x80) /* check if MSB is high */
W25X_DI = 1;
else
W25X_DI = 0; /* if not, set to low */
W25X_CLK = 1; /* toggle clock high */
out = (out << 1); /* shift 1 place for next bit */
nop();nop();nop();nop();
W25X_CLK = 0; /* toggle clock low */
}
}
//=================================================================================================
uchar SPI_Get_Byte()
{ uchar i = 0, in = 0, temp = 0;
W25X_CS = 0;
for (i = 0; i < 8; i++)
{ in = (in << 1); // shift 1 place to the left or shift in 0
temp = W25X_DO; // save input
W25X_CLK = 1; // toggle clock high
if (temp == 1) // check to see if bit is high
in |= 0x01; // if high, make bit high
W25X_CLK = 0; // toggle clock low
}
return in;
}
//=================================================================================================
void delay(uchar tt)
{
while(tt--);
}
//=================================================================================================
void SPI_Wait_Busy()
{
/* waste time until not busy WEL & Busy bit all be 1 (0x03). */
while (SPI_Read_StatusReg() == 0x03)
SPI_Read_StatusReg();
}
//=================================================================================================
void SPI_init()
{
W25X_CLK = 0; // set clock to low initial state for SPI operation mode 0
// W25X_CLK = 1; // set clock to High initial state for SPI operation mode 3
// _hold = 1;
W25X_WP = 1;
W25X_CS = 1;
SPI_WriteW25X_Disable();
}
//=================================================================================================
uchar SPI_Read_StatusReg()
{ uchar byte = 0;
W25X_CS = 0; // enable device
SPI_Send_Byte(W25X_ReadStatusReg); // send Read Status Register command
byte = SPI_Get_Byte(); // receive byte
W25X_CS = 1; // disable device
return byte;
}
//=================================================================================================
void SPI_Write_StatusReg(byte)
{ W25X_CS = 0; // enable device
SPI_Send_Byte(W25X_WriteStatusReg); // select write to status register
SPI_Send_Byte(byte); // data that will change the status(only bits 2,3,7 can be written)
W25X_CS = 1; // disable the device
}
//=================================================================================================
void SPI_Write_Enable()
{ W25X_CS = 0; // enable device
SPI_Send_Byte(W25X_WriteEnable); // send W25X_Write_Enable command
W25X_CS = 1; // disable device
}
//=================================================================================================
void SPI_PowerDown()
{ W25X_CS = 0; // enable device
SPI_Send_Byte(W25X_PowerDown); // send W25X_PowerDown command 0xB9
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -