CH347读写SPI Flash

CH347读写SPI Flash

前面耽搁了几天,今天终于把CH347 SPI接口调试好了。

CH347动态库中SPI接口函数如下:

typedef struct _SPI_CONFIG{UCHAR           iMode;                 // 0-3:SPI Mode0/1/2/3UCHAR           iClock;                // 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz, 4=3.75MHz, 5=1.875MHz, 6=937.5KHz,7=468.75KHzUCHAR			iByteOrder;            // 0=LSB first(LSB), 1=MSB first(MSB)USHORT          iSpiWriteReadInterval; // The SPI interface routinely reads and writes data command, the unit is uSUCHAR           iSpiOutDefaultData;    // SPI prints data by default when it reads dataULONG			iChipSelect;           // Piece of selected control, if bit 7 is 0, slice selection control is ignored, if bit 7 is 1, the parameter is valid: bit 1 bit 0 is 00/01 and CS1/CS2 pins are selected as low level active chip options respectivelyUCHAR           CS1Polarity;           // Bit 0: CS1 polarity control: 0: effective low level; 1: effective lhigh level;UCHAR           CS2Polarity;           // Bit 0: CS2 polarity control: 0: effective low level; 1: effective lhigh level;USHORT          iIsAutoDeativeCS;      // Whether to undo slice selection automatically after the operation is completeUSHORT          iActiveDelay;          // Set the latency for read/write operations after slice selection,the unit is usULONG           iDelayDeactive;        // Delay time for read and write operations after slice selection is unselected,the unit is us
}mSpiCfgS,*mPSpiCfgS;/***************SPI********************/
// SPI Controller Initialization
BOOL	WINAPI	CH347SPI_Init(ULONG iIndex,mSpiCfgS *SpiCfg);// Get SPI controller configuration information
BOOL    WINAPI  CH347SPI_GetCfg(ULONG iIndex,mSpiCfgS *SpiCfg);// Before setting the chip selection status, call CH347SPI_Init to set CS
BOOL	WINAPI	CH347SPI_ChangeCS(ULONG			iIndex,         // Specify device number	UCHAR         iStatus);       // 0=Cancel the piece to choose,1=Set piece selected// Set SPI slice selection
BOOL	WINAPI	CH347SPI_SetChipSelect(ULONG			iIndex,            // Specify device numberUSHORT           iEnableSelect,     // The lower octet is CS1 and the higher octet is CS2. A byte value of 1= sets CS, 0= ignores this CS settingUSHORT           iChipSelect,       // The lower octet is CS1 and the higher octet is CS2. A byte value of 1= sets CS, 0= ignores this CS settingULONG            iIsAutoDeativeCS,  // The lower 16 bits are CS1 and the higher 16 bits are CS2. Whether to undo slice selection automatically after the operation is completeULONG            iActiveDelay,      // The lower 16 bits are CS1 and the higher 16 bits are CS2. Set the latency of read/write operations after chip selection, the unit is usULONG            iDelayDeactive);   // The lower 16 bits are CS1 and the higher 16 bits are CS2. Delay time for read and write operations after slice selection the unit is us//SPI4 write data
BOOL	WINAPI	CH347SPI_Write(ULONG			iIndex,          // Specify device number	ULONG			iChipSelect,     // Slice selection control, when bit 7 is 0, slice selection control is ignored, and when bit 7 is 1, slice selection operation is performedULONG			iLength,         // Number of bytes of data to be transferred	ULONG			iWriteStep,      // The length of a single block to be readPVOID			ioBuffer);       // Point to a buffer to place the data to be written out from MOSI//SPI4 read data. No need to write data first, the efficiency is higher than that of the CH347SPI_WriteRead
BOOL	WINAPI	CH347SPI_Read(ULONG			iIndex,           // Specify device numberULONG			iChipSelect,      // Slice selection control, when bit 7 is 0, slice selection control is ignored, and when bit 7 is 1, slice selection operation is performedULONG         oLength,          // Number of bytes to sendPULONG		iLength,          // Number of bytes of data to be read inPVOID			ioBuffer);        // Points to a buffer that place the data to be written out from DOUT, return the data read in from DIN// Handle SPI data stream 4-wire interface
BOOL	WINAPI	CH347SPI_WriteRead(ULONG			iIndex,       // Specify the device numberULONG			iChipSelect,  // Selection control, if the film selection control bit 7 is 0, ignore the film selection control bit 7 is 1 and operate the film selectionULONG			iLength,      // Number of bytes of data to be transferredPVOID			ioBuffer );   // Points to a buffer that place the data to be written out from DOUT, return the data read in from DIN//place the data to be written from MOSI, return the data read in from MISO
BOOL	WINAPI	CH347StreamSPI4(ULONG			iIndex,       // Specify the device numberULONG			iChipSelect,  // Film selection control, if bit 7 is 0, slice selection control is ignored.If bit 7 is 1, the parameter is valid:Bit 1 bit 0 is 00/01/10. Select D0/D1/D2 pins as low level active chip options respectivelyULONG			iLength,      // Number of bytes of data to be transferredPVOID			ioBuffer );   // Points to a buffer, places data to be written out from DOUT, and returns data to be read in from DIN

要实现SPI通信,至少要用到CH347SPI_Init(ULONG iIndex,mSpiCfgS *SpiCfg) CH347SPI_Write(ULONG iIndex, ULONG iChipSelect, ULONG iLength, ULONG iWriteStep, PVOID ioBuffer) CH347SPI_Read(ULONG iIndex, ULONG iChipSelect, ULONG oLength, PULONG iLength, PVOID ioBuffer)这3个函数。

对这3个函数进行封装:

class SPIConfig(ctypes.Structure):_fields_ = [("iMode", ctypes.c_ubyte),                      # 0-3: SPI Mode0/1/2/3("iClock", ctypes.c_ubyte),                     # 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz,("iByteOrder", ctypes.c_ubyte),                 # 4=3.75MHz, 5=1.875MHz, 6=937.5KHz, 7=468.75KHz("iSpiWriteReadInterval", ctypes.c_ushort),     # Regular interval for SPI read/write commands, in microseconds("iSpiOutDefaultData", ctypes.c_ubyte),         # Default output data when reading from SPI("iChipSelect", ctypes.c_ulong),                # Chip select control. Bit 7 as 0 ignores chip select control,# Bit 7 as 1 makes the parameters valid:# Bit 1 and Bit 0 as 00/01 selects CS1/CS2 pin as the active low chip select.("CS1Polarity", ctypes.c_ubyte),                # Bit 0: CS1 polarity control, 0: active low, 1: active high("CS2Polarity", ctypes.c_ubyte),                # Bit 0: CS2 polarity control, 0: active low, 1: active high("iIsAutoDeativeCS", ctypes.c_ushort),          # Automatically de-assert chip select after the operation is completed("iActiveDelay", ctypes.c_ushort),              # Delay time for executing read/write operations after chip select is set, in microseconds("iDelayDeactive", ctypes.c_ulong)              # Delay time for executing read/write operations after chip select is de-asserted, in microseconds]def spi_init(self, device_index: int, spi_config: SPIConfig) -> bool:"""Initialize the SPI Controller.Args:device_index (int): The device number.spi_config (SPIConfig): The configuration for the SPI controller.Returns:bool: True if initialization is successful, False otherwise."""result = self.ch347dll.CH347SPI_Init(device_index, ctypes.byref(spi_config))return resultdef spi_write(self, device_index: int, chip_select: int, write_data: bytes, write_step: int = 512) -> bool:"""SPI write data.Args:device_index (int): Device number.chip_select (int): Chip selection control. When bit 7 is 0, chip selection control is ignored.When bit 7 is 1, chip selection operation is performed.write_data (bytes): Data to write.write_step (int, optional): The length of a single block to be read. Default is 512.Returns:bool: True if successful, False otherwise."""write_length = len(write_data)write_buffer = ctypes.create_string_buffer(write_data)result = self.ch347dll.CH347SPI_Write(device_index, chip_select, write_length, write_step, write_buffer)return resultdef spi_read(self, device_index: int, chip_select: int, write_data: bytes, read_length: int) -> bytes:"""SPI read data.Args:device_index (int): Device number.chip_select (int): Chip selection control. When bit 7 is 0, chip selection control is ignored.When bit 7 is 1, chip selection operation is performed.write_data (bytes): Data to write.read_length (int): Number of bytes to read.Returns:bytes: Data read in from the SPI stream if successful, None otherwise."""write_length = len(write_data)# Create ctypes buffer for write datawrite_buffer = ctypes.create_string_buffer(write_data)# Create ctypes buffer for read dataread_buffer = ctypes.create_string_buffer(read_length)# Create combined buffer for read and write datacombined_buffer = ctypes.create_string_buffer(write_buffer.raw[:write_length] + read_buffer.raw)result = self.ch347dll.CH347SPI_Read(device_index, chip_select, write_length, ctypes.byref(ctypes.c_ulong(read_length)), combined_buffer)if result:# Extract the read data from the combined bufferread_data = combined_buffer[:read_length]return bytes(read_data)else:return None

连接CH347和SPI Flash模块:

连接CH347和SPI Flash模块

上图中,红色LED的是W25Q32FV SPI Flash模块,绿色LED的是MPU6050。

编写测试代码:

import ch347dll_path = "ch347dlla64.dll"  # Replace with the actual path to the DLL
device_index = 0  # Set the device index according to your requirementsch347_driver = ch347.CH347Driver(dll_path)result = ch347_driver.open_device(device_index)
if result:print(f"Successfully opened device index: {device_index}")
else:print(f"Failed to close device index: {device_index}")spi_config = ch347.SPIConfig(iMode = 0,iClock = 0,iByteOrder = 1,iSpiWriteReadInterval = 0,iSpiOutDefaultData = 0,iChipSelect = 0x80,CS1Polarity = 0,CS2Polarity = 0,iIsAutoDeative = 1,iActiveDelay = 0,iDelayDeactive = 0
)
result = ch347_driver.spi_init(device_index, spi_config)
if result:print("Success to init SPI.")
else:print("Failed to init SPI.")# 读制造商数据
read_data = ch347_driver.spi_read(device_index, 0x80, b"\x90\x00\x00\x00", 2)
print(read_data)# 读 0x000000 4个字节
read_data = ch347_driver.spi_read(device_index, 0x80, b"\x03\x00\x00\x00", 4)
print(read_data)# 写 0x000000 2个字节 0x01 0x02
ch347_driver.spi_write(device_index, 0x80, b'\x06')
ch347_driver.spi_write(device_index, 0x80, b'\x02\x00\x00\x00\x01\x02')# 读 0x000000 4个字节
read_data = ch347_driver.spi_read(device_index, 0x80, b"\x03\x00\x00\x00", 4)
print(read_data)# Example usage of CH347CloseDevice
result = ch347_driver.close_device(device_index)
if result:print(f"Successfully closed device index: {device_index}")
else:print(f"Failed to close device index: {device_index}")

运行一下:

❯ python testSPI.py
Successfully opened device index: 0
Success to init SPI.
b'\xef\x15'
b'\xff\xff\xff\xff'
b'\x01\x02\xff\xff'
Successfully closed device index: 0

至此就可以读写SPI Flash了。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

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

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

相关文章

【数据库】形式化关系查询语言(一):关系代数Relational Algebra

目录 一、关系代数Relational Algebra 1. 基本运算 a. 选择运算(Select Operation) b. 投影运算(Project Operation) 组合 c. 并运算(Union Operation) d. 集合差运算(Set Difference Op…

python: 用百度API读取增值税发票信息

# encoding: utf-8 # 版权所有 2023 涂聚文有限公司 # 许可信息查看: # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 311 # Datetime : 2023/9/30 6:56 # User : geovindu # Product : PyCharm # Proj…

机器学习笔记 - 基于强化学习的贪吃蛇玩游戏

一、关于深度强化学习 如果不了解深度强化学习的一般流程的可以考虑看一下下面的链接。因为这里的示例因为在PyTorch 之上实现深度强化学习算法。 机器学习笔记 - Deep Q-Learning算法概览深度Q学习是一种强化学习算法,它使用深度神经网络来逼近Q函数,用于确定在给定状态下采…

架构设计第七讲:数据巡检系统之daily线上表结构自动化比对

架构设计第七讲:数据巡检系统之daily&线上表结构自动化比对 本文是架构设计第七讲,数据巡检系统之daily&线上表结构自动化比对,避免正式环境与测试环境数据库/表、列结构不一致带来问题。 文章目录 架构设计第七讲:数据巡…

193419-86-2,用于蛋白电泳检测的Fluorescein o-acrylate

产品简介:Fluorescein o-acrylate 中FITC具有荧光素衍生物的普遍特性,FITC也经常被用于蛋白电泳检测和荧光能量激发转移测试。 荧光染料及其荧光标记技术一直是生物领域常用的产品和技术,荧光物质是指具有共轭双键体系化学结构的化合物&…

LabVIEW开发实时自动化多物镜云计算全玻片成像装置

LabVIEW开发实时自动化多物镜云计算全玻片成像装置 数字病理学领域正在迅速发展,这主要是由于计算机处理能力、数据传输速度、软件创新和云存储解决方案方面的技术进步。因此,病理科室不仅将数字成像用于图像存档等简单任务,还用于远程病理学…

monkeyrunner录制脚本和回放

Monkeyrunner关于使用录制、生成脚本、编译脚本及执行脚本。 首先在计算机上下载和安装SDK、python 2.将recorder.py文件放置SDK文件夹里tools文件夹下 3.USB连接手机,手机端,开启USB调试,并在计算机DOS中输入adb devices命令,查看…

K8S-CNI

CNI的设计思想即为:Kubernetes在启动Pod的pause容器之后,直接调用CNI网络插件,从而实现为Pod内部应用容器月在的Network Namespace配置符合预期的网络信息。 这里面需要特别关注两个方面:Container必须有自己的网络命名空间的环境,也就是end…

go mod tidy 报错:x509: certificate signed by unknown authority 最佳实践

最近在docker中运行了一个ubuntu20的系统,在上面运行golang程序,使用go mod tidy后报错: tls: failed to verify certificate: x509: certificate signed by unknown authority 如: go: finding module for package google.gol…

Java:使用 Graphics2D 类来绘制图像

目录 过程介绍创建一个 BufferedImage 对象创建一个 Graphics2D 对象绘制字符和干扰线将生成的图像保存到文件 示例代码 过程介绍 创建一个 BufferedImage 对象 首先创建一个 BufferedImage 对象来表示图像 创建一个 Graphics2D 对象 然后使用 createGraphics() 方法创建一…

XXE 漏洞及案例实战

文章目录 XXE 漏洞1. 基础概念1.1 XML基础概念1.2 XML与HTML的主要差异1.3 xml示例 2. 演示案例2.1 pikachu靶场XML2.1.1 文件读取2.1.2 内网探针或者攻击内网应用(触发漏洞地址)2.1.4 RCE2.1.5 引入外部实体DTD2.1.6 无回显读取文件 3. XXE 绕过3.1 dat…

网络爬虫--伪装浏览器

从用户请求的Headers反反爬 在访问某些网站的时候,网站通常会用判断访问是否带有头文件来鉴别该访问是否为爬虫,用来作为反爬取的一种策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资…

Go语言strings标准库

strings包 参考资料 常用函数 函数功能备注EqualFold(s, t string) bool判断两个utf-8编码字符串(将unicode大写、小写、标题三种格式字符视为相同)是否相同。HasPrefix(s, prefix string) bool判断s是否有前缀字符串prefixHasSuffix(s, suffix strin…

【Leetcode】 501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义&#xf…

【图论C++】树的重心——教父POJ 3107(链式前向星的使用)

》》》算法竞赛 /*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在竞赛算法学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记:转载…

K8S:pod控制器详解

文章目录 一.pod控制器的基础1.pod概念及分类2.什么是Pod控制器及其功用3.pod控制器有多种类型(1)ReplicaSet(2)Deployment(3)DaemonSet(4)Statef…

css调整字体间距 以及让倾斜字体

调整字体间距 .element {letter-spacing: 2px; /* 调整为适当的值 */ }倾斜字体1 .element {font-style: italic; }请注意&#xff0c;不是所有的字体都有斜体样式可用。如果字体本身没有斜体版本&#xff0c;则可能无法实现完全的斜体效果。 倾斜字体2 <span class"…

python time和datetime的常用转换处理

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了&#xff0c;直接在文末名片自取就可 一、time 1、…

第一部分:HTML5

目录 一&#xff1a;网页 1.1&#xff1a;什么是网页&#xff1f; 1.2&#xff1a;什么是HTML&#xff1f; 1.3&#xff1a;网页的形成 二&#xff1a;常用浏览器 三&#xff1a;Web标准 3.1&#xff1a;为什么需要Web标准&#xff1f; 3.2&#xff1a;Web标准的构成 四&a…

自动群发节日祝福,1 行 Python 代码搞定,小白可用

想了解更多精彩内容&#xff0c;快来关注程序员晚枫 大家节日快乐&#xff0c;这里是程序员晚枫&#xff0c;小红薯也叫这个名字。 今天给大家分享一个实用功能&#xff1a;自动群发祝福消息。 我相信社会人都体会过&#xff0c;过年过节给别人群发祝福消息的无奈&#xff0…