[STM32U3] 【STM32U385RG 测评】5、做为I2C slave与CH347通讯
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-8import osimport timefrom ctypes import *class USBI2C():ch347 = windll.LoadLibrary("./CH347DLLA64.dll")def __init__(self, usb_dev = 0, i2c_dev = 0x30):self.usb_id = usb_devself.dev_addr = i2c_devUSBI2C.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_addrUSBI2C.ch347.CH347StreamI2C(self.usb_id, 1, rec, 9, ibuf)USBI2C.ch347.CH347CloseDevice(self.usb_id)return ibufelse:print("USB CH347 Open Failed!")return 0def 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_addrfor i in range (size):tcmd[i+1] = cmd[i] & 0xffprint(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上位机





。
---------------------
作者:sujingliang
链接:https://bbs.21ic.com/icview-3471916-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。
更多推荐


所有评论(0)