stm32之硬件SPI读写W25Q64存储器应用案例

系列文章目录

1. stm32之SPI通信协议
2. stm32之软件SPI读写W25Q64存储器应用案例
3. stm32之SPI通信外设


文章目录

  • 系列文章目录
  • 前言
  • 一、电路接线图
  • 二、应用案例代码
  • 三、应用案例代码分析
    • 3.1 基本思路
    • 3.2 相关库函数介绍
    • 3.3 MySPI模块
      • 3.3.1 模块初始化
      • 3.3.2 SPI基本时序单元模块


前言

提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔记,旨在学习记录,如有侵权请联系作者

本案例使用硬件SPI外设通信的方式实现了STM32与W25Q64 Flash存储器的通信,完成了常见的Flash存储器操作如读ID、页写、扇区擦除、读取数据等。


一、电路接线图

下图所示为W25Q64模块硬件接线图,左边是W25Q64模块作为从机,右边是stm32作为主机。本案例选用SPI1外设作为通信,经查阅引脚定义表可知,其中PA4对应主机的从机选择线SPI1_NSS连接到从机的CS引脚,PA5对应主机的时钟同步线SPI1_SCK连接到从机的CLK引脚,PA6对应主机的主机输入从机输出线SPI1_MISO连接到从机的DO引脚,PA7对应主机的主机输出从机输入线SPI1_MOSI连接到从机的DI引脚。最后,W25Q64模块的VCC和GND分别接到stm32的电源正负极进行供电。

在这里插入图片描述

二、应用案例代码

MySPI.h:

#ifndef __MYSPI_H
#define __MYSPI_Hvoid MySPI_Init(void);
void MySPI_Start(void);
void MySPI_Stop(void);
uint8_t MySPI_SwapByte(uint8_t ByteSend);#endif

MySPI.c:

#include "stm32f10x.h"                  // Device headervoid MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);MySPI_W_SS(1);
}void MySPI_Start(void)
{MySPI_W_SS(0);
}void MySPI_Stop(void)
{MySPI_W_SS(1);
}uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);SPI_I2S_SendData(SPI1, ByteSend);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);return SPI_I2S_ReceiveData(SPI1);
}

W25Q64_Ins.h:

#ifndef __W25Q64_INS_H
#define __W25Q64_INS_H#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3#define W25Q64_DUMMY_BYTE							0xFF#endif

W25Q64.h:

#ifndef __W25Q64_H
#define __W25Q64_Hvoid W25Q64_Init(void);
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID);
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count);
void W25Q64_SectorErase(uint32_t Address);
void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count);#endif

W25Q64.c:

#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_Ins.h"void W25Q64_Init(void)
{MySPI_Init();
}void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();MySPI_SwapByte(W25Q64_JEDEC_ID);*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);*DID <<= 8;*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);MySPI_Stop();
}void W25Q64_WriteEnable(void)
{MySPI_Start();MySPI_SwapByte(W25Q64_WRITE_ENABLE);MySPI_Stop();
}void W25Q64_WaitBusy(void)
{uint32_t Timeout;MySPI_Start();MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);Timeout = 100000;while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01){Timeout --;if (Timeout == 0){break;}}MySPI_Stop();
}void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_PAGE_PROGRAM);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >> 8);MySPI_SwapByte(Address);for (i = 0; i < Count; i ++){MySPI_SwapByte(DataArray[i]);}MySPI_Stop();W25Q64_WaitBusy();
}void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >> 8);MySPI_SwapByte(Address);MySPI_Stop();W25Q64_WaitBusy();
}void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{uint32_t i;MySPI_Start();MySPI_SwapByte(W25Q64_READ_DATA);MySPI_SwapByte(Address >> 16);MySPI_SwapByte(Address >> 8);MySPI_SwapByte(Address);for (i = 0; i < Count; i ++){DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);}MySPI_Stop();
}

main.c:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"uint8_t MID;
uint16_t DID;uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04};
uint8_t ArrayRead[4];int main(void)
{OLED_Init();W25Q64_Init();OLED_ShowString(1, 1, "MID:   DID:");OLED_ShowString(2, 1, "W:");OLED_ShowString(3, 1, "R:");W25Q64_ReadID(&MID, &DID);OLED_ShowHexNum(1, 5, MID, 2);OLED_ShowHexNum(1, 12, DID, 4);W25Q64_SectorErase(0x000000);W25Q64_PageProgram(0x000000, ArrayWrite, 4);W25Q64_ReadData(0x000000, ArrayRead, 4);OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);OLED_ShowHexNum(3, 3, ArrayRead[0], 2);OLED_ShowHexNum(3, 6, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);OLED_ShowHexNum(3, 12, ArrayRead[3], 2);while (1){}
}

完整工程:stm32之硬件SPI读写W25Q64存储器

三、应用案例代码分析

有了上一章节软件SPI的基础,那么我们只需要在原有的基础上将软件SPI的接口直接改写成硬件实现就行了,具体来说就是只需要修改MySPI_Init以及MySPI_SwapByte函数的内部实现即可,这就是模块化封装的好处。我们先来看一下SPI的硬件基本结构图。

在这里插入图片描述

3.1 基本思路

  • 第一步,开启时钟,使能SPI和GPIO时钟。
  • 第二步,初始化GPIO口,配置相应GPIO口的引脚模式。
  • 第三步,配置SPI外设,调用SPI_Init函数完成初始化配置。
  • 第四步,SPI使能,调用SPI_Cmd函数开启SPI外设。

以上就是SPI初始化函数的基本思路了,接下来我们只需要在上一章软件SPI通信模块的基础上进行修改即可,把软件实现的时序用硬件SPI接口替换掉。

3.2 相关库函数介绍

老规矩,还是先来看一下操作SPI外设的相关函数。找到stm32f10x_spi.h然后拉到最后,可以发现这里很多的函数都带了个I2S,因为SPI和I2S共用同一套电路,我们不需要使用I2S,直接当它不存在就行了。

其实学完了这么多的外设可以发现,很多东西都是一个套路,像下面这些函数都是经常见的了,不过是换了个外设的名称,功能都是差不多的,这里就简单讲一下就好了。

void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
  • SPI_I2S_DeInit,恢复缺省配置。
  • SPI_Init,SPI外设初始化。
  • SPI_StructInit,结构体变量初始化。
  • SPI_Cmd,SPI外设使能。
  • SPI_I2S_ITConfig,中断使能。
  • SPI_I2S_DMACmd,DMA使能。

接下来是SPI比较重要的两个函数,发送与接收一个字节函数

void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);

最后就是一些获取标志位和清除标志位的相关函数,我们主要会用到SPI_I2S_GetFlagStatus来获取TXE和RXNE标志位的状态,再配合写DR和读DR的函数就能控制时序的产生了。

FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

ok,库函数的介绍就到这里,下面我们就进入正题吧!Let ’s go !

3.3 MySPI模块

3.3.1 模块初始化

1. 开启时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

注意:SPI1是APB2侧的外设

2. 初始化GPIO口

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

其中SCK(PA5)和MOSI(PA7)是由硬件外设控制的输出信号,所以配置为复用推挽输出。MISO(PA6)是硬件外设的输入信号,我们可以配置为上拉输入(因为输入设备可以有多个,所以不存在复用输入这种东西,直接配置为上拉输入即,普通GPIO口能输入,外设也能输入)。最后还有SS(PA4)引脚,SS引脚是软件控制的输出信号,所以配置为通用推挽输出即可。

3. 配置SPI外设

SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

以下是关于SPI初始化配置各个参数的解析:

  • SPI_Mode:SPI的模式,这里选择SPI_Mode_Master,即SPI1 被配置为主设备。
  • SPI_Direction:这里选择SPI_Direction_2Lines_FullDuplex,SPI 工作在全双工模式。
  • SPI_DataSize:这里选择SPI_DataSize_8b,数据大小为 8 位。
  • SPI_FirstBit:这里选择为SPI_FirstBit_MSB,数据按最高有效位 (MSB) 先发送。
  • SPI_BaudRatePrescaler:这里选择为SPI_BaudRatePrescaler_128,SPI 时钟源频率被分频为 128。
  • SPI_CPOL:这里选择为SPI_CPOL_Low,空闲时钟极性SCK为低电平。
  • SPI_CPHA:这里选择为SPI_CPHA_1Edge,数据在第一个时钟边沿进行采样。
  • SPI_NSS:这里选择为SPI_NSS_Soft:NSS 信号通过软件控制,不使用硬件 NSS 管脚管理。
  • SPI_CRCPolynomial:这里选择为SPI_CRCPolynomial 设置为 7,虽然这里没有启用 CRC 校验,但必须指定一个多项式。

这里要注意一下的就是SPI_CPOL以及SPI_CPHA配置的是模式0。

4. SPI使能

SPI_Cmd(SPI1, ENABLE);

最后别忘了置SS为默认高电平状态,不选择从机。

MySPI_W_SS(1);

3.3.2 SPI基本时序单元模块

1. 起始与终止信号

void MySPI_Start(void)
{MySPI_W_SS(0);
}void MySPI_Stop(void)
{MySPI_W_SS(1);
}

这个跟软件SPI一样,SS引脚我们采用软件控制GPIO口的方式来进行控制。

2. 交换一个字节

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);SPI_I2S_SendData(SPI1, ByteSend);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);return SPI_I2S_ReceiveData(SPI1);
}

在这里我们使用的是SPI主模式全双工非连续传输的方式,这种传输方式的逻辑大概就是:

  • 第一步,等待TXE标志位为1,发送寄存器为空。
  • 第二步,写入DR,将数据写入TDR。
  • 第三步,等待RXNE标志位为1,接受寄存器非空。
  • 第四步,读取DR,从RDR中读取数据。

ok,到这里关于硬件SPI读写W25Q64存储器的分析就到这里了,剩下的还有W25Q64模块以及主程序代码逻辑的分析在软件SPI那一章已经详细地分析过了,这里就不再累述了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/423007.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01_Python基本语法

Hello Python 与其他编程一样&#xff0c;第一个程序都是输出Hello World!。 print("Hello World!")print() 函数由两部分构成 &#xff1a; 指令&#xff1a;print指令的执行对象&#xff0c;在 print 后面的括号里的内容 Hello World!。 Python程序的执行流程如…

机器学习中最常见的50个问题(进阶篇)

机器学习中最常见的50个问题 进阶篇 1.解释SVM的工作原理。 SVM&#xff0c;全称支持向量机&#xff08;Support Vector Machine&#xff09;&#xff0c;是一种有监督学习算法&#xff0c;主要用于解决数据挖掘或模式识别领域中的数据分类问题。 SVM的工作原理是建立一个最…

【排序算法】之基数排序

一、算法介绍 基数排序是一种非比较型整数排序算法&#xff0c;其原理是将整数按低位到高位或者高位到低位的顺序&#xff0c;依次根据每一位的数值进行排序。通常情况下&#xff0c;基数排序会使用桶排序来处理每一位上的数值。 实现方法主要有如下&#xff1a; 最高位优先(…

echarts实现湖南省地图并且定时轮询

1、在HTML页面引入echarts.min.js <script src"https://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js"></script> 2、实现代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"utf-8"><…

如何搞定日语翻译?试试这四款工具

写一篇字数800-1000字的软文&#xff0c;用翻译新手的角度分享福昕翻译在线、福昕翻译客户端、海鲸AI翻译以及彩云翻译在翻译日语时候的表现&#xff0c;要求口语化表达。 最近对于一些轻小说突然感兴趣了&#xff0c;所以我开始尝试各种翻译工具来帮助我搞定日语翻译。今天&am…

仕考网:省考面试流程介绍,提前了解

省考面试流程介绍&#xff0c;一文带大家了解! 一、面试登记及抽签 考生通常需要提前10至30分钟到达指定地点进行登记。 考试工作人员核对考生身份证和面试通知书等相关证件后&#xff0c;进行抽签确定分组和进场顺序。 二、候考阶段 考生完成抽签后进入候考区等待考试。在…

【LeetCode每日一题】2024年9月第二周(上)

2024.9.9 中等 难度评分 1333 链接&#xff1a;2181. 合并零之间的节点 &#xff08;1&#xff09;题目描述&#xff1a; &#xff08;2&#xff09;示例 &#xff08;3&#xff09;分析 整体来说&#xff0c;描述还算清晰的题目&#xff0c;找到0节点所框定的区域&#xff0c…

【iOS】UIViewController的生命周期

UIViewController的生命周期 文章目录 UIViewController的生命周期前言UIViewController的一个结构UIViewController的函数的执行顺序运行代码viewWillAppear && viewDidAppear多个视图控制器跳转时的生命周期pushpresent 小结 前言 之前对于有关于UIViewControlller的…

cesium.js 入门到精通(3)

天空盒子的设置 目前的地球背景 是 地图的cesium 我们想换成自己背景 // 设置天空盒skyBox: new Cesium.SkyBox({sources: {positiveX: "./texture/sky/px.jpg",negativeX: "./texture/sky/nx.jpg",positiveY: "./texture/sky/ny.jpg",negativ…

如何构建高效快速的数据同步策略方案

在数据化的商业环境中&#xff0c;实现数据的实时同步不仅是提升企业内部协作效率的关键&#xff0c;更是确保业务决策精准性和时效性的核心要素。通过确保数据的一致性和最新性&#xff0c;企业能够实现跨部门的无缝协作&#xff0c;从而为业务流程的顺畅运作和快速响应市场变…

Linux系统部署SmartKG(知识图谱安装)

基本要求 #docker需要高版本 Docker version 20.10.14, build a224086docker 20.10.14离线安装 SmartKG官网 官方详细文档 下载部署包 SmartKG官网 准备部署 #上传到服务器 [roottest-server01 opt]# ll SmartKG-master.zip -rw-r--r-- 1 root root 79708691 Sep 11 17:4…

k8s环境搭建(续)

查看节点信息并做快照 kubectl get nodes 将components.yml文件上传到master主机 创建nginx&#xff0c;会在添加一个新的pod kubectl run nginx --imagesnginx:latest 查看nginx的pod信息 [rootk8s-master ~]# kubectl get po -Aowide|grep nginx 出现错误&#xff0c;查…

跨越技术壁垒:EasyCVR为何选择支持FMP4格式,重塑视频汇聚平台标准

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;视频监控系统已经从传统的安防监控扩展到智慧城市、智能交通、工业制造等多个领域。视频流格式作为视频数据传输与存储的基础&#xff0c;其兼容性与效率直接影响到整个视频监控系统的性能。 在众多视频流格式中&#…

吴牧野与他的家首登国际家居杂志《安邸AD》秋季封面

国际钢琴艺术家吴牧野登国际一线家居杂志《安邸AD》金九秋季封面&#xff0c;首次在自己的私宅接受媒体拍摄访问&#xff0c;他的家也第一次曝光在公众面前。凭借深刻的音乐性、高超的琴技和高级感的气质&#xff0c;吴牧野打破了中国观众对钢琴家炫技派的刻板印象&#xff0c;…

携手科大讯飞丨云衔科技为企业提供全栈AI技术解决方案

作为智能时代的核心驱动力&#xff0c;人工智能不仅重塑了传统行业的面貌&#xff0c;更开辟了全新的经济增长点。科大讯飞以其深厚的技术底蕴和创新能力&#xff0c;持续引领着人工智能领域的发展潮流。云衔科技作为科大讯飞开放平台的AI技术产品线合作伙伴代理商&#xff0c;…

YOLOV8实现小目标检测

YOLOV8小目标检测 前言&#xff1a;&#xff1a; yolo版出现很多&#xff0c;基本大同小异 但是这些差异让我们考虑在实验中使用哪个版本会比较好&#xff01; 在对小目标检测的过程中&#xff0c;yolov7相比yolov8性能更加好。 如果我们还是想使用yolov8&#xff0c;也是可以实…

QImage、cv::Mat 与 HalconCpp::HObject 之间的转换

在机器视觉应用中&#xff0c;不同的图像处理库和框架常使用不同的数据结构来表示图像。常用的库包括 Qt 的 QImage、OpenCV 的 cv::Mat 以及 Halcon 的 HObject。为了在这些库之间实现无缝的数据传递和处理&#xff0c;图像格式的转换成为必不可少的环节。本文将详细介绍如何在…

再次进阶 舞台王者 第八季完美童模全球赛形象大使【许雅雯】赛场秀场超燃合集!

7月20-23日&#xff0c;2024第八季完美童模全球总决赛在青岛圆满落幕。在盛大的颁奖典礼上&#xff0c;一位才能出众的少女——许雅雯&#xff0c;迎来了她舞台生涯的璀璨时刻。 形象大使——许雅雯&#xff0c;以璀璨童星之姿&#xff0c;优雅地踏上完美童模盛宴的绚丽舞台&am…

玉米种子质量检测系统源码分享

玉米种子质量检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

掌握“问一问”策略,视频号流量轻松实现质的飞跃!

掌握“问一问”策略&#xff0c;视频号流量轻松实现质的飞跃&#xff01; 视频号新流量入口&#xff0c;微信问一问。如何玩转问一问功能&#xff0c;手把手操作教学。#视频号#微信#问一问#短视频#直播 市面上还有这么牛逼的一个流量隐藏入口&#xff0c;先看一下数据&#x…