这次还是说SPI读写FLASH(S25FL04),不过这次是直接使用Mega8的SPI口来读写FLASH,其速度比模拟SPI的要快很多。
程序如下:
#define SI 4
#define SO 3
#define SCLK 5
#define CS 2
#define WP 1
#define PORT1 PORTB
#define PIN1 PINB
#define DDR1 DDRB
#define WP_0 PORT1&=~(1<#define WP_1 PORT1|=(1<#define CS_0 PORT1&=~(1<#define CS_1 PORT1|=(1<
void Spi_init(void)
{
DDR1=((1<SPCR=((1<WP_1;
}
void Spi_MT(uint8 data)
{
SPDR=data;
while(!(SPSR&(1<}
uint8 Spi_MR()
{
uint8 data;
data=SPDR;
SPDR=data;
while(!(SPSR&(1<return SPDR;
}
/***************************************************************************************
读取一个字节
*****************************************************************************************/
uint8 Read_abyte(uint32 address)
{
uint8 data;
uint8 address2,address1,address0;
address2=(uint8)(address>>16);
address1=(uint8)(address>>8);
address0=(uint8)address;
while((Read_RDSR())&0x01);
CS_0;
Spi_MT(0x03);
Spi_MT(address2);
Spi_MT(address1);
Spi_MT(address0);
data=Spi_MR();
CS_1;
return data;
}
/***************************************************************************************
写入一个字节
*****************************************************************************************/
void Write_abyte(uint32 address,uint8 write_data)
{
uint8 address2,address1,address0;
address2=(uint8)(address>>16);
address1=(uint8)(address>>8);
address0=(uint8)address;
while((Read_RDSR())&0x01);
WriteEN();
CS_0;
Spi_MT(0x02);
Spi_MT(address2);
Spi_MT(address1);
Spi_MT(address0);
Spi_MT(write_data);
CS_1;
}
/***************************************************************************************
写入写使能命令
*****************************************************************************************/
void WriteEN(void)
{
CS_0;
Spi_MT(0x06);
CS_1;
}
/***************************************************************************************
写入写禁止命令
*****************************************************************************************/
void WriteDisable(void)
{
CS_0;
Spi_MT(0x04);
CS_1;
}
/***************************************************************************************
写入段擦除使能命令
*****************************************************************************************/
void Sector_Erase(uint32 address)
{
uint8 address2,address1,address0;
address2=(uint8)(address>>16);
address1=(uint8)(address>>8);
address0=(uint8)address;
while((Read_RDSR())&0x01);
WriteEN();
CS_0;
Spi_MT(0xd8);
Spi_MT(address2);
Spi_MT(address1);
Spi_MT(address0);
CS_1;
Prints("Erase sector ",0);
Send_abyte(table[address2/10]);
Send_abyte(table[address2%10]);
Prints(" completed...",1);
}
/***************************************************************************************
写入片擦除使能命令
*****************************************************************************************/
void Bulk_Erase(void)
{
WriteEN();
while((Read_RDSR())&0x01);
CS_0;
Spi_MT(0xc7);
CS_1;
Prints("Bulk Erawe completed...",1);
}
/***************************************************************************************
延时X/100ms
*****************************************************************************************/
void DelayX100ms(uint32 x)
{
uint32 i;
while(x--)
{
i="1295";
while(i--);
}
}
/***************************************************************************************
读取状态寄存器。
*****************************************************************************************/
uint8 Read_RDSR(void)
{
uint8 read_data;
//Prints("Run Read_RDSR()...",1);
CS_0;
Spi_MT(0x05);
//Prints("Run Spi_MT()...",1);
read_data=Spi_MR();
//Prints("Run Spi_MR()...",1);
CS_1;
return(read_data);
}
/**************************************************************
写入一串字节。
****************************************************************/
void Write_string(uint8 *string,uint32 address,uint16 n)
{
uint16 i;
uint8 address2,address1,address0;
address2=(uint8)(address>>16);
address1=(uint8)(address>>8);
address0=(uint8)address;
while((Read_RDSR())&0x01);
WriteEN();
CS_0;
Spi_MT(0x02);
Spi_MT(address2);
Spi_MT(address1);
Spi_MT(address0);
for(i=0;i{
Spi_MT(*string);
string++;
}
CS_1;
Prints("Write string start addr ",0);
Send_abyte('0');
Send_abyte('x');
Send_abyte('0');
Send_abyte(table[address2%16]);
Send_abyte(table[address1/6]);
Send_abyte(table[address1%16]);
Send_abyte(table[address0/16]);
Send_abyte(table[address0%16]);
Prints(" completed...",1);
}
/**************************************************************
读入一串字节。
****************************************************************/
void Read_string(uint32 address,uint32 n)
{
uint8 i;
uint8 address2,address1,address0;
address2=(uint8)(address>>16);
address1=(uint8)(address>>8);
address0=(uint8)address;
while((Read_RDSR())&0x01);
WriteEN();
CS_0;
Spi_MT(0x03);
Spi_MT(address2);
Spi_MT(address1);
Spi_MT(address0);
for(i=0;i{
read_string=Spi_MR();
}
CS_1;
}
/**************************************************************
写保护
****************************************************************/
void Write_Protect()
{
while((Read_RDSR())&0x01);
WriteEN();
CS_0;
Spi_MT(0x02);
Spi_MT(0X9C);
CS_1;
Prints("Chip Write Protect...",1);
}
基本的程序就这样了,主函数很简单,自己随便写个试试吧。至于调试图片,到周末空闲了再发给大家。
zwj-gg_818035047 2008-3-14 08:45