原创 AVR(Mega8)的study:10、SPI读写FLASH

2008-3-13 22:02 4904 6 7 分类: MCU/ 嵌入式

      这次还是说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);
}


基本的程序就这样了,主函数很简单,自己随便写个试试吧。至于调试图片,到周末空闲了再发给大家。


工程包 点击下载

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

zwj-gg_818035047 2008-3-14 08:45

大哥用ade7755做的那么复杂,应该是研究生的吧, 能否提供一点资料,或者留下联系方式,我以后做的过程中如果有什么问题好向你请教! zwj-gg@qq.com 13507150742
相关推荐阅读
用户131149 2008-06-29 19:55
080629写了个按键的程序(扫描方式)
        刚刚写了个5个按键,扫描方式检测的。烧写进实验板后发现按起来不够灵敏,常常是按N多次才响应一次,高手帮忙看看什么问题。程序包在下面附件里,打算再用中断方式写一个看看。         ...
用户131149 2008-06-28 14:37
080628我的开发板,有PP
          得空拍了张图,大家可以看看!        ...
用户131149 2008-06-28 11:38
080628我的第一个ARM2410程序(2)
             昨天说了一下工程建立、编译链接及得到BIN文件,现在只要烧写到SDRAM里面就可以跑起来看看现象了。烧写前准备工作要做好。                1.先将板的串口线、...
用户131149 2008-06-28 01:34
080627成功的烧写到板上,跑了我的第一个程序(1)
              今天晚上花了点时间将昨天写好的程序,成功的下到了板上,跑了起来,迈出了实验的第一步。其中用USB下载花了我点时间来装驱动。现在将我跑的第一个程序过程给大家分享下。     ...
用户131149 2008-06-27 00:10
关于IO口模拟SPI
               最近有朋友问到IO口模拟SPI的问题,其实光模拟来说,就时序问题,读取和写入一个字节的时序。                   首先选4个IO口,作模拟用,分别模拟CS...
用户131149 2008-06-26 22:51
080626Make成第一个实验程序
        经过近两天对ADS和2410用户手册的学习,终于搞定了一个可以烧到板上的实验程序。由于板现在不在宿舍,所以还无法搞定。明天看能不能烧到板上跑起来。程序是从网上淘的一个,做了小小修改,以...
EE直播间
更多
我要评论
1
6
关闭 站长推荐上一条 /3 下一条