GD32F303采取IIC通讯情况下,未知设备ID,轮询得到当前设备ID

概要

使用GD32开发板,测试一个未知的USB设备时,时钟线始终没有数据,那么想采取轮询的方式反过来测试ID

整体架构流程

简单来说,就是通过寄存器标志位来判断是否有数据返回,如果没返回的话延时一段时间,地址增加继续发送,如果存在数据,那么记录地址
累加地址I2C 从00-7F,因为I2C通讯最大地址只有7F。

具体代码

主程序

int main(void)
{
    rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);//设置主频120M(#define __SYSTEM_CLOCK_120M_PLL_HXTAL           (uint32_t)(120000000),8M外部晶振  (#define HXTAL_VALUE    ((uint32_t)8000000))
	systick_config();//1ms systick
	rcu_periph_clock_enable(RCU_AF); //AF时钟使能 
	delay_1ms(1000);//等待1000ms
    rcu_periph_clock_enable(RCU_GPIOB);//GPIOB时钟使能
	gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//PB10要配置成I2C1 SCL,PB11要配置成I2C1 SDA
    rcu_periph_clock_enable(RCU_I2C1);
	i2c_config();
	delay_1ms(180);
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */


  while (1)
  {
		delay_1ms(180);//等待180ms
		BH170_ReadData(DataBuff);//读取数据	
		
	}	  
}



I2C初始化

#define I2C1_SLAVE_ADDRESS7    0x00
void i2c_config(void)
{
    /* configure I2C1 clock */
    i2c_clock_config(I2C1, 100000, I2C_DTCY_2);
    /* configure I2C1 address */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}

具体BH170_ReadData函数

unsigned char errorflag1=0;
unsigned char errorflag2=0;
	uint8_t  trueAddress=0;

#define I2C_SLAVE_ADDR_START   0x01
#define I2C_SLAVE_ADDR_END     0xFF  // ???7????0x7F

uint8_t currentSlaveAddress = I2C_SLAVE_ADDR_START;
 uint32_t timeout=1000;
void BH170_ReadData(unsigned char*Read)
{

	
	 /* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    /* send slave address to I2C bus */
    i2c_master_addressing(I2C1, currentSlaveAddress, I2C_RECEIVER);
    /* disable ACK before clearing ADDSEND bit */
    i2c_ack_config(I2C1, I2C_ACK_DISABLE);
    /* wait until ADDSEND bit is set */
    while (!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND) &&timeout--) {}

    if (timeout == 0xFFFFFFFF) {
//        // Handle timeout condition (optional)
//        // Optionally return an error or take appropriate action
       errorflag1=1;       
			
    }
	
		else
		{
		  	trueAddress=currentSlaveAddress;
		}
			timeout=1000;

    /* clear ADDSEND bit */
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    /* Wait until the last data byte is received into the shift register */
    /* wait until the RBNE bit is set */
    /* Wait until the RBNE bit is set or timeout occurs */
    while (!i2c_flag_get(I2C1, I2C_FLAG_RBNE) && timeout--) {
    // Add delay or other necessary operations here if needed
    }

    if (timeout == 0xFFFFFFFF) {
    // Handle timeout condition
    errorflag2 = 1;  // Set error flag or take appropriate action
    }
			else
		{
		  	trueAddress=currentSlaveAddress-1;
		}
		timeout=1000;

    /* read a data from I2C_DATA */
    Read[0] = i2c_data_receive(I2C1);

    /* read a data from I2C_DATA */
    Read[1] = i2c_data_receive(I2C1);
		
		Read[2] = i2c_data_receive(I2C1);

    /* read a data from I2C_DATA */
    Read[3] = i2c_data_receive(I2C1);
    /* send a stop condition */
    i2c_stop_on_bus(I2C1);
		
		currentSlaveAddress++;
		if(currentSlaveAddress>0x7F)
		{
		currentSlaveAddress=00;
		}

	
}

在keil或者其他编译器查看,trueAddress就是找到的i2c设备的具体地址,找不到就是硬件存在问题

GD32F130是一款基于ARM Cortex-M4的微控制器,支持I2C通信作为从设备。在GD32F130上实现I2C从机功能通常涉及以下几个步骤: 1. **初始化I2C模块**: 首先需要配置I2C端口的工作模式,设置时钟速率,以及指定自己作为从设备。 ```c void i2c_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; // ... (这里设置GPIO用于I2C数据线) GPIO_InitStructure.GPIO_Pin = ...; // 数据线和其他所需的GPIO引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(I2C_GPIO_Port, &GPIO_InitStructure); // ... (这里设置I2C时钟频率) I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x07; HAL_I2C_Init(&hi2c1, &I2C_InitStructure); HAL_I2C_MasterConfigEx(&hi2c1, I2C_SlaveMode, &I2C_InitStructure); } ``` 2. **设置中断处理程序**: 指定当收到起始信号或读取、写入完成时触发的回调函数。 ```c void MX_I2C1_IRQHandler(void) { HAL_I2C_MasterHandleEvent(&hi2c1); } ``` 3. **主从设备交互**: 当接收到主机的数据时,可以读取并响应;如果需要发送数据,通过`HAL_I2C_Master_Transmit()`或`HAL_I2C_Master_Receive()`进行。 ```c void handle_i2c_data(uint8_t* data, uint16_t length) { if (length > 0) { HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADDRESS, data, length, timeout); // ... 处理接收或错误情况 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级馒头神

看看谁给我第一个打赏。太感谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值