概要
使用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设备的具体地址,找不到就是硬件存在问题
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/watch361/article/details/140133778
|