//--------------------------------------------------------------------------//
//标 题: SPI测试程序 C51模拟 //
//版 本: V1.00 //
//日 期: 2013-07-24 //
//描 述: P20 ->CS P21->CLK P22->DO P23-> DI //
//声 明: //
//--------------------------------------------------------------------------//
#include <reg52.h>
#include <intrins.h> //_nop_();
#include <Uart.h>
#include <SPI.h>
#define nop() _nop_()
uchar ID_DATA[8];
uchar SEL_CS;
//**************端口初始化*************************/
sbit SPI_CS1 = P2^0; //CS
sbit SPI_CS2 = P2^4; //CS
sbit SPI_CLK = P2^3; //CLK
sbit SPI_DO = P2^2; //DO
sbit SPI_DI = P2^1; //DI
//sbit SPI_WP = P2^4; //WP
/**********************************************************/
#define SPI_WriteEnable 0x06
#define SPI_WriteDisable 0x04
#define SPI_ReadStatusReg 0x05
#define SPI_WriteStatusReg 0x01
#define SPI_ReadData 0x03
#define SPI_FastReadData 0x0B
#define SPI_FastReadDual 0x3B
#define SPI_PageProgram 0x02
#define SPI_BlockErase 0xD8
#define SPI_SectorErase 0x20
#define SPI_ChipErase 0xC7
#define SPI_PowerDown 0xB9
#define SPI_ReleasePowerDown 0xAB
#define SPI_DeviceID 0xAB
#define SPI_ManufactDeviceID 0x90
#define SPI_JedecDeviceID 0x9F
/***********************************************************/
/*****************SPI初始化**********************************/
void SPI_init()
{
SPI_CLK = 0; // set clock to low initial state for SPI operation mode 0
//SPI_CLK = 1; // set clock to High initial state for SPI operation mode 3
//hold = 1;
//SPI_WP = 1;
SPI_CS1 = 1; // disable device
SPI_CS2 = 1;
//SPI_Write_Disable();
}
//============================================================
void SEL_Device(uchar cs_data)
{
switch (cs_data)
{
case 1:
SPI_CS1 = 0;
SPI_CS2 = 1;
break;
case 0:
SPI_CS1 = 1;
SPI_CS2 = 0;
break;
default:
break;
}
}
/**********************SPI单字节接收**************/
uchar SPI_Get_Byte()
{ uchar i = 0, in = 0, temp = 0;
//SPI_CS = 0;
SEL_Device(SEL_CS);
for (i = 0; i < 8; i++)
{ in = (in << 1); // shift 1 place to the left or shift in 0
temp = SPI_DO; // save input
SPI_CLK = 1; // toggle clock high
if (temp == 1) // check to see if bit is high
in |= 0x01; // if high, make bit high
SPI_CLK = 0; // toggle clock low
}
return in;
}
/**************************SPI发送单字节数据***********/
void SPI_Send_Byte(uchar out)
{
uchar i = 0;
//uchar a = 0;
//SPI_CS = 0;
SEL_Device(SEL_CS);
nop();nop();
SPI_CLK = 0;
for (i = 0; i < 8; i ++)
{
if ((out & 0x80) == 0x80) // check if MSB is high
SPI_DI = 1;
else
SPI_DI = 0; // if not, set to low
SPI_DI=out&0x80;
SPI_CLK = 1; // toggle clock high
out = (out << 1); // shift 1 place for next bit
nop();nop();nop();nop();
SPI_CLK = 0; // toggle clock low
}
}
/***************************************************************************************/
uchar SPI_Read_StatusReg()
{
uchar byte = 0;
SEL_Device(SEL_CS);
//SPI_CS = 0; // enable device
SPI_Send_Byte(SPI_ReadStatusReg); // send Read Status Register command
byte = SPI_Get_Byte(); // receive byte
SPI_CS1 = 1; // disable device
SPI_CS2 = 1;
return byte;
}
/*************************************************************/
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_Write_Enable()
{
//SPI_CS = 0; // enable device
SEL_Device(SEL_CS);
SPI_Send_Byte(SPI_WriteEnable); // send SPI_Write_Enable command
SPI_CS1 = 1; // disable device
SPI_CS2 = 1; // disable device
}
/********************SPI禁止写数据************************/
/*void SPI_Write_Disable()
{
SEL_Device(SEL_CS);
//SPI_CS = 0; // enable device
SPI_Send_Byte(SPI_WriteDisable); // send SPI_WriteSPI_DIsable command
SPI_CS1 = 1; // disable device
SPI_CS2 = 1; // disable device
}*/
//=================================制造/器件ID================================================
void SPI_Read_ID2(uchar ID_Addr)
{
//unsigned int IData16;
SEL_Device(SEL_CS);//SPI_CS = 0; // enable device
SPI_Send_Byte(SPI_ManufactDeviceID); // send read ID command (90h)
//SPI_Send_Byte(0x90);
SPI_Send_Byte(0x00); // send address
SPI_Send_Byte(0x00); // send address
SPI_Send_Byte(ID_Addr); // send W25Pxx selectable ID address 00H or 01H
//IData16 = SPI_Get_Byte()<<8; // receive Manufature or Device ID byte
//IData16 |= SPI_Get_Byte(); // receive Device or Manufacture ID byte
ID_DATA[0]=SPI_Get_Byte();
ID_DATA[1]=SPI_Get_Byte();
SPI_CS1 = 1;
SPI_CS2 = 1; // disable device
SendString(ID_DATA,2);
SPI_Wait_Busy();
//return IData16;
}
//============================= 读o个字节数据====================================================
void SPI_Read_nBytes(uint32 Dst_Addr,uint32 nBytes_128)
{
uint j;
SPI_Wait_Busy();
SEL_Device(SEL_CS);
//SPI_CS = 0; // enable device
SPI_Send_Byte(SPI_ReadData); // read command
SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));// send 3 address bytes
SPI_Send_Byte((uchar)((Dst_Addr & 0x00FFFF) >> 8));
SPI_Send_Byte((uchar)(Dst_Addr & 0x0000FF));
for (j = 0 ; j < nBytes_128 ; j++)//32768
{
ID_DATA[6] = SPI_Get_Byte();
Uart_Send(ID_DATA[6]);
}
SPI_CS1 = 1;
SPI_CS2 = 1; // disable device
SPI_Wait_Busy();
}
//=================================================================================================
void SPI_Write_nBytes(uint32 Dst_Addr, uint nBytes_128)
{
uint i;
SPI_Wait_Busy();
SEL_Device(SEL_CS);//SPI_CS = 0; // enable device
SPI_Write_Enable(); // set WEL
SEL_Device(SEL_CS);//SPI_CS = 0;
SPI_Wait_Busy();
SEL_Device(SEL_CS);//SPI_CS = 0;
SPI_Send_Byte(SPI_PageProgram); // send Byte Program command
SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16)); /* send 3 address bytes */
SPI_Send_Byte((uchar)((Dst_Addr & 0x00FFFF) >> 8));
SPI_Send_Byte((uchar)Dst_Addr & 0x0000FF);
for (i = 0; i<nBytes_128; i++)
{
- 1
- 2
前往页