#include "iom32v.h"
#define uchar unsigned char
#define uint unsigned int
#define spi_cs 2 //PB2 O 片选
#define spi_rdy 1 //PB1 I 忙标志
#define spi_rst 0 //PB0 O
#define run_led 3 //PB3 O 指示灯
//命令字
#define F_READ_STATUS_CMD 0xD7 //STATUS_READ
#define F_WRITE_BUFFER1_CMD 0x84 //write buffer1
#define F_WRITE_BUFFER2_CMD 0x87 //write buffer2
#define F_READ_BUFFER1_CMD 0x54 //READ BUFFER1
#define F_READ_BUFFER2_CMD 0x56 //READ BUFFER2
#define F_WRITE_BUFFER1_TO_Page_CMD 0x83 //write buffer1 to page
#define F_WRITE_BUFFER2_TO_Page_CMD 0x86 //write buffer2 to page
#define F_READ_Page_TO_BUFFER1_CMD 0x53 //read main to buffer1
#define F_READ_Page_TO_BUFFER2_CMD 0x55 //read main to buffer2
#define F_READ_PAGE_CMD 0x52 //directly from main to ram
#define F_BUFFER_NUMBER1 0x01 //
uchar f_page_addrh ; //flash页地址缓存0~4096
uchar f_page_addrl ;
uchar f_data_addr ; //数据地址0~255
uchar f_data_num ; //数据个数0~255
uchar cpu_data_ram_addr; //
uchar f_page_addrth ; //内部地址
uchar f_page_addrtl ;
uchar f_page_byte_addr;
uchar CPU_RAM_SPI_DATA[30];
/* 延时us 子程序 */
void delay_us(int time) //us delay
{
do
{
time--;
}
while (time>1);
}
/*延时ms子程序 ms delay */
void delay_ms(unsigned int time)
{
while(time!=0)
{
delay_us(500);
time--;
}
}
//io方向初始化
io_init()
{
DDRB=0xd5; //
}
//SPI 初始化
void spi_init(void)
{
SPCR=0x51; //
SPSR=0x00; //
}
// flash spi 子函数
//往SPI写一个字节
void write_spi_one_byte(uchar data_buf)
{
SPDR=data_buf;
while(!(SPSR & (1<<SPIF)));
}
//读SPI一个字节
unsigned char read_spi_one_byte(void)
{
unsigned char data_buf;
SPDR=0x00;
while(!(SPSR & (1<<SPIF)));
data_buf=SPDR;
return data_buf;
}
//;************
//直接从flash页面读到RAM中
//;page页面以F_PAGE_ADDR, F_PAGE_BYTE_ADDR
//为起始页内地址的F_DATA_NUM个数据读入CPU_RAM_SPI_DATA[i]中
//;52
void READ_PAGE_DATA(uint f_page_addr,uchar f_page_byte_addr,uchar f_data_num)
{
uint temp;
uint f_page_addrt;
uchar i;
f_page_addrt=f_page_addr;
f_page_addrt=f_page_addrt*4;
PORTB &=~(1<<spi_cs); //0 选择
delay_us(5);
write_spi_one_byte(F_READ_PAGE_CMD);//命令52
temp=f_page_addrt; //页地址
write_spi_one_byte((char)(temp>>8));
temp=f_page_addrt;
write_spi_one_byte((char)(temp));
write_spi_one_byte(f_page_byte_addr); //页内地址
write_spi_one_byte(0x00);
write_spi_one_byte(0x00);
write_spi_one_byte(0x00);
write_spi_one_byte(0x00);
//开始读
for(i=0;i<f_data_num ;i++)
{
CPU_RAM_SPI_DATA[i]=read_spi_one_byte();
}
//读完
delay_us(5);
PORTB |=(1<<spi_cs) ;
}
//*************************
//************************
//;/*----------------------------------------------------------------
//; - 将指定buffer1中的的数据写入到指定主存_page中。自动删除
//; 保存buffer1 20MS 83H
//; ---------------------------------------------------------------*/
void WRITE_BUFFER1_TO_PAGE(uint f_page_addr)
{
uint temp;
uchar i;
uint f_page_addrt;
f_page_addrt=f_page_addr;
f_page_addrt=f_page_addrt*4;
PORTB &=~(1<<spi_cs); //0 选择
delay_us(5);
write_spi_one_byte(F_WRITE_BUFFER1_TO_Page_CMD);
temp=f_page_addrt; //页地址
write_spi_one_byte((char)(temp>>8));
temp=f_page_addrt;
write_spi_one_byte((char)(temp));
write_spi_one_byte(0x00);
//写完
delay_us(5);
PORTB |=(1<<spi_cs) ;
//
delay_ms(15);
}
//********************************
//;*******************************
//;- 将data_buff(cpu_data_ram_addr对应)中数据的前f_data_num个字节写入到指定buffer1中
//;F_DATA_ADDR 代表buffer中起始地址 84H
//
void WRITE_TO_BUFFER1(uchar f_data_addr,uchar f_data_num)
{
uchar i;
PORTB &=~(1<<spi_cs); //0 选择
delay_us(5);
write_spi_one_byte(F_WRITE_BUFFER1_CMD); //
write_spi_one_byte(0x00);
write_spi_one_byte(0x00);
write_spi_one_byte(f_data_addr);
for(i=0;i<f_data_num;i++)
{
write_spi_one_byte(CPU_RAM_SPI_DATA[i]);
}
delay_us(5);
PORTB |=(1<<spi_cs) ;
}
void main(void)
{
uchar i, j;
io_init();
spi_init();
PORTB |=(1<< spi_rst);
delay_ms(100);
while(1)
{
CPU_RAM_SPI_DATA[0]=0x89;
CPU_RAM_SPI_DATA[1]=0x95;
CPU_RAM_SPI_DATA[2]=0xfe;
CPU_RAM_SPI_DATA[3]=0x37;
//从CPU_RAM_SPI_DATA[i]把4个数据写进buffer1的0x30开始后
WRITE_TO_BUFFER1(0x30,0x04); //BUFFER1内地址,个数
WRITE_BUFFER1_TO_PAGE(3500); //把buffer1写进3500页
//
delay_ms(4000);
CPU_RAM_SPI_DATA[0]=0x00;
CPU_RAM_SPI_DATA[1]=0x00;
CPU_RAM_SPI_DATA[2]=0x00;
CPU_RAM_SPI_DATA[3]=0x00;
READ_PAGE_DATA(3500,0x30,0x04);
//从3500页第0x30字节直接读出4个到CPU_RAM_SPI_DATA中
if((CPU_RAM_SPI_DATA[0]==0x89)&&(CPU_RAM_SPI_DATA[1]==0x95)&&(CPU_RAM_SPI_DATA[2]==0xfe)&&(CPU_RAM_SPI_DATA[3]==0x37))
{
PORTB &=~(1<<run_led); //0 亮
delay_ms(100);
PORTB |=(1<<run_led); //1 灭
delay_ms(500);
}
}
}