上位机图像处理和嵌入式模块部署(f407 mcu中的spi总线操作)

news/2024/10/18 18:23:07/

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        前面我们学习mcu,一般都是模板和模块之间的接口,比如说串口、usb、eth这种。还有一种接口,更多的是芯片和芯片之间的接口,比如说spi、iic、iis、sdio这种,这其中尤其是以spi最为典型。spi本身是一种总线协议,但是总线上面传输什么格式数据,这是不一定的。另外,spi对接的,可能是norflash,可能是nand flash,可能是wifi,可能是ad/da芯片,也可能是一块屏幕。

        所以学习spi的时候,一般需要分成两部分。第一部分,就是mcu上面的spi应该如何配置、如何发命令;另外一部分,就是和mcu对接的spi芯片,需要spi发什么样的命令才能进行通信。今天我们spi对接的就是一块norflash芯片。

1、基本电路

        学习前,我们可以简单了解一下norflash的芯片接口,其实也不复杂,主要就是四根线。一个是cs,一个是sck,一个是miso(master in slave out),一个是mosi(master out slave in)。

2、配置spi基本属性

        spi配置方面,主要就是两个部分。一个是设置spi的gpio属性,对这四个pin进行设置;还有一个就是配置spi的基本属性。前面gpio的设置方法,我们都比较熟悉,今天看下spi的设置方法。

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(FLASH_SPI, &SPI_InitStructure);SPI_Cmd(FLASH_SPI, ENABLE);

3、利用spi实现flash协议

        spi配置好了之后,这个时候就可以结合norflash芯片手册来编写代码了。编写的代码,要严格按照flash给出的时序来做。出现问题的话,也只有拿着协议手册、示波器和代码,来做比对分析了,

void SPI_FLASH_SectorErase(u32 SectorAddr)
{SPI_FLASH_WriteEnable();SPI_FLASH_WaitForWriteEnd();SPI_FLASH_CS_LOW();SPI_FLASH_SendByte(W25X_SectorErase);SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);SPI_FLASH_SendByte(SectorAddr & 0xFF);SPI_FLASH_CS_HIGH();SPI_FLASH_WaitForWriteEnd();
}

        这个函数其实就是根据norflash的时序来做的。它的主要功能是对某一个sector进行erase操作。首先写使能,等待写使能结束。接着cs拉低,依次输入erase命令、sector的24位地址,cs拉高。最后等待写结束。整个操作结束,对应的sector就erase好了。这里面W25X_SectorErase就是flash特有的命令,类似的命令还有这些,

#define W25X_WriteEnable		      0x06 
#define W25X_WriteDisable		      0x04 
#define W25X_ReadStatusReg		      0x05 
#define W25X_WriteStatusReg		  	  0x01 
#define W25X_ReadData			      0x03 
#define W25X_FastReadData		      0x0B 
#define W25X_FastReadDual		      0x3B 
#define W25X_PageProgram		      0x02 
#define W25X_BlockErase			      0xD8 
#define W25X_SectorErase		      0x20 
#define W25X_ChipErase			      0xC7 
#define W25X_PowerDown			      0xB9 
#define W25X_ReleasePowerDown	 	  0xAB 
#define W25X_DeviceID			      0xAB 
#define W25X_ManufactDeviceID   	  0x90 
#define W25X_JedecDeviceID		      0x9F 

        如果是其他的spi芯片,一般也会给出对应的命令和时序要求的。一开始大家自己不会写,其实没有关系,只要看懂别人的代码就可以。因为大多数norflash、nandflash的命令都是差不多的。后期编写其他spi芯片,也只需要看懂别人的示例代码,自己会改写就好了。

4、测试方法

        测试还是比较简单的,首先读取device id,接着读取flash id。如果flash id读取没有问题,先erase一个sector的数据,接着依次write数据、read数据。read出来的数据,要和之前write的数据进行比较。没问题,则代表数据ok;有问题,则代表写入失败。最后则是flash下电处理。

5、编译验证

        一起都准备好之后,就可以开始烧入了。运行的时候,串口提示读取不到flash id,看了一下代码,确认是作者把cs的a3当然了a4,修改一下

#define FLASH_CS_PIN                        GPIO_Pin_4             
#define FLASH_CS_GPIO_PORT                  GPIOA                     
#define FLASH_CS_GPIO_CLK                   RCC_AHB1Periph_GPIOA

        重新编译烧入,这个时候可以读到flash id,但是测试没有开始,单步调试一下,发现id不匹配。可能是因为作者后期替换了flash芯片,我们添加一下测试的flash id,

#define  sFLASH_ID                       0xEF4016    //W25Q32
#define  pFLASH_ID                       0x856016    //P25Q32
#define  qFLASH_ID                       0x684016    

        判断逻辑也重新修改下,

	if(FlashID == sFLASH_ID||FlashID == pFLASH_ID||FlashID == qFLASH_ID){/* ...... */}

        至此,测试可以顺利进行了。不过测试的时候,发现flash id有的时候可以读出来;有的时候会失败。不太清楚失败的原因是flash原因,还是读的太快了。这个时候我们把延时放大一点,至少读不出来的现象没有了,

	DeviceID = SPI_FLASH_ReadDeviceID();Delay( 20000 ); FlashID = SPI_FLASH_ReadID();

        重新编译后,上电、复位、测试,输出的结果是这样的,

6、总结

        从存储的角度来说,有的时候mcu生成的文件比较大,或者是一部分数据mcu放不下,例如字体、图片、配置文件,这些都需要放在norflash、nandflash里面,这都是常有的事情。建议大家好好掌握一下。


http://www.ppmy.cn/news/1466196.html

相关文章

HTML 总结

HTML 简介 HTML(HyperText MarkupLanguage): 超文本标记语言 超文本 : 普通文本指的是只有文字没有图片 ,视频, 音乐,而超文本就有 标记语言 : 由标签构成的语言 HTML的标签都是预定好的, 如<a> </a> 为超链接 HTML代码直接在浏览器中运行,由浏览器内核进行解…

【算法设计与分析】基于Go语言实现贪心法解决TSP问题

一、前言 本文以上文动态规划法为基础按照相似的输入来完成编程。 二、代码思路 因为是贪心法&#xff0c;直接去找离目前正在遍历的点最近的点&#xff0c;因此输入了一个二维矩阵&#xff0c;咱们还需要设置一个一维数组来存/检验是否遍历过点&#xff0c;遍历过就不要再算了…

【明道云】如何在发送邮件模块给出多条记录形成的列表

【背景】 在完成批量分别发送邮件给不同部门担当的任务后,作为主管部门的用户希望能够获得成功得到处理的所有记录信息。这些信息需要在提醒邮件中以表格形式呈现。 【分析】 获得多条记录的方法能够拿到数据,问题在于如何合适地以表格形式呈现在邮件中。 只有富文本支持表…

开发Windows应用程序的多种工具和语言

在软件开发领域&#xff0c;Windows应用程序的开发是一个广泛而多样化的领域。开发者可以利用各种工具和编程语言来创建功能丰富、用户友好的应用程序。以下是一些常见的开发环境和编程语言&#xff0c;它们被广泛用于开发Windows应用程序。 Visual Studio&#xff1a;微软的集…

【考研数据结构知识点详解及整理——C语言描述】第二章 线性表链式存储结构上的基本操作——单链表的初始化

25计算机考研&#xff0c;数据结构知识点整理&#xff08;内容借鉴了王道408&#xff0b;数据结构教材&#xff09;&#xff0c;还会不断完善所整理的内容&#xff0c;后续的内容也会不断更新&#xff08;可以关注&#xff09;&#xff0c;若有错误和不足欢迎各位朋友指出! 一.…

mysql中的模糊匹配

在MySQL中,模糊查询通常使用 LIKE 运算符和通配符来实现。模糊查询用于匹配满足特定模式的字符串,可以在字符串中使用通配符进行搜索。以下是关于MySQL模糊查询的详细介绍: LIKE 运算符 LIKE 运算符用于在WHERE子句中搜索列中的指定模式。可以使用两种通配符: %:表示零个…

UVa11604 General Sultan

UVa11604 General Sultan 题目链接题意分析AC 代码 题目链接 UVA - 11604 General Sultan 题意 给出一些0和1组成的模式串&#xff0c;问是否存在一个串使得有多种方案将这个串分解成模式串。    给一个包含n&#xff08;n≤100&#xff09;个符号的二进制编码方式&#xff…

【计算机毕设】基于SpringBoot的医院管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个基于SpringBoot的医院管理系统&#xff0c;以提高医院管理效率&#xff0c;优化医疗服务流程&#xff0c;提升患者就诊体验…