(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; //执行命令成功 }