(Kinetis K60)flash读写

#include "uart4.h"
#include "LED.h"



void Flash_init(void);
U8 Flash_erase_sector(U16 sectorNo);
U8 Flash_write(U16 sectNo,U16 offset,U16 cnt,U8 buf[]);
U32 Flash_cmd_launch(void);
U8 Flash_read(U16 sectNo,U16 offset,U16 cnt,U8*bBuf);

void main(void)
{
    U8 NUM;
    U8 Send_Flash[] = "flash ";
    U8 Receive_Flash[6];

    DisableInterrupts;  

    UART4_Init(115200);
    Flash_init(); 

    EnableInterrupts;
 
    while(1)
    {
        Flash_erase_sector(100);
        Flash_write(100,0,6,Send_Flash);  
        Flash_read(100,0,6,Receive_Flash);
        for(NUM=0;NUM<6;NUM++)
            Uart4_SendByte(Receive_Flash[NUM]);
        Delay(1000); //一秒
    }
    
}

void Flash_init(void)
{
    FMC_PFB0CR |= FMC_PFB0CR_S_B_INV_MASK;       // 清除Flash预读取缓冲区
    
    while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK));    // 等待命令完成
    
    FTFL_FSTAT = (0 | FTFL_FSTAT_ACCERR_MASK      // 清除访问错误标志位
                    | FTFL_FSTAT_FPVIOL_MASK);    
}


U8 Flash_erase_sector(U16 sectorNo)
{
    union
    {
        U32  word;
        U8   byte[4];
    } dest;
    
    dest.word    = (U32)(sectorNo*(1<<11));

    FTFL_FCCOB0 = 0x09; //擦除扇区
    
    // 设置目标地址
    FTFL_FCCOB1 = dest.byte[2];
    FTFL_FCCOB2 = dest.byte[1];
    FTFL_FCCOB3 = dest.byte[0];
    
    // 执行命令序列
    if(1 == Flash_cmd_launch())    //若执行命令出现错误
        return 1;     //擦除命令错误
   
    // 若擦除sector0时,则解锁设备
    if(dest.word <= 0x800)
    {
        
        FTFL_FCCOB0 = 0x06; // 写入4字节
        // 设置目标地址
        FTFL_FCCOB1 = 0x00;
        FTFL_FCCOB2 = 0x04;
        FTFL_FCCOB3 = 0x0C;
        // 数据
        FTFL_FCCOB4 = 0xFF;
        FTFL_FCCOB5 = 0xFF;
        FTFL_FCCOB6 = 0xFF;
        FTFL_FCCOB7 = 0xFE;
        // 执行命令序列
        if(1 == Flash_cmd_launch())  //若执行命令出现错误
            return 2;   //解锁命令错误
    }  
    
    return 0;  //成功返回
}



U8 Flash_read(U16 sectNo,U16 offset,U16 cnt,U8*bBuf)
{
    U32 wAddr = 0;
    wAddr = sectNo * 2048 + offset;
    while (cnt--)
        *bBuf++=*(U8*)wAddr++;
   return TRUE;
}


U8 Flash_write(U16 sectNo,U16 offset,U16 cnt,U8 buf[])
{
    U32 size;
    U32 destaddr;
    
    union
    {
        U32   word;
        U8  byte[4];
    } dest;
    
    if(offset%4 != 0)
        return 1;   //参数设定错误,偏移量未对齐(4字节对齐)
    
    // 设置写入命令
    FTFL_FCCOB0 = 0x06;
    destaddr = (U32)(sectNo*(1<<11) + offset);//计算地址
    dest.word = destaddr;
    for(size=0; size<cnt; size+=4, dest.word+=4, buf+=4)
    {
        // 设置目标地址
        FTFL_FCCOB1 = dest.byte[2];
        FTFL_FCCOB2 = dest.byte[1];
        FTFL_FCCOB3 = dest.byte[0];
 
        // 拷贝数据
        FTFL_FCCOB4 = buf[3];
        FTFL_FCCOB5 = buf[2];
        FTFL_FCCOB6 = buf[1];
        FTFL_FCCOB7 = buf[0];
        
        if(1 == Flash_cmd_launch()) 
            return 2;  //写入命令错误
    }
    
    return 0;  //成功执行
}


U32 Flash_cmd_launch(void)
{
    // 清除访问错误标志位和非法访问标志位
    FTFL_FSTAT = (1<<5) | (1<<4);
    
    // 启动命令
    FTFL_FSTAT = (1<<7);

    // 等待命令结束
    while(!(FTFL_FSTAT &(1<<7)));

    // 检查错误标志
    if(FTFL_FSTAT & ((1<<5) | (1<<4) | 1))
        return 1 ; //执行命令出错
  
    return 0; //执行命令成功
}

 

posted @ 2013-06-25 05:41  默默地EEer  阅读(2140)  评论(1编辑  收藏  举报