向韦东山学:裸板_SPI_FLASH 三部曲
go spi系列:裸板_SPI_FLASH 三部曲
作者:titer1? 本文所有代码版权归原作者所有? 读 设备id Read Manufacturer / Device 0x90? The Read Manufacturer/Devlce ID instruction is ve ry similar to th e Release from Powe r-dow n / Device IDinstruction.? After which,the Manufacturer ID for Winbond (EFh) and the Device ID are shifted out on the falling edge Of CLK with most significant bit (MSB) first as shown? The Device ID values for the W25Q16DV is listed in Manufacturer and Device Identification?
void SPIFlashReadID(int *pMID,int *pDID) { SPIFlash_Set_CS(0); /* 选中SPI FLASH */ SPISendByte(0x90); SPISendByte(0); SPISendByte(0); SPISendByte(0); *pMID = SPIRecvByte(); *pDID = SPIRecvByte(); SPIFlash_Set_CS(1); } 不过为了更有扩展性: static SPIFlashSendAddrunsigned int addr) { SPISendByte(addr >> 16); SPISendByte(addr >> 8); SPISendByte(addr & 0xff); } /* 选中SPI FLASH */ SPISendByte(0x90); SPIFlashSendAddr(0); *pMID = SPIRecvByte(); *pDID = SPIRecvByte(); SPIFlash_Set_CS(1); } 成员函数实现片选引脚设置实现原理就是 flash连到gpg pin2 spi 读函数的实现 看手册 理清时序? //pin:gpg5 master in char SPI_Get_DIvoid) { if (GPGDAT & (1<<5)) return 1; else 0; } SPIRecvByteint i; unsigned char val = 0; for (i = 0; i < 8; i++) { val <<= 1; SPI_Set_CLK(0); if (SPI_Get_DI()) val |= 1); } return val; } 测试函数@main摘取片段 SPIFlashReadID(&mid,&pid); printf("SPI Flash : MID = 0x%02x,PID = 0x%02xnr",mid,pid); sprintf(str,"SPI : %02x,%02x",pid); OLEDPrint(2,0,str); 小节:如果读id操作顺利,说明读写spi的逻辑都是通过的 实现spi 读 写 三大步guideline
环节1 之使能 禁用? 使能? 实现如下: SPIFlashWriteEnableint enable) { if (enable) { SPIFlash_Set_CS(0); SPISendByte(0x06); SPIFlash_Set_CS(else { SPIFlash_Set_CS(0x04); SPIFlash_Set_CS(1); } } 环节1之 状态寄存器
以上是状态寄存器的内容? 读状态SPIFlashReadStatusReg1char val; SPIFlash_Set_CS(0); SPISendByte(0x05); val = SPIRecvByte(); SPIFlash_Set_CS(1); return val; } SPIFlashReadStatusReg2void) { ... SPISendByte(0x35); ... return val; } 写状态简明说到就是 命令字1+状态寄存器1值+状态寄存器2值 SPIFlashWaitWhenBusywhile (SPIFlashReadStatusReg1() & 1);//bit0 表征busy 。。将会加载write封装命令的后面 } SPIFlashWriteStatusRegchar reg1,239)">char reg2) { SPIFlashWriteEnable(1); SPIFlash_Set_CS(0x01); SPISendByte(reg1); SPISendByte(reg2); SPIFlash_Set_CS(1); SPIFlashWaitWhenBusy(); } 应用 清理状态寄存器保护看懂状态寄存器的图示就是基础。 应用 清理状态数据寄存器保护 看懂状态寄存器的图示就是基础。? 本质就是将图是的红框中都设置为0 SPIFlashClearProtectForDatavoid) { /* cmp=0,bp2,1,0=0b000 */ char reg1,reg2; reg1 = SPIFlashReadStatusReg1(); reg2 = SPIFlashReadStatusReg2(); reg1 &= ~(7<<2);//关键:我的理解:bit 3 /2/1 都为1,bit0不管这里, reg2 &= ~(6); SPIFlashWriteStatusReg(reg1,reg2); } 以上就是三部曲之一:使能+状态寄存器清除 三部曲之二 :擦除 擦除大小是4k为单位,关键就是找到命令字? /* erase 4K */ SPIFlashEraseSectorint addr) { SPIFlashWriteEnable(0x20); SPIFlashSendAddr(addr); SPIFlash_Set_CS(1); SPIFlashWaitWhenBusy(); } 三部曲之三:编写
原理如图:
/* program */ SPIFlashProgramint addr,239)">char *buf,239)">int len) { int i; SPIFlashWriteEnable(0x02); SPIFlashSendAddr(addr); 0; i < len; i++) SPISendByte(buf[i]); SPIFlash_Set_CS(1); SPIFlashWaitWhenBusy(); } 最终集成去除写保护SPIFlashInitvoid) {
SPIFlashClearProtectForStatusReg();
SPIFlashClearProtectForData();
}
测试函数SPIFlashInit();//各宗使能,状态寄存器护理 SPIFlashEraseSector(4096); SPIFlashProgram(4096,116)">"100ask",255)">7); SPIFlashRead(7); "SPI Flash read from 4096: %snr",str); OLEDPrint(4,str); 做个标记,至此,视频播放在41:00? 小节完整讲解 spi + flash的操作。? 第一阶段就是认识 三部曲。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – 是否可以根据表示其类型的字符串值创建对象实例?
- 温度场有限容积法程序入门之六:后处理.花絮.Contour Plott
- object_getClassName swift得到类名
- ruby-on-rails – Nginx无法将请求协议正确转发到上游
- ruby-on-rails – Rails Kaminari – 如何订购/分页数组?
- Fragment异常:Binary XML file line #8: Error inflating c
- 设计模式之策略模式
- .NET微信开发之PC 端微信扫码注册和登录功能实现
- Swift GYB 简易教程
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第十七节