⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 SPI FLASH,SL811HST驱动
💻 C
字号:
/*flash.c*/

#include "flash.h"
#include "struct.h"
extern SYSTEMTIME CurrentTime;
//#include "rs485.h"
//extern box[3];

//extern wendu;

//extern box[3];			//定义3个探测箱数据结构	

//extern struct wendu box; 
/**********************************************************************************
*SPI初始化
***********************************************************************************/
void spi_init(void)
{
 	TRISC0=0;	//nCS  输出
 	TRISC3=0;	//SCK  输出
 	TRISC4=1;	//SI   输入
 	TRISC5=0;	//SO   输出
}

void Delay(void)
{
     asm("nop");
     asm("nop");
}
/**********************************************************************************
*向SPI写数据
*从SPI读数据
*数据一写入SSPBUF就开始发送,同时
***********************************************************************************/
/*
unsigned char OutPut(unsigned char SendData)
{
     unsigned char temp;
     SSPBUF=SendData;
     asm("nop");
     asm("nop");
	 while(BF==0)
	 {   
         asm("clrwdt");
     }
	 SSPIF=0;
     temp=SSPBUF;
     return temp;
}
*/
void OutPut(unsigned char data)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
    	SPI_SCK=0;
   		SPI_SDO=0;
    	if(data&0x80) SPI_SDO=1; //先发高位
   		data<<=1;
    	SPI_SCK=1;          //上升沿发数据
		asm("nop");
  }
	SPI_SDO=0;
}
unsigned char InPut(void)
{
	unsigned char i;
	unsigned char temp=0,readData=0;
	for(i=0;i<8;i++)
	{
		SPI_SCK=0;
		asm("nop");
		temp=SPI_SDI;
             //下降沿发读数
		SPI_SCK=1; 
    	//temp=temp<<i;
		readData<<=1;
		readData|=temp;
		
    }
	return readData;
}

//*************************************************************************************************
//直接读主存
void read_one_message(unsigned char *RBuff, unsigned int page_counter, unsigned int page_offset) 
{ 
	unsigned char i,temp; 
 
	SPI_nCS=0;
	Delay();
	OutPut(0xD2);                                       //读主存 
	OutPut((unsigned char)(page_counter>>6));                    //页地址PA11-PA6 
	OutPut((unsigned char)((page_counter<<2)|(page_offset>>8))); //页地址PA5-PA0,页内偏移BA9-BA8 

	OutPut((unsigned char)page_offset); 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 

	asm("nop");
	for(i=0;i<BYTES_PER_MSG;++i)  //每条信息8字节
	{	
		 temp=InPut();   		//*(RBuff+i)=read_memory(page,page_offset++); 
		//*(RBuff+i)=temp; 
		RBuff[i]=temp;
	}
	
	Delay();
	SPI_nCS=1;

}

void read_N_msg(unsigned char *Nbuf, unsigned int page_counter, unsigned int page_offset,unsigned char N)
{
	unsigned char i,temp,k; 

	SPI_nCS=0;
	Delay();
	OutPut(0xD2);                                       //读主存 
	OutPut((unsigned char)(page_counter>>6));                    //页地址PA11-PA6 
	OutPut((unsigned char)((page_counter<<2)|(page_offset>>8))); //页地址PA5-PA0,页内偏移BA9-BA8 

	OutPut((unsigned char)page_offset); 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 

	asm("nop");
	for(k=0;k<N;k++)
	{
		for(i=0;i<BYTES_PER_MSG;++i)  //每条信息8字节
		{	
			 temp=InPut();   		//*(RBuff+i)=read_memory(page,page_offset++); 
		//*(RBuff+i)=temp; 
		//RBuff[i]= temp;
			RBuff[k*BYTES_PER_MSG+i]=temp;
		}
	}
	Delay();
	SPI_nCS=1;
	
}
//直接写主存
void write_memory (unsigned char write_CMD,unsigned int page_counter,unsigned int page_offset) 
{ 
	OutPut(write_CMD);                                   //直接写主存,0X82选buffer1,0X85选buffer2 
	OutPut((unsigned char)(page_counter>>6));                     //页地址PA11-PA6 
	OutPut((unsigned char)((page_counter<<2)|(page_offset>>8)));  //页地址PA5-PA0,页内偏移BA9-BA8 
	OutPut((unsigned char)(page_offset)); 
} 

/******************************************************************************************************/
//最早记录16 bits、最新记录的下一条16 bits、循环标记 8 bits、
/******************************************************************************************************/
void read_flash_flag(unsigned char *FlagBuff)
{
//	read_one_message(FlagBuff,1007,0);
	unsigned char i,temp;
	const unsigned int page_counter = 1033;
	unsigned int page_offset = 0; 
 
	SPI_nCS=0;
	Delay();
	OutPut(0xD2);                                       //读主存 
	OutPut((unsigned char)(page_counter>>6));                    //页地址PA11-PA6 
	OutPut((unsigned char)((page_counter<<2)|(page_offset>>8))); //页地址PA5-PA0,页内偏移BA9-BA8 

	OutPut((unsigned char)page_offset); 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 
	OutPut(0x00);//无关位 

	asm("nop");
	for(i=0;i<3;++i)  //每条信息8字节
	{	
		 temp=InPut();   		//*(RBuff+i)=read_memory(page,page_offset++); 
		//*(RBuff+i)=temp; 
		FlagBuff[i]=temp;
	}
	
	Delay();
	SPI_nCS=1;	
	
}

void write_flash_flag(unsigned char *FlagBuff)
{
	unsigned char j,temp;
	
	SPI_nCS=0;
	Delay();
	write_memory (0x82,1033,0);    //
	for(j=0;j<3/*BYTES_PER_MSG*/;++j)  //
	{	
		temp=FlagBuff[j];   		//
		OutPut(temp); 
	}
	Delay();
	SPI_nCS=1;
}

/***************************************************************/
//比较USB txt文件最后一条数据的时间与FLASH中数据的时间,返回最早数据所在的页 或 最后一次复制过的数据的下一个页
/***************************************************************/

unsigned int find_last_copy(unsigned char pbuf[8], unsigned char *flash_flag) //pbuf为USB txt文件中最后一条信息的数据
{
	unsigned char  RBuff1[8];
//	unsigned int  i;//  /flash中最早的信息

	unsigned int  page0 ;//  //flash中最早的信息
//	unsigned char flash_flag[3];
	unsigned char CircleFlag;
	unsigned int flash_flag_int_new;
	unsigned int count_write ;

//	read_flash_flag(flash_flag);

	CircleFlag = flash_flag[2];

	flash_flag_int_new = (unsigned int)flash_flag[0];
	flash_flag_int_new <<=8;
	flash_flag_int_new|= flash_flag[1];

	if(CircleFlag==0x55)
	{
		page0 = flash_flag_int_new;
		count_write = 834;
	}
	else
	{
		page0 = 1;
		count_write = flash_flag_int_new - page0;
	}

//	for(i=0; i<833; ++i)     //总共834条数据
	while( count_write!=0)
	{
		count_write--;

		if(page0 > 834) page0=1;

		read_one_message(RBuff1, page0, 0);

		if(RBuff1[0]<pbuf[0])                  //年   该信息已经拷贝过
		{
			page0++;
		}
		else if(RBuff1[0]>pbuf[0])                   //该信息未拷贝过, 则全部拷贝,FLASH中的信息全部为新数据
			{
				return page0;
			}
			else if(RBuff1[1]<pbuf[1])            //月  该信息已经拷贝过
				{
					page0++;
				}
				else if(RBuff1[1]>pbuf[1])     //该信息未拷贝过, 则全部拷贝,FLASH中的信息全部为新数据
					{
						return page0;
					}
					else if(RBuff1[2]<pbuf[2])    //日   该信息已经拷贝过
						{
							page0++;
						}
						else if(RBuff1[2]>pbuf[2]) //该信息未拷贝过, 则全部拷贝,FLASH中的信息全部为新数据
							{
								return page0;
							}
							else if(RBuff1[3]<pbuf[3])    //时  该信息已经拷贝过
								{
									page0++;
								}
								else if(RBuff1[3]>pbuf[3])   //该信息未拷贝过, 则全部拷贝,FLASH中的信息全部为新数据
									{
										return page0;
									}
									else if(RBuff1[4]<pbuf[4])    //分  该信息已经拷贝过
										{
											page0++;
										}
										else if(RBuff1[4]>pbuf[4])    //该信息未拷贝过, 则全部拷贝,FLASH中的信息全部为新数据
											{
												return page0;
											}
											else     //时间信息完全一致,说明,上次拷贝正好到这个位置,则返回下一页
											{
												++page0;
												if(page0 > 834) page0=1;
												return page0;
											}
	}
	return 1000;

}

void write_flash( void )
{
//	unsigned int tpage_offset=0;
	unsigned char i,j,k,temp;
	unsigned char buff[8];
/******************test********************/
	unsigned char asc;
/********************************/
	unsigned char flash_flag[3];
	unsigned int flash_flag_int=0;

	read_flash_flag(flash_flag);

/*************test*********************/
	ClearLcd();
	asc = flash_flag[1]+'0';
	GotoXY(1,0);	
	Print(&asc);
	pause_ms(250);
/**************************************/

//	flash_flag_int = (((unsigned int)flash_flag[0])<<8)|flash_flag[1];
	flash_flag_int = (unsigned int)flash_flag[0];
	flash_flag_int <<=8;
	flash_flag_int|= flash_flag[1];

	asc = flash_flag_int+'0';
	GotoXY(1,3);	
	Print(&asc);
	pause_ms(100);
/*******************************************/
	SPI_nCS=0;
	Delay();
//	write_memory (0x82,tpage,0);    //tpage 为全局变量
	write_memory (0x82,flash_flag_int,0);
	for(i=0; i<10/*MSGS_PER_SAMPLE*/; ++i) //采样一次60条数据,10个箱子,6×10x8=480 Bytes
	{
	
		//485接受一个终端的数据//一个探测箱的数据
	//	show_time();
		Rs485_master( i );
		buff[5]=i;		//chest;
		for(k=0;k<6;k++)
		{
			//接收采集终端信息,tbuff随之变化
			buff[0]=CurrentTime.Year;		//year;
			buff[1]=CurrentTime.Month;		//month;
			buff[2]=CurrentTime.Day;		//data;
			buff[3]=CurrentTime.Hour;		//hour;
			buff[4]=CurrentTime.Minute;	    //miniute;
		
			buff[6]=k;		//channel;
			buff[7]=REC_BUF[k+i*6];		//tempeture;
			//write_one_message(buff, tpage, tpage_offset);	//tpage为全局变量
			for(j=0;j<BYTES_PER_MSG;++j)  //每条信息8字节
			{	
				 temp=buff[j];   		//
				 OutPut(temp); 
			}
		}
	}
	Delay();
	SPI_nCS=1;  //nCS上升沿将采样一次的信息从AT45DB161B的buffer1一起送入主存的对应page中
/************************************************/
	flash_flag_int++;


	asc = flash_flag_int+'0';
	GotoXY(1,5);	
	Print(&asc);
	pause_ms(100);

	if(flash_flag_int>834)
	{
		flash_flag_int = 1;
		flash_flag[2]=0x55;
	}

	flash_flag[1] = (unsigned char)flash_flag_int;
	flash_flag[0] = flash_flag_int>>8;          //最新数据页数的下一页页号

	asc = flash_flag[1]+'0';
	GotoXY(1,7);	
	Print(&asc);
	pause_ms(100);

	write_flash_flag(flash_flag);

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -