当前位置: 首页 > news >正文

哪些网站可以做店淘客房地产市场调查报告

哪些网站可以做店淘客,房地产市场调查报告,温州网站设计服务商,医院网站设计与实现目录 1. 初始化 2. CS控制例子 3. 读ID 3.1 制造商 3.2 容量大小 3.3 设置IO类型 3.3.1 setQSPIWinbond 3.3.2 setQSPIMxic 3.3.3 setQSPIMicrochip 3.3.4 setQSPIMicron 4. 写保护 5. 等待空闲 6. 擦除扇区 7. 页编程 8. 页读 9. 写 10. 读 11. 验证 基于M…目录 1.  初始化 2. CS控制例子 3. 读ID 3.1 制造商 3.2 容量大小 3.3 设置IO类型 3.3.1 setQSPIWinbond 3.3.2 setQSPIMxic 3.3.3 setQSPIMicrochip 3.3.4 setQSPIMicron 4. 写保护 5. 等待空闲 6. 擦除扇区 7. 页编程 8. 页读 9. 写 10. 读 11. 验证 基于MPSSE SPI实现Nor Flash的读写。也定义两组flash。 typedef enum {SFLASH_PORT_0 0,SFLASH_PORT_1,SFLASH_PORT_MAX, }sflash_port_e; 定义一个结构体记录flash的属性 typedef struct {sflash_io_e ioType;uint8_t spiPort;void (*pCSEnable)(uint8_t port, bool enable);sflash_manufactor_e manufactor;sflash_size size;sflash_addr_size_e addrSize; }sflash_s; ioType表示flash的IO类型一般支持3种接口方式 typedef enum {SFLASH_SPI 0,SFLASH_DSPI,SFLASH_QSPI, }sflash_io_e; spiPort表示该flash使用哪组SPI pCSEnable对应CS脚控制的接口函数 manufactor该flash的生产商 typedef enum {SFLASH_Winbond 0,SFLASH_Cypress,SFLASH_ESMT,SFLASH_GigaDevice,SFLASH_MXIC,SFLASH_Micron,SFLASH_ISIS,SFLASH_Microchip,SFLASH_ZBit,SFLASH_FuDan,SFLASH_BOYA,SFLASH_Unknown, }sflash_manufactor_e; size该flash的大小 typedef enum {SFLASH_SIZE_256KB 0,SFLASH_SIZE_512KB,SFLASH_SIZE_1MB,SFLASH_SIZE_2MB,SFLASH_SIZE_4MB,SFLASH_SIZE_8MB,SFLASH_SIZE_16MB,SFLASH_SIZE_32MB, }sflash_size;addrSize该flash的地址宽度 typedef enum {SFLASH_ADDR_24BIT 3,SFLASH_ADDR_32BIT, }sflash_addr_size_e; 1.  初始化 void sflashInit(uint8_t port, sflash_s init) {if(port SFLASH_PORT_MAX)return;sflash[port] init; } 2. CS控制例子 初始化spi要根据实际情况配置CS的控制函数例如 #define SFLASH_CS_PIN 3 void sflash0CS(uint8_t port, bool enable) {spiCPOL(port);mpsseGpioWrite(SFLASH_CS_PIN, !enable); } 3. 读ID 通过命令0x9F读取flash的Jedec ID其函数原型为 uint32_t sflashReadJedecID(uint8_t port) 返回值即是id。 uint8_t cmd[4] {CMD_READ_ID, 0xff, 0xff, 0xff};uint32_t id;sflash[port].pCSEnable(port, true);spiWriteBytes(sflash[port].spiPort, cmd, 1);spiReadBytes(sflash[port].spiPort, cmd 1, 3);sflash[port].pCSEnable(port, false);id ((uint32_t)cmd[1] 16) | (uint32_t)(cmd[2] 8) | (uint32_t)(cmd[3]); 由于flash的QSPI方式和品牌商有关这里根据ID做判断注意这套规则并不是所有厂商都符合 3.1 制造商 由ID的16~23位确定品牌商 switch (id 0xff0000){case 0xEF0000:sflash[port].manufactor SFLASH_Winbond;printf(sflash Winbond\n);break;case 0x010000:sflash[port].manufactor SFLASH_Cypress;printf(sflash Cypress\n);break;case 0x8C0000:sflash[port].manufactor SFLASH_ESMT;printf(sflash ESMT\n);break;case 0xC80000:sflash[port].manufactor SFLASH_GigaDevice;printf(sflash GigaDevice\n);break;case 0xC20000:sflash[port].manufactor SFLASH_MXIC;printf(sflash MXIC\n);break;case 0x200000:sflash[port].manufactor SFLASH_Micron;printf(sflash Micron\n);break;case 0x5E0000:sflash[port].manufactor SFLASH_ZBit;printf(sflash ZBit\n);break;case 0x9D0000:sflash[port].manufactor SFLASH_ISIS;printf(sflash ISIS\n);break;case 0xA10000:sflash[port].manufactor SFLASH_FuDan;printf(sflash FuDan\n);break;case 0xBF0000:sflash[port].manufactor SFLASH_Microchip;printf(sflash Microchip\n);break;case 0x680000:sflash[port].manufactor SFLASH_BOYA;printf(sflash BOYA\n);break;default:sflash[port].manufactor SFLASH_Unknown;printf(sflash Unknown\n);break;} 3.2 容量大小 根据ID的位0~7确定容量大小 switch(id 0xff){case 0x12:sflash[port].size SFLASH_SIZE_256KB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 256KB, 24bits address\n);break;case 0x13:sflash[port].size SFLASH_SIZE_512KB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 512KB, 24bits address\n);break;case 0x14:sflash[port].size SFLASH_SIZE_1MB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 1MB, 24bits address\n);break;case 0x15:sflash[port].size SFLASH_SIZE_2MB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 2MB, 24bits address\n);break;case 0x16:sflash[port].size SFLASH_SIZE_4MB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 4MB, 24bits address\n);break;case 0x17:sflash[port].size SFLASH_SIZE_8MB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 8MB, 24bits address\n);break;case 0x18:sflash[port].size SFLASH_SIZE_16MB;sflash[port].addrSize SFLASH_ADDR_24BIT;printf(sflash size 16MB, 24bits address\n);break;case 0x19:sflash[port].size SFLASH_SIZE_32MB;sflash[port].addrSize SFLASH_ADDR_32BIT;printf(sflash size 32MB, 32bits address\n);break;} 3.3 设置IO类型 if (sflash[port].ioType SFLASH_QSPI){sflashSetQSPI(true);}else{sflashSetQSPI(false);} 根据不同制造商设置flash的IO类型这里只实现SPI和QSPI的方式部分制造商的设定方式是一样的。 bool sflashSetQSPI(uint8_t port, bool enable) {bool ret false;switch(sflash[port].manufactor){case SFLASH_Winbond:case SFLASH_GigaDevice:case SFLASH_Cypress:case SFLASH_ZBit:case SFLASH_BOYA:case SFLASH_FuDan:ret setQSPIWinbond(port, enable);break;case SFLASH_MXIC:case SFLASH_ESMT:case SFLASH_ISIS:ret setQSPIMxic(port, enable);break;case SFLASH_Microchip:ret setQSPIMicrochip(port, enable);break;case SFLASH_Micron:ret setQSPIMicron(port, enable);break;default:return false;}return ret; } 3.3.1 setQSPIWinbond 第一种方式以Winbond为代表QSPI的使能位在Status2寄存器中。 通过命令0x35读入该寄存器值通过0x31写即可。 bool setQSPIWinbond(uint8_t port, bool enable) {uint8_t cmd[2] {0x35, 0xff};sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 1) 0)return false;if(spiReadBytes(sflash[port].spiPort, cmd 1, 1) 0)return false;sflash[port].pCSEnable(port, false);if(enable true){if ((cmd[1] 0x02) 0x02) //QE 1{return true;}cmd[1] | 0x02;}else{if ((cmd[1] 0x02) 0x00) //QE 0{return true;}cmd[1] (uint8_t)0xFD;}cmd[0] 0x31;sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 2) 0)return false;sflash[port].pCSEnable(port, false);return true; } 3.3.2 setQSPIMxic 第二种方式以Mxic为代表QSPI的使能位在Status寄存器的位6 通过命令0x05读入该寄存器0x01写。 bool setQSPIMxic(uint8_t port, bool enable) {uint8_t cmd[2] {0x05, 0xff};sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 1) 0)return false;if(spiReadBytes(sflash[port].spiPort, cmd 1, 1) 0)return false;sflash[port].pCSEnable(port, false);if(enable true){if ((cmd[1] 0x40) 0x40) //QE 1{return true;}cmd[1] | 0x40;}else{if ((cmd[1] 0x40) 0x00) //QE 0{return true;}cmd[1] (uint8_t)0xBF;}cmd[0] 0x01;sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 2) 0)return false;sflash[port].pCSEnable(port, false);return true; } 3.3.3 setQSPIMicrochip Microchip的QSPI是 通过命令的方式使能0x38和禁止(0xFF)的。以SST26VF040A为例 bool setQSPIMicrochip(uint8_t port, bool enable) {uint8_t cmd[1] {0x38};if(enable true){sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 1) 0)return false;sflash[port].pCSEnable(port, false);}else{cmd[0] 0xff;sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 1) 0)return false;sflash[port].pCSEnable(port, false);}return true; } 3.3.4 setQSPIMicron Micron以MT25QL256为例的QSPI通过读写易失性配置寄存器的位7配置。 通过命令0x85读入该寄存器0x81写。 bool setQSPIMicron(uint8_t port, bool enable) {uint8_t cmd[2] {0x85, 0xff};sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 1) 0)return false;if(spiReadBytes(sflash[port].spiPort, cmd 1, 1) 0)return false;sflash[port].pCSEnable(port, false);if(enable true){if ((cmd[1] 0x80) 0x80) //QE 1{return true;}cmd[1] | 0x80;}else{if ((cmd[1] 0x80) 0x00) //QE 0{return true;}cmd[1] (uint8_t)0x7F;}cmd[0] 0x81;sflash[port].pCSEnable(port, true);if(spiWriteBytes(sflash[port].spiPort, cmd, 2) 0)return false;sflash[port].pCSEnable(port, false);return true; } 4. 写保护 使能写的命令为 #define CMD_WRITE_ENABLE 0x06 对应的函数 void sflashWriteEnable(uint8_t port) {uint8_t cmd[1] {CMD_WRITE_ENABLE};sflash[port].pCSEnable(port, true);spiWriteBytes(sflash[port].spiPort, cmd, 1);sflash[port].pCSEnable(port, false); } 禁止写的命令为 #define CMD_WRITE_DISABLE 0x04 对应的函数 void sflashWriteDisable(uint8_t port) {uint8_t cmd[1] {CMD_WRITE_DISABLE};sflash[port].pCSEnable(port, true);spiWriteBytes(sflash[port].spiPort, cmd, 1);sflash[port].pCSEnable(port, false); } 5. 等待空闲 通过读状态寄存器等待设备空闲。 void sflashWaitFree(uint8_t port) {while(true){uint8_t cmd[2] {CMD_READ_STATUS, 0xFF};sflash[port].pCSEnable(port, true);spiWriteBytes(sflash[port].spiPort, cmd, 1);spiReadBytes(sflash[port].spiPort, cmd 1, 1);sflash[port].pCSEnable(port, false);if((cmd[1] 0x01) 0)break;usleep(1000);} } 6. 擦除扇区 一般扇区大小为4096个字节擦除扇区的命令 #define CMD_SECTOR_ERASE 0x20 命令后面接需要擦除扇区的起始地址。 在擦除命令前必须先设置写使能擦除根据芯片不同可能需要几十ms才能完成例如W25Q128FVxxIQ需要45msSST26VF032B需要25ms等待一段时间后判断擦除是否完成最后恢复写保护。 void sflashEraseSector(uint8_t port, uint32_t addr) {uint8_t cmd[5] {CMD_SECTOR_ERASE, 0, 0, 0, 0};uint8_t offset 1;if(sflash[port].addrSize SFLASH_ADDR_32BIT)cmd[offset] (uint8_t)(addr 24);cmd[offset] (uint8_t)(addr 16);cmd[offset] (uint8_t)(addr 8);cmd[offset] (uint8_t)(addr 0);sflashWriteEnable(port);sflash[port].pCSEnable(port, true);spiWriteBytes(sflash[port].spiPort, cmd, offset);sflash[port].pCSEnable(port, false);usleep(1000 * 20);sflashWaitFree(port);sflashWriteDisable(port); } 7. 页编程 void sflashPageProgram(uint8_t port, uint32_t addr, uint8_t *buf, uint16_t len) norflash的写不能按字节写最小单位为页一般页的大小为256字节。但是实际上页内是可以按照字节写的。比如可以在地址16的位置写10个字节数据。 地址的计算方式和擦除一样 uint8_t cmd[5] {CMD_PAGE_PROGRAM, 0, 0, 0, 0};uint8_t offset 1;if(sflash[port].addrSize SFLASH_ADDR_32BIT)cmd[offset] (uint8_t)(addr 24);cmd[offset] (uint8_t)(addr 16);cmd[offset] (uint8_t)(addr 8);cmd[offset] (uint8_t)(addr 0); 然后不同的接口有不同的命令SPI的命令是0x02QSPI的命令是0x32这里有个特例MXIC的芯片QPI的命令是0x38。 #define CMD_PAGE_PROGRAM 0x02 #define CMD_PAGE_PROGRAM_QIO 0x32 注意QPI的接口模式下命令字是SPI方式发送的。  sflashWriteEnable(port);sflash[port].pCSEnable(port, true);if(sflash[port].ioType SFLASH_QSPI){cmd[0] CMD_PAGE_PROGRAM_QIO;if(sflash[port].manufactor SFLASH_MXIC){cmd[0] 0x38;}spiWriteBytes(sflash[port].spiPort, cmd, 1);qspiWriteBytes(sflash[port].spiPort, cmd 1, offset);qspiWriteBytes(sflash[port].spiPort, buf, len);}else{cmd[0] CMD_PAGE_PROGRAM;spiWriteBytes(sflash[port].spiPort, cmd, offset);spiWriteBytes(sflash[port].spiPort, buf, len);}sflash[port].pCSEnable(port, false); 最后等待编程结束 sflashWaitFree(port);sflashWriteDisable(port); 8. 页读 对于flash来说没有页读的概念这里定义页读的方式是因为FTDI设备每笔最大通信是64K字节每次读最好设置为256B这是因为FTDI设备的最大传输字节数为64KB由于GPIO模拟的SPI协议特别费字节大了会超过64KB的大小另外太大了有时候会出现通讯错误 对于SPI接口使用Fast Read命令0x0B对于QSPI使用0xEB命令。 #define CMD_FASTREAD 0x0B #define CMD_FASTREAD_QIO 0xEB 地址的计算等同其他 uint8_t cmd[5] {CMD_FASTREAD, 0, 0, 0, 0};uint8_t offset 1;if(sflash[port].addrSize SFLASH_ADDR_32BIT)cmd[offset] (uint8_t)(addr 24);cmd[offset] (uint8_t)(addr 16);cmd[offset] (uint8_t)(addr 8);cmd[offset] (uint8_t)(addr 0); 写完地址后需要空读1-2个字节QSPI是空读2个字节SPI读空1个字节 sflash[port].pCSEnable(port, true);if(sflash[port].ioType SFLASH_QSPI){uint8_t dummy[2];cmd[0] CMD_FASTREAD_QIO;spiWriteBytes(sflash[port].spiPort, cmd, 1);qspiWriteBytes(sflash[port].spiPort, cmd 1, offset);qspiReadBytes(sflash[port].spiPort, dummy, 2);qspiReadBytes(sflash[port].spiPort, buf, len);}else{uint8_t dummy[1];cmd[0] CMD_FASTREAD;spiWriteBytes(sflash[port].spiPort, cmd, offset);spiReadBytes(sflash[port].spiPort, dummy, 1);spiReadBytes(sflash[port].spiPort, buf, len);}sflash[port].pCSEnable(port, false); 9. 写 void sflashWrite(uint8_t port, uint32_t addr, uint8_t *buf, uint32_t len) 在写之前要确保flash已经擦除。 首先判断一下地址是不是页对齐不是就先把不齐的部分编程。 uint32_t offset 0;uint16_t count;if(port SFLASH_PORT_MAX)if(len 0)return;if((addr % sflashPageSize) 0){count (len (sflashPageSize - (addr % sflashPageSize))) ?(uint16_t)(sflashPageSize - (addr % sflashPageSize)) : (uint16_t)len;sflashPageProgram(port, addr, buf, count);offset count;len - count;addr count;} 剩余的数据写完 while (len 0){count (len sflashPageSize) ? (uint16_t)sflashPageSize : (uint16_t)len;sflashPageProgram(port, addr, buf offset, count);offset count;len - count;addr count;} 10. 读 void sflashRead(uint8_t port, uint32_t addr, uint8_t *buf, uint32_t len) 读可以任意的地址读没有特别的处理。 uint32_t offset 0;uint32_t readPageSize 256;while(len 0){uint16_t count;count (len readPageSize) ? (uint16_t)readPageSize : (uint16_t)len;sflashPageRead(port, addr, buf offset, count);offset count;len - count;addr count;} 11. 验证 配置和SPI验证一样。这里只验证SPI、Mode0的方式。 擦除扇区-写随机数据-读入数据-比较读写的数据是否相等。 #define EX_SFLASH_SIZE 2048uint8_t wrBuf[EX_SFLASH_SIZE];uint8_t rdBuf[EX_SFLASH_SIZE];int i;uint8_t port 0; 然后产生随机数据 srand(time(NULL));for(i 0; i EX_SFLASH_SIZE; i){wrBuf[i] (uint8_t)rand();rdBuf[i] 0;} 擦除一个扇区 sflashEraseSector(port, 0 * 4096); 将随机数据写入flash sflashWrite(port, 0, wrBuf, EX_SFLASH_SIZE); 再从相同地址读回 sflashRead(port, 0, rdBuf, EX_SFLASH_SIZE); 最后比较 for(i 0; i EX_SFLASH_SIZE; i){if(wrBuf[i] ! rdBuf[i]){printf(sflash test fail %d: %x!%x\n, i, wrBuf[i], rdBuf[i]);break;}}printf(sflash test finish\n);
http://www.zqtcl.cn/news/601140/

相关文章:

  • 手机管理网站网站打开速度优化
  • 做微网站需要什么做的比较好的美食网站有哪些
  • 五金商城网站建设注意wordpress虚拟空
  • 成都工程网站建设网站界面设计的优点
  • 网站建设里的知识找别人做公司网站第一步做什么
  • 婚纱摄影网站模板之家专业seo网站优化公司
  • 商丘市住房和城乡建设局网站广西网站建设timkee
  • php网站开发是做什么的网站策划总结
  • 站长工具seo推广秒收录WordPress注册插件中文
  • 目前个人网站做地最好是哪几家做汽配网站需要多少钱
  • php做网站多少钱网络营销推广方案3篇
  • 浙江坤宇建设有限公司 网站省直部门门户网站建设
  • 直播类网站怎么做上海市建设质量协会网站
  • 筑巢做网站怎么样网站设计接单
  • 会ps的如何做网站wordpress 仿虎嗅
  • 免费响应式网站建设嘉兴建企业网站
  • 织梦网站首页幻灯片不显示建设银行网站特色
  • php企业网站开发东莞网站建设时间
  • 仿win8网站模板网站开发接私活的经理
  • 仿牌网站 域名注册衡水安徽网站建设
  • 合肥义城建设集团有限公司网站专业建站公司电话咨询
  • 国外平面设计网站有哪些建商城网站公司
  • 深圳做响应式网站网站建设公司行业现状
  • 网站部署城阳网站开发公司
  • 旅游网站的网页设计素材如何网络推广运营
  • 惠州网站建设多少钱注册邮箱
  • 视频制作网站都有哪些网站优化的公司
  • 网站开发运营推广叫什么苏州seo关键词优化推广
  • 龙泉驿区建设局网站引流推广平台软件
  • 做盗版网站韩国服装网站建设