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

📄 flash.c

📁 LPC213x系列微处理器操作M25P64存储器的驱动程序
💻 C
字号:

#include  "config.h"
#include "RD_LPC2100.h"
#include <stdarg.h>
#include <stdio.h>

#include "flash.h"
//#include "dataret.h"
#include "ASCII.h"

#include "userlib.h"

/*
//应该继续添加的内容
1 写操作之前的WREN命令
2 命令序列中的Selection Enable操作
3 写操作之间的RDSR操作,判断WIP标志位
4 Sector Erase之前的保存机制
5 
*/

// SSP作主机,当只和1个从机通信的时候,可以不用另外的IO口作从机选择线,直接用SSEL1即可。
//#define   SLAVE_CS       (1 << 29)      // P0.29口为SSP为从机的选择控制引脚


volatile uint32 FlashCurrentWriteAddr = 0,FlashCurrentReadAddr=0;
volatile uint8 flash_buf[256] = {0};
volatile FlashRecord AlarmDataRecord;
volatile uint8 FlashCurrentSector = 0,FlashFormatEn =0;
/*
*********************************************************************************************************
** 函数名称:SSP_Init()
** 函数功能:将SSP控制器设置为主机SPI。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************
*/
void  SSP_Init(void)
{
    
    PCONP |= 1<<10;
    // PINSEL1 = 0x000002A8;                  // 设置SSP管脚连接
    // PINSEL1 = 0xAA << 2;
   	PINSEL1 = (PINSEL1 & (~(0xFF << 2))) | (0xAA << 2);
    // IO0DIR = SLAVE_CS;
    // IO0SET = SLAVE_CS;
    SE1_DISABLE;
    SSPCR0 = (0x01 << 8) |              // SCR  设置SPI时钟分频
             (0x01 << 7) |              // CPHA 时钟输出相位,仅SPI模式有效 
             (0x01 << 6) |              // CPOL 时钟输出极性,仅SPI模式有效
             (0x00 << 4) |              // FRF  帧格式 00=SPI,01=SSI,10=Microwire,11=保留
             (0x07 << 0);               // DSS  数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位

    SSPCR1 = (0x00 << 3) |              // SOD  从机输出禁能,1=禁止,0=允许
             (0x00 << 2) |              // MS   主从选择,0=主机,1=从机
             (0x01 << 1) |              // SSE  SSP使能,1=允许SSP与其它设备通信
             (0x00 << 0);               // LBM  回写模式
             
    SSPCPSR = 0x52;                     // PCLK分频值
   // SSPIMSC = 0x07;                     // 中断屏蔽寄存器
    SSPICR  = 0x03;                     // 中断清除寄存器
}

void SSP_Soft_Init(void)
{
    SSP_SOFT;
    IO0DIR |= (DO1|SCK1|SE1);
    IO0DIR &= (~DI1);
    IOSET|= (DO1|SCK1|SE1|DI1);
}

/*
*********************************************************************************************************
* 函数名称:SSP_SendData()
* 函数功能:SSP接口向SPI总线发送数据。
* 入口参数:data        待发送的数据
* 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8  SSP_SendData(uint8 data)
{  
//    IOCLR = SLAVE_CS;			        // 选择从机   
    uint8 i;
    i = SSPDR;
    i++;
    SSPDR = data;
    while( (SSPSR & 0x10) == 0x10 );	    // 等待TFE置位,即发送FIFO空   
//    IOSET = SLAVE_CS;
    i = SSPDR;
    return(i);
}

uint SSPS_SendData(uint8 data,uint8 dataen)
{
    volatile uint8 i,j=0;
    
    for(i=0;i<8;i++)
    {
        SCK1L;
        if (dataen == 1)
        {
        if (((data<<i)&0x80)== 0)
        {
            DO1L;
        }
        else
        {
            DO1H;
        }
        
        }
        SCK1H;
        if (DI1H)
        {
            j|=0x01;
            j=j<<1;
        }
    }
    return (j);
}


/*
*********************************************************************************************************
* 函数名称:FLASH_CMD()
* 函数功能:Flash 存储器读写函数
* 入口参数:cmd   读写命令
* 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8 FlashCmd(uint8 cmd)
{
    return(1);
}

uint8 CMD_WREN(void)
{
    volatile uint8 i;
    SEL;
    i = SSP_SendData(WREN);
    SEH;
     i = CMD_RDSR();
     i = i;
    //while ((i&0x01)==1)
    //{
    //    i = CMD_RDSR();
    //}
    return (i);
}


uint8 CMD_WRDI(void)
{
    volatile uint8 i;
    SEL;
    i = SSP_SendData(WRDI);
    SEH;
    // i = CMD_RDSR();
    //while ((i&0x01)==1)
    //{
    //    i = CMD_RDSR();
    //}
    return (i);
}

volatile uint8 ID[3]={0};
uint8 CMD_RDID(void)
{
    volatile uint8 i;
    uint16 j;
    SEL;
    for (j=0;j<50000;j++);  //
    //DO1_ENABLE;
    i = SSP_SendData(RDID);
    //DO1_DISABLE;
    ID[0]=SSP_SendData(0xff);
    ID[1]=SSP_SendData(0xff);
    ID[2]=SSP_SendData(0xff);
    //DO1_ENABLE;
    SEH;
    SEH;
    i = ID[2];
    return (i);
}

uint8 CMD_RDIDS(void)
{
    volatile uint8 i;
    uint16 j;
    SEL;
    for (j=0;j<50000;j++);
    i = SSPS_SendData(RDID,1);
    ID[0]= SSPS_SendData(0,0);
    ID[1]= SSPS_SendData(0,0);
    ID[2]= SSPS_SendData(0,0);
    SEH;
    return (0);
}


uint8 CMD_RES(void)
{
    volatile uint8 i;
    uint16 j;
    SEL;
    for (j=0;j<50000;j++);
    //DO1_ENABLE;
    i = SSP_SendData(RES);

    ID[0]=SSP_SendData(0xff);
    ID[1]=SSP_SendData(0xff);
    ID[2]=SSP_SendData(0xff);
    //DO1_DISABLE;
    i = SSP_SendData(0xff);    
    //DO1_ENABLE;
    SEH;
    return (i);
}

uint8 CMD_RDSR(void)
{
    volatile uint8 i;
    uint16 j;
    SEL;
    for (j=0;j<50000;j++);
    //DO1_ENABLE;
    i = SSP_SendData(RDSR);
    //DO1_DISABLE;
    i = SSP_SendData(0xff);
    //DO1_ENABLE;
    SEH;
    // i = CMD_RDSR();
    //while ((i&0x01)==1)
    //{
    //    i = CMD_RDSR();
    //}
    
    return (i);
}

uint8 CMD_WRSR(uint8 data)
{
    volatile uint8 i;
    uint16 j;
    CMD_WREN();
    i = Wait_For_WEL();
    SEL;
    for (j=0;j<50000;j++);
    i = SSP_SendData(WRSR);
    i = SSP_SendData(data);
    SEH;
    i = Wait_For_Status(WIP);

    return (i);
}


uint8 CMD_READ(uint32 addr,uint8 *data,uint16 length)
{
    volatile uint8 i;
    uint16 j;
    //DO1_ENABLE;
    SEL;
    for (j=0;j<50000;j++);
    i = SSP_SendData(READ);
    i = SSP_SendData((uint8)(addr>>16));
    i = SSP_SendData((uint8)(addr>>8));
    i = SSP_SendData((uint8)(addr&0xff));
    
    //DO1_DISABLE;
    for (j=0;j<length;j++)
    {
        *(data+j) = SSP_SendData(0xff);
        //flash_buf[i] = SSP_SendData(0xff);
    }
    //DO1_ENABLE;
    SEH;
    return (*data);
}

uint8 CMD_FREAD(uint32 addr,uint8 length)
{
    volatile uint8 i;
    uint16 j;
    SEL;
    for (j=0;j<50000;j++);
    i = SSP_SendData(FAST_READ);
    i = SSP_SendData((uint8)(addr>>16));
    i = SSP_SendData((uint8)(addr>>8));
    i = SSP_SendData((uint8)(addr&0xff));
    i = SSP_SendData(0xff);
    
    //DO1_DISABLE;
    for (i=0;i<length;i++)
    {
        flash_buf[i] = SSP_SendData(0xff);
    }
    //DO1_ENABLE;
    SEH;
    return (i);
}

uint8 CMD_PP(uint32 addr,uint8 *data,uint16 length)
{
    volatile uint8 i;
    uint16 k,j;
    i = CMD_WREN();
    i = Wait_For_WEL();
    SEL;
    for (k=0;k<50000;k++);
    i = SSP_SendData(PP);
    i = SSP_SendData((uint8)(addr>>16));
    i = SSP_SendData((uint8)(addr>>8));
    i = SSP_SendData((uint8)(addr&0xff));
    for (j=0;j<length;j++)
    {
        i = SSP_SendData(*(data+j));
        //j = SSP_SendData(flash_buf[i]);
    }
    SEH;
    i = Wait_For_Status(WIP);
    return (i);
}

uint8 CMD_SE(uint32 saddr)
{
    volatile uint8 i;
    uint16 j;
    i = CMD_WREN();
    i = Wait_For_WEL();
    i = i;
    SEL;
    for (j=0;j<50000;j++);
    i = SSP_SendData(SE);
    i = SSP_SendData((uint8)(saddr>>16));
    i = SSP_SendData((uint8)(saddr>>8));
    i = SSP_SendData((uint8)(saddr&0xff));
    SEH;
    i = Wait_For_Status(WIP);
    i = i;
    return (i);
}

uint8 CMD_BE(void)
{
    volatile uint8 i;
    uint16 j;
    i = CMD_WREN();
    i = Wait_For_WEL();
    SEL;
    for (j=0;j<50000;j++);
    i = SSP_SendData(BE);
    SEH;
    i = Wait_For_Status(WIP);
    return (i);

}

uint8 Wait_For_WEL(void)
{
	volatile uint32 n, i;
	volatile uint8 status_register = 0;
	volatile uint8 ErrorCode = 0;	// tells us if there was an error erasing flash
	
		for(i = 0; i < 35; i++)
		{
			status_register = CMD_RDSR();
			if( (status_register & WEL)==WEL )
			{
				ErrorCode = 0;	// tells us if there was an error erasing flash
				break;
			}
			
			for(n=0; n<1000; n++)
				n= n;
				//asm("nop;");
			ErrorCode = 1;	// Time out error
		};
		
	return ErrorCode;
}

uint8 Wait_For_Status( uint8 Statusbit )
{
	volatile uint32 n, i;
	volatile uint8 status_register = 0xFF;
	volatile uint8 ErrorCode = 0;	// tells us if there was an error erasing flash
	
		for(i = 0; i < TIMEOUT; i++)
		{
			status_register = CMD_RDSR();
			if( !((status_register & Statusbit)==Statusbit) )
			{
				ErrorCode = 0;	// tells us if there was an error erasing flash
				break;
			}
			
			for(n=0; n<1000; n++)
				n=n;
				//asm("nop;");
			ErrorCode = 1;	// Time out error
		};
		
	return ErrorCode;
}


uint8 FlashRead(uint32 FlashAddr,uint8 *RamAddr,uint8 length)
{
    uint8 i;
    if (FLASHAUTO == FlashAddr)
    {
        FlashAddr = FlashCurrentReadAddr;
        i = CMD_READ(FlashAddr,RamAddr,length);
    }
    else
    {
        i = CMD_READ(FlashAddr,RamAddr,length);
    }
    FlashCurrentReadAddr += length;
    if (FLASH_AVAILABLE <= FlashCurrentReadAddr)
    {
        FlashCurrentReadAddr = 0;
    }
    return(i);
}

uint8 FlashWrite(uint32 FlashAddr,uint8 *RamAddr,uint8 length)
{
    uint8 i;
    if (FlashAddr == FLASHAUTO)
    {
        FlashAddr = FlashCurrentWriteAddr;
        i = CMD_PP(FlashAddr,RamAddr,length);
    }
    else
    {
        i = CMD_PP(FlashAddr,RamAddr,length);
    }
    FlashCurrentWriteAddr += length;
    if (FLASH_AVAILABLE <= FlashCurrentWriteAddr)
    {
        FlashCurrentWriteAddr = 0;      //reserve the upper 2 page
    }
    
    return(i);
}

uint8 RecordPackage(LPFlashRecord RData,LPUART485 UData,LPMONITDATA AData)
{
    RData->RecordID = 0;
    RData->RecordTrain = UData->train;            //*(2个字节)车次
    RData->RecordDriver = UData->driver;           //*(2个字节)司机号
    RData->RecordCarriageNum = CarriageNum;
    RData->RecordDistance = UData->distance;
    RData->RecordSpeed =  UData->speed;
    RData->RecordSec = UData->sec;
    RData->RecordMin = UData->min;
    RData->RecordHour = UData->hour;
    RData->RecordDate = UData->date;
    RData->RecordMonth = UData->month;
    RData->RecordHor1 = AData->Hor1;
    RData->RecordVer1 = AData->Ver1;
    RData->RecordHor2 = AData->Hor2;
    RData->RecordVer2 = AData->Ver2;
    RData->RecordHor3 = AData->Hor3;
    RData->RecordVer3 = AData->Ver3;
    RData->RecordHor4 = AData->Hor4;
    RData->RecordVer4 = AData->Ver4;
    RData->RecordForw = AData->Forw;
    RData->RecordAlarmFlag = AData->AlarmFlag;
    RData->RecordReserved0 = 0x55;
    RData->RecordReserved1 = 0xaa;
    
    return(0);
}

uint8 SearchRecordIndex(void)
{
    uint8 i;
    for (FlashCurrentReadAddr = 0;FlashCurrentReadAddr<FLASH_AVAILABLE;
            FlashCurrentReadAddr+=32)
    {
        i = FlashRead(FlashCurrentReadAddr,(uint8 *)flash_buf,32);
        if (0xff==i)
        {
            break;
        }
    }
    
    if (FLASH_AVAILABLE <= FlashCurrentReadAddr)
    {
        FlashCurrentReadAddr = 0;
        i = CMD_SE(FlashCurrentWriteAddr);
    }
    return(i);
}


uint8 ReadRecordFromFlash(LPFlashRecord RData)
{
    uint8 i;
    if ((FlashCurrentReadAddr&0x1f)==0)
    {
        //i = FlashRead(FlashCurrentReadAddr,(uint8 *)flash_buf,32);
        i = FlashRead(FlashCurrentReadAddr,(uint8 *)RData,32);
    }
    else
    {
        i=0;
    }
    return(i);
}

uint8 WriteRecord2Flash(LPFlashRecord RData)
{
    uint8 i;
    
    if ((FlashCurrentWriteAddr&0xffff)==0)
    {
        i = FlashRead(FlashCurrentWriteAddr,(uint8 *)flash_buf,32);
        if (0xff!=i)
        {
            i = CMD_SE(FlashCurrentWriteAddr);
        } 
    }
    
    FlashWrite(FlashCurrentWriteAddr,(uint8 *)RData,32);
    
    return(0);
}

⌨️ 快捷键说明

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