打印
[STM32U3]

【STM32U385RG 测评】5、做为I2C slave与CH347通讯

[复制链接]
383|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 sujingliang 于 2025-7-19 11:12 编辑

I2C的实例位于:
STM32Cube_FW_U3_V1.2.0\Projects\NUCLEO-U385RG-Q\Examples\I2C
其中I2C_TwoBoards_MultiMasterIT_Master,I2C_TwoBoards_MultiMasterIT_Slave可以实现一对开发板进行I2C发送接收演示。
如果没有2个STM32U385RG开发板,可以用其他的STM32开发板代替,其他开发板也有这个2个示例,可以和STM32U385RG进行I2C通讯。

我将STM32U385RG做Slave,STM32H533RE做Master发现可以很容易实现两者的I2C通信实验。


于是想如果用CH347做Master,是否也可以和做为Slave的STM32U385RG进行I2C通信呢?

一、尝试HAL_I2C_Slave_Receive_IT失败了
然后发现竟然不行,也许是认知有限吧。

在I2C_TwoBoards_MultiMasterIT_Slave中采用的HAL_I2C_Slave_Receive_IT做为接收函数。
HAL_I2C_Slave_Receive_IT 设计用于简单的单次传输(主机发送数据后结束通信)。可能 CH347 的通信协议中包含了重复起始条件(Repeated Start)或连续传输(如先写后读),此函数无法自动处理,导致 Slave 无响应。

试了很多次,没有成功,还是放弃了。

二、使用HAL_I2C_Master_Seq_Receive_IT成功了
后来看了I2C_TwoBoards_RestartComIT这个示例,这个例子使用HAL_I2C_Master_Seq_Receive_IT做为接收函数,经过尝试发现可以实现和CH347通信。

1、CH347简介
CH347 是南京沁恒微电子(WCH)推出的一款高速USB总线转接芯片,支持 USB 转多协议串行接口,包括:
USB 转 I2C(主/从模式)、USB 转 SPI(主模式)、USB 转 异步串口(UART)、GPIO 控制
其中,
I2C 支持        - 主模式(Master)- 速率:标准模式(100kHz)、快速模式(400kHz)、高速模式(1MHz)


从已知的资料上看CH347支持I2C Master模式,所以STM32U385RG只能做为Slave


2、STM32U385RG软件部分

1)I2C初始化
速率:100khz
hi2c2.Instance = I2C2;
  hi2c2.Init.Timing = 0x0070123C;
  hi2c2.Init.OwnAddress1 = I2C_ADDRESS;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  {
    Error_Handler();
  }


2)启用监听模式
int main(void)
{
...
if(HAL_I2C_EnableListen_IT(&hi2c2) != HAL_OK)
    {
        Error_Handler();
    }
while(1)
{
}


3)地址匹配回调
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
        HAL_I2C_Slave_Seq_Receive_IT(&hi2c2, aRxBuffer, 10, I2C_FIRST_FRAME);
}


4)接收完成回调
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{

        printf("Received data: [%s]\r\n", aRxBuffer);
        
        if (hi2c2.State != HAL_I2C_STATE_READY) {
        HAL_I2C_DeInit(&hi2c2);
        HAL_I2C_Init(&hi2c2);
    }
        HAL_I2C_EnableListen_IT(&hi2c2);
}
在 RxCpltCallback 中强制复位 I2C,并重启监听模式

3、ch347 I2C Master发送部分

#! /usr/bin/env python
#coding=utf-8
import os
import time
from ctypes import *

class USBI2C():
    ch347 = windll.LoadLibrary("./CH347DLLA64.dll")
    def __init__(self, usb_dev = 0, i2c_dev = 0x30):
        self.usb_id   = usb_dev
        self.dev_addr = i2c_dev
        USBI2C.ch347.CH347I2C_Set(self.usb_id,4)
        if USBI2C.ch347.CH347OpenDevice(self.usb_id) != -1:
            USBI2C.ch347.CH347CloseDevice(self.usb_id)
        else:
            print("USB CH347 Open Failed!")
        

    def read(self):
        if USBI2C.ch347.CH347OpenDevice(self.usb_id) != -1:
            
            rec  = (c_byte * 1)()
            ibuf = (c_byte * 9)()
            rec[0] = self.dev_addr
            
            USBI2C.ch347.CH347StreamI2C(self.usb_id, 1, rec, 9, ibuf)
            USBI2C.ch347.CH347CloseDevice(self.usb_id)
            
            return ibuf
        else:
            print("USB CH347 Open Failed!")
            return 0

    def write(self,cmd,size):
        if USBI2C.ch347.CH347OpenDevice(self.usb_id) != -1:
            tcmd = (c_byte * (size + 1))()
            ibuf = (c_byte * 1)()
            tcmd[0] = self.dev_addr
            for i in range (size):
                tcmd[i+1] = cmd[i] & 0xff
                print(tcmd[i+1])
            
            USBI2C.ch347.CH347StreamI2C(self.usb_id,11,tcmd,1,ibuf)
            USBI2C.ch347.CH347CloseDevice(self.usb_id)
        else:
            print("USB CH347 Open Failed!")

if __name__ == "__main__":
    cmd = (c_byte * 10)(0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39)
    size = sizeof(cmd)
    q = USBI2C()
    while True:
        q.write(cmd,size)

        time.sleep(1) #1s
也可以利用沁恒提供的上位机


三、运行效果

1、使用PYTHON脚本


2、使用CH347上位机


使用特权

评论回复
沙发
LOVEEVER| | 2025-7-29 23:25 | 只看该作者
I2C_TwoBoards_RestartComIT这个示例很有必要

使用特权

评论回复
板凳
数码小叶| | 2025-8-1 10:23 | 只看该作者
沁恒官网提供的上位机能打开?我下载下来一直打不开。。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

147

帖子

3

粉丝