蓝牙BLE芯片PHY6222之I2C主从通信

本文围绕PHY6222开发板的I2C开发展开。介绍了开发环境,包括开发板、SDK版本及路径、硬件连接。阐述了I2C主机和从机相关内容,特别指出PHY6222硬件I2C读写sensor时地址自动左移问题。还给出了注意事项,如主从机共地、上拉电阻等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蓝牙BLE芯片PHY6222之I2C主从通信

开发环境

1.PHY6222开发板
2.SDK版本以及路径:SDK\release_bbb_sdk-PHY62XX_SDK_3.0.9\example\peripheral\gpio
3.硬件连接
SDA  GPIO_P33----------GPIO_33
CLK  GPIO_P34----------GPIO_34
     GND----------GND

I2C主机

		//初始化
		hal_gpio_pin_init(I2C_MASTER_SDA,IE);
		hal_gpio_pin_init(I2C_MASTER_CLK,IE);
		hal_gpio_pull_set(I2C_MASTER_SDA,STRONG_PULL_UP);
		hal_gpio_pull_set(I2C_MASTER_CLK,STRONG_PULL_UP);
		hal_i2c_pin_init(I2C_0, I2C_MASTER_SDA, I2C_MASTER_CLK);
		//使用I2C0,100K的频率,主机地址0x10
		master_pi2c=hal_i2c_init(I2C_0,I2C_CLOCK_100K);//I2C_CLOCK_400K);
		if(master_pi2c==NULL)
		{
		    LOG("I2C master init fail\n");
		}
		else
		{
			LOG("I2C master init OK\n");
		}	
		//每3秒向从机发送一次数据
		osal_start_reload_timer(key_TaskID, KEY_I2C_READ_DATA_EVT, 3000);

---------------------------------------------------------------------------------------
//事件处理函数,从机地址slave_i2c_addr为0x20
	  if( events & KEY_I2C_READ_DATA_EVT)
    {
            int res;
			static int i=0;
			i++;
			LOG("i==%d\n",i);
			res=I2CWrite(master_pi2c,I2C_TX_data,I2C_MASTER_SEND_DATA_LEN,slave_i2c_addr);
			if(res==PPlus_SUCCESS)
				LOG("I2C  Master  send data   ok\n");
        return (events ^ KEY_I2C_READ_DATA_EVT);
    }

I2C从机

	//从机初始化
	hal_gpio_pin_init(I2C_SLAVE_SDA,IE);
	hal_gpio_pin_init(I2C_SLAVE_CLK,IE);
	hal_gpio_pull_set(I2C_SLAVE_SDA,STRONG_PULL_UP);
	hal_gpio_pull_set(I2C_SLAVE_CLK,STRONG_PULL_UP);

	I2C_Slave_Init();
{
	I2C_Slave_Parameter *I2C_Slave_cfg = (I2C_Slave_Parameter *)osal_mem_alloc(sizeof(I2C_Slave_Parameter));
	osal_memset(I2C_Slave_cfg,0,sizeof(I2C_Slave_Parameter));
	
	// config i2c slave parameter
	I2C_Slave_cfg->id = I2C_Slave_Module;
	I2C_Slave_cfg->workmode = Slave;
	I2C_Slave_cfg->AddressMode = I2C_ADDR_7bit;
	//从机中断源
	I2C_Slave_cfg->IRQ_Source = (I2C_MASK_TX_ABRT | I2C_MASK_RD_REQ | I2C_MASK_RX_FULL | I2C_MASK_RX_DONE |I2C_MASK_RX_UNDER);//| I2C_TX_EMPTY_Evt);
	I2C_Slave_cfg->RX_FIFO_Len = I2C_RX_TL_CNT;
	I2C_Slave_cfg->Tx_FIFO_Len = I2C_TX_TL_CNT;
	I2C_Slave_cfg->Slave_Address =0x20;//0x20;// chendy add 20200909 I2C_IC_DEFAULT_ADDR;
	I2C_Slave_cfg->SCL_PIN = I2C_SLAVE_CLK;
	I2C_Slave_cfg->SDA_PIN = I2C_SLAVE_SDA;
	I2C_Slave_cfg->evt_handler = hal_i2c_slave_evt_hdl;
	
	ret = Hal_I2C_Slave_Init(I2C_Slave_cfg,&I2C_Slave_Handle);
	if( ret != PPlus_IIC_SUCCESS )
	{
		I2C_Slave_Handle = PPlus_INVALID_HANDLE;
		LOG("I2C Slave Init Failure %d \n",ret);
	}
	else
	{

		LOG("I2C Slave Init Success111 , handle:%d \n",I2C_Slave_Handle);
	}

	osal_mem_free(I2C_Slave_cfg);
}	

//从机中断处理
void hal_i2c_slave_evt_hdl(I2C_Evt_t *pev)
{
	uint16_t conn_hdl;

	LOG("i2c s handle type=%x,len=%x\n",pev->type,pev->len);
	
	switch(pev->type){
		case I2C_RX_UNDER_Evt:
			 //IC_RXFLR
		break;
		case I2C_RX_OVER_Evt:
		break;
		case I2C_RX_FULL_Evt:
			//I2C_slave_rx_handle(I2C_RX_TL_CNT);
		  hal_i2c_slave_rx_full_handler();
		  osal_set_event(key_TaskID,KEY_I2C_READ_DATA_EVT);
		break;
.........
	

特别需要注意的是:PHY6222的硬件I2C在读写sensor的时候地址会自动左移,意思是:比如sensor的地址是0x89,那此时读写数据传入的地址应该是0x44,01000100<<1 等于 10001000,最后一位是读写位;

注意事项

1.建议主从机要共地,且芯片外部SDA和CLK必须上拉电阻(提高驱动能力,我上拉的是4.7K电阻)
2.在jump_table.c里的 jump_table_base函数里加上I2C的中断申请
3.PHY6222作为主机读写sensor时(如SC7A20),不能单单从波形分析,注意sensor手册里规定相应的地址,同时是否与原理图相对应
4. CFG_SLEEP_MODE=PWR_MODE_NO_SLEEP 不然初始化完就进入睡眠了
5. 建议项目工程不能通信的时,可以拿此例程测试看对比是否是硬件,或者软件的主从某一方有问题

PS:个人学习笔记,仅供参考)
demo传送门
提取码:j4ny

实现效果如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值