电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【小熊派BearPi-loT开发板连载】MX25L1608存储器芯片开发
分 享
扫描二维码分享
【小熊派BearPi-loT开发板连载】MX25L1608存储器芯片开发
小熊派
MX251608
瑟寒凌风
关注
发布时间: 2021-05-27
丨
阅读: 554
MX25L1608是一种存储芯片,用来保存单片机程序中的参数. 定义flash结构体: ```c typedef struct { uint16_t FCE_Pin; //片选引脚 GPIO_TypeDef* FCE_Port; //片选引脚端口号 SPI_Cfg FSPI; //设备所用SPI接口 }MX251608D_Cfg; //DATAFLASH结构体 ``` void GetMX251608Dx_ID(u8* ID,MX251608D_Cfg* Fx) 获取设备ID ```c void GetMX251608Dx_ID(u8* ID) { if(ID == (u8*)0) //长度保护 return; MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x9F); ID[0] = SPIbyteSendGet(0); ID[1] = SPIbyteSendGet(0); ID[2] = SPIbyteSendGet(0); MX251608D_CEH(); //关闭设备 } ``` Flash的线性读操作 ```c s32 MX251608D_Read(u32 ReadAddr,u8* pBuffer,u32 Len) { u8 err = 0; //错误状态 u32 realLen = 0; //实际读到的数据个数 if(pBuffer == 0) //指针保护 return -1; if(Len == 0) //长度保护 return -1; // if(Fx == (MX251608D_Cfg*)0) //控制保护 // return 0; if(MX251608D_Mutex == 0) //互斥量未创建 return -1; SysMutexPend(MX251608D_Mutex, 0, &err); //获取互斥量 未获取到会一直等待 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x03); SPIbyteSendGet((ReadAddr & 0xFF0000) >> 16); SPIbyteSendGet((ReadAddr & 0xFF00) >> 8); SPIbyteSendGet(ReadAddr & 0xFF); while (Len--) { *pBuffer = SPIbyteSendGet(0); //获取数据 pBuffer++; //下一地址 realLen++; //实际读到的数据个数 } MX251608D_CEH(); //关闭设备 if(MX251608D_Mutex == 0) //互斥量未创建 return -1; SysMutexPost(MX251608D_Mutex); //释放互斥量 // *RealLen = realLen; //实际获取的数据个数 return realLen; //读取完成 } ``` 忙状态查询 ```c u8 MX251608D_IsBusy() { u8 Bflag = 0; //忙标志 u8 flashstatus = 0; MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x05); //查询状态 flashstatus = SPIbyteSendGet(0); Bflag = flashstatus & 0x01; //获取忙标志 [0]位上的标志是忙状态 1忙 0不忙 MX251608D_CEH(); //关闭设备 return Bflag; //返回忙标志 } ``` 忙等待 ```c void MX251608D_BusyWait() { u8 flashstatus = 1; //初始化为忙状态 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x05); //查询状态 while ((flashstatus & 0x01) == 1) flashstatus = SPIbyteSendGet(0); MX251608D_CEH(); //关闭设备 } ``` 擦除芯片 ```c void MX251608D_Erase() { MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x06); //写使能 MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0xC7); //芯片擦除 MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x04); //写失能 MX251608D_CEH(); //关闭设备 } ``` 擦除扇区 4096 Byte ```c void MX251608D_EraseSector(u32 SectorAddr) { MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x06); //写使能 MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x20); //扇区擦除 SPIbyteSendGet((SectorAddr & 0xFF0000) >> 16); SPIbyteSendGet((SectorAddr & 0xFF00) >> 8); SPIbyteSendGet(SectorAddr & 0xFF); MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x04); //写失能 MX251608D_CEH(); //关闭设备 } ``` 擦除块 65536 Byte ```c void MX251608D_EraseBlock(u32 BlockAddr) { MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x06); //写使能 MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0xD8); //块擦除 SPIbyteSendGet((BlockAddr & 0xFF0000) >> 16); SPIbyteSendGet((BlockAddr & 0xFF00) >> 8); SPIbyteSendGet(BlockAddr & 0xFF); MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x04); //写失能 MX251608D_CEH(); //关闭设备 } ``` Flash的页写操作 ```c void MX251608D_PageWrite(u8* pBuffer, u32 WriteAddr, u32 Len) { if(pBuffer == 0) //指针保护 return; if(Len == 0) //长度保护 return; MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x06); //写使能 MX251608D_CEH(); //关闭设备 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x02); //选择页 SPIbyteSendGet((WriteAddr & 0xFF0000) >> 16); //地址 SPIbyteSendGet((WriteAddr & 0xFF00) >> 8); SPIbyteSendGet(WriteAddr & 0xFF); while (Len--) //数据 { SPIbyteSendGet(*pBuffer); pBuffer++; } MX251608D_CEH(); //关闭设备 MX251608D_BusyWait(); //忙等待 MX251608D_CEL(); //开启设备 SPIbyteSendGet(0x04); //写失能 MX251608D_CEH(); //关闭设备 } ``` 线性存储 ```c s32 MX251608D_Write(u32 Addr,u8* Buffer,u32 Len) { u8 err; u16 PageSurplusLen = 0; //页剩余空间长度 最大256 u16 WLen = 0; //当前存数据长度 u32 RCnt = 0; //实际写入的数据个数 if(Buffer == 0) //指针保护 return -1; if(Len == 0) //长度保护 return -1; // if(Fx == (MX251608D_Cfg*)0) //控制保护 // return 0; //超过最大存储范围 if((Addr + Len) > CapacitySize) //0 - 2097152 (256 * 256) return -1; //写操作 while(Len > 0) //数据没处理完 { PageSurplusLen = PageSize - Addr % PageSize; //计算从所处页的所处页内地址到页结束可以存多少个数据 if(Len > PageSurplusLen) //希望存储的数据个数是否超过当前所处页剩余容量 WLen = PageSurplusLen; //按剩余容量存储 else WLen = Len; //按希望存储的数据个数存储 if(MX251608D_Mutex == 0) //互斥量未创建 return -1; SysMutexPend(MX251608D_Mutex, 0, &err); //获取互斥量 未获取到会一直等待获取 MX251608D_PageWrite(Buffer,Addr,WLen); //页存储数据 MX251608D_BusyWait(); //忙等待 if(MX251608D_Mutex == 0) //互斥量未创建 return -1; SysMutexPost(MX251608D_Mutex); //释放互斥量 RCnt += WLen; //实际写入的数据个数 Len -= WLen; //更新希望存储的数据个数 Buffer += WLen; //存储数据源偏移 Addr += WLen; //开始存储地址偏移 if(Len != 0) //数据没有存储完 { if((Addr % PageSize) != 0) //地址检查 下一次数据一定为页开头开始取 return -1; } } // *RealLen = RCnt; //实际写入的数据个数 return RCnt; } ``` 串口控制 ```c static s32 MX251608D_Ioctl(u32 cmd,u32 lParam) { switch(cmd) { case MX251608D_CMDERASE: //芯片擦除 { MX251608D_Erase(); return 1; } case MX251608D_CMDBLOCKERASE: //块擦除 { MX251608D_EraseBlock(lParam); return 1; } case MX251608D_CMDSECTORERASE: //扇区擦除 { MX251608D_EraseSector(lParam); return 1; } case MX251608D_CMDISBUSY: //忙检测 return MX251608D_IsBusy(); case MX251608D_CMDBUSYWAIT: //忙等待 { MX251608D_BusyWait(); return 1; } } return 0; //错误命令 } ``` DataFlash初始化 ```c u8 MX251608D_Init(u8 prio) { u8 err = 0; // GPIO_InitTypeDef G; #if(MX251608DA == 1) //注册用变量 DEV_REG mx25a = //设备注册信息表 不必static { BLOCK_DATAFLASH, //设备ID号 0, //是否共享 0:不可共享使用, 1:可共享使用 0, //对于共享设备最大打开次数 1, //最大读次数 1, //最大写次数 MX25A_pDisc, //驱动描述 自定义 20120001, //驱动版本 自定义 (u32*)MX251608D_Open, //设备打开函数指针 (u32*)MX251608D_Close, //设备关闭函数指针 (u32*)MX251608DRead, //块读函数 (u32*)MX251608DWrite, //块写函数 (u32*)MX251608D_Ioctl //控制函数 }; #endif #if(MX251608DA == 1) SPIx_Init(); //设备SPI初始化 // else if(MX25A.FCE_Port == GPIOC) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //开启引脚时钟C IoSetMode(FLASH_FCE,IO_MODE_OUTPUT); IoPushPull(FLASH_FCE); IoSetSpeed(FLASH_FCE,IO_SPEED_50M); MX251608D_CEH(); //关闭设备 if(MX251608D_Mutex == 0) MX251608D_Mutex = SysMutexCreate(prio, &err); //创建互斥量 //提升到的优先级,该优先级不能被占用 if(err != SYS_ERR_NONE) //互斥量创建失败 return 0; if(DeviceInstall(&mx25a) != HVL_NO_ERR) //设备注册 return 0; #endif return 1; } ``` 如此,函数准备完毕,在使用该器件的时候,只需要使用以上函数,即可完成读写操作.
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
瑟寒凌风
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交