0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在QCC300x上实现I2C功能

蓝牙 来源:蓝牙 作者:蓝牙 2020-10-10 09:28 次阅读

本文主要介绍如何在QCC300x上实现I2C功能,只在空白工程上实现相关功能。所用的ADK版本为ADK_QCC300x.WIN.1.0.167。

此方法理论上同样适用于CSR8670/CSR8675。

本文实现的功能很简单,通过对IIC设备发起一个读写操作,从设备有ACK即可。因为如果实现了这个基本操作,后续的其他复杂操作就是怎么写代码的问题了。

将数据0x1234写入到芯片寄存器0x06和0x07中:

从寄存器0x06和0x07中读取:

这里先讲一下硬件,本次测试用的是官方的开发板,在开发板的P00和P01口上挂了一颗IC--TCA9555,它是一颗IO扩展芯片,IIC接口,所以,本次测试正好使用这颗芯片作为测试。

QCC300x的IIC默认配置为P00和P01,当然它也可以改成其他IO:

首先,建立一个空白工程,然后工程属性中有个地方需要改一下:

改Transport的原因是因为我们使用P00和P01作为I2C的接口,如果使用其他IO口,这个应该就不用改了。

然后,我们先烧录一下程序,这样它会擦除FLASH并对FLASH进行分区,然后再用pstool merge一下默认的psr程序(这个请参考之前文档)。然后用pstool改以下配置:

将I2C configuration改为“1”的目的是将IIC的速率切换到400kHz。

下面两个参数是配置I2C接口所对应的IO口的:

这些配置完毕后,保存pskey,然后,开始编写我们的代码。

代码也很简单,就一个main.c文档,代码内容如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MESSAGE_TX_DATA 0x4000

#define MESSAGE_RX_DATA 0x4001

#define I2C_DEVICE_ADDRESS (0x20<<1)

#define I2C_A_DEVICE_REGISTER 0x06

typedef struct

{

TaskData task;

}I2CTaskData;

I2CTaskData theI2CTaskData;

uint16 i2c_register_data;

static void I2CMessageHandler(Task pTask, MessageId pId,Message pMessage);

static void i2c_example_init(void);

static void i2c_write_16bit_device_register(uint8device_address, uint8 device_register, uint16 data);

static void i2c_read_16bit_device_register(uint8device_address, uint8 device_register, uint16 *data);

int main(void)

{

PRINT(("hello world. "));

i2c_example_init();

/* Start the message scheduler loop */

MessageLoop();

/* Never get here...*/

return 0;

}

void i2c_example_init(void)

{

/* Assign task message handler */

theI2CTaskData.task.handler = I2CMessageHandler;

/* Send MESSAGE_TX_DATA to the task */

MessageSendLater(&theI2CTaskData.task,MESSAGE_TX_DATA, 0, 2000);

/* Send MESSAGE_RX_DATA to the task */

MessageSendLater(&theI2CTaskData.task,MESSAGE_RX_DATA, 0, 1000);

}

void i2c_write_16bit_device_register(uint8device_address, uint8 device_register, uint16 data)

{

uint8 i2c_data[3];

i2c_data[0] = device_register;

i2c_data[1] = (data >> 8) & 0xFF;

i2c_data[2] = data & 0xFF;

/*

I2cTransfer(uint16 address, const uint8 *tx, uint16tx_len, uint8 *rx, uint16 rx_len)

If tx_len is non-zero and rx_len is zero then the sequencereduces to:

- Start condition (S).

- Write slave address and direction byte (address | 0).

- Write tx_len data bytes from the buffer at tx.

- Stop condition (P).

*/

/*I2cTransfer(device_address, i2c_data, 3, NULL, 0);*/

PanicZero(I2cTransfer(device_address, i2c_data, 3, NULL,0));

}

void i2c_read_16bit_device_register(uint8 device_address,uint8 device_register, uint16 *data)

{

uint8 i2c_data[1];

uint8 i2c_rx_data[2];

i2c_data[0] = device_register;

/*

I2cTransfer(uint16 address, const uint8 *tx, uint16tx_len, uint8 *rx, uint16 rx_len)

If tx_len is non-zero and rx_len is non-zero then thesequence is:

- Start condition (S).

- Write slave address and direction byte (address | 0).

- Write tx_len data bytes from the buffer at tx.

- Repeated start condition (Sr).

- Write slave address and direction byte (address | 1).

- Read rx_len bytes into the buffer at rx, acknowledgingall but the final byte.

- Stop condition (P).

*/

/*I2cTransfer(device_address, i2c_data, 1, i2c_rx_data,2);*/

PanicZero(I2cTransfer(device_address, i2c_data, 1,i2c_rx_data, 2));

*data = (i2c_rx_data[0] << 8) + i2c_rx_data[1];

}

void I2CMessageHandler(Task pTask, MessageId pId, MessagepMessage)

{

switch (pId)

{

case MESSAGE_TX_DATA:

/*将数据0x1234写入到寄存器0x06和0x07中*/

i2c_write_16bit_device_register(I2C_DEVICE_ADDRESS,I2C_A_DEVICE_REGISTER,0x1234);

/* Send MESSAGE_TX_DATA to the task */

MessageSendLater(&theI2CTaskData.task,MESSAGE_TX_DATA, 0, 1000);

break;

case MESSAGE_RX_DATA:

/*从寄存器0x06和0x07中读取之前写入的值*/

i2c_read_16bit_device_register(I2C_DEVICE_ADDRESS,I2C_A_DEVICE_REGISTER,&i2c_register_data);

/* Send MESSAGE_RX_DATA to the task */

MessageSendLater(&theI2CTaskData.task,MESSAGE_RX_DATA, 0, 2000);

break;

default:

break;

}

}

也没啥好讲的,直接贴到main.c中,做过嵌入式开发的人,几分钟内就能完全读懂了。跟I2C相关的其实就一个函数:

uint16 I2cTransfer(uint16 address, constuint8 *tx, uint16 tx_len, uint8 *rx, uint16 rx_len);

关于它的解释,可以参考API的说明。

这里再简单讲一下如何用I2cTransfer实现IIC的最基本的两个操作吧。

1.写:

I2cTransfer(device_address, i2c_data, 3, NULL, 0);

以上函数会往device_address的设备将i2c_data数组中的3个字节写入到iic外设中,i2c_data[0]为device_register,然后后面两个字节为数据内容:

i2c_data[0]= device_register;

i2c_data[1]= (data >> 8) & 0xFF;

i2c_data[2] = data & 0xFF;

2.读:

i2c_data[0]= device_register;

I2cTransfer(device_address,i2c_data, 1, i2c_rx_data, 2);

*data = (i2c_rx_data[0] << 8) + i2c_rx_data[1];

以上代码是从device_register位置读取两个字节的标准操作。

更多操作的话,可以参考前面提到的API说明。

最后,编译运行,就能得到文章一开始的结果了。
责任编辑:YYX

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    4778

    浏览量

    116566
  • IIC
    IIC
    +关注

    关注

    11

    文章

    270

    浏览量

    37470
  • I2C
    I2C
    +关注

    关注

    27

    文章

    1295

    浏览量

    119985

原文标题:【BAQ026A】QCC300x如何实现I2C通信

文章出处:【微信号:TalkBT,微信公众号:蓝牙】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    高通QCC300x系列蓝牙芯片应用常见问题的解达

    程序下载烧录,成功跑起来了。经过三周学习及调式,最终完成了客户demo的功能,交样机给客户去评估。现我遇见的部分问题及商家提供的解决 分享给大家,可以少走弯路。问:QCC300x可以做发射功能吗?类似于
    发表于 02-15 19:29

    NIOS实现I2C总线

    I2C 总线的实现关键是SDA,他是双向线,如果对与一个芯片只写而不读,I2C 实现起来很容易.使用NIOS 实现
    发表于 11-01 14:28 37次下载

    启动belasigna 300使用I2C接口的方法

    启动belasigna 300使用I2C接口 简介 本应用笔记介绍了如何引导belasigna 300通过I2C接口时,它不有一个EEPROM连接(即引导)。这当蓝牙或基带芯片出现情况
    发表于 03-31 10:38 25次下载

    硬件I2C与模拟I2C

    硬件I2C对应芯片I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的
    发表于 12-28 19:14 77次下载
    硬件<b class='flag-5'>I2C</b>与模拟<b class='flag-5'>I2C</b>

    I2C拉电阻设计

    I2C拉电阻 在一些PCB的layout中,大家往往会看到在I2C通信的接口处,往往会接入一个4.7K的电阻,有的datasheet上面明确有要求,需要接入,有的则没有要求。 I2C
    发表于 01-14 14:10 8次下载
    <b class='flag-5'>I2C</b><b class='flag-5'>上</b>拉电阻设计

    MM32F013x——I2C从机多地址应用

    I2C中,通信是借助设备地址寻址实现的,大致可以分为两类:一对多、多对多通信。在多主机通信时,从机如果想接收多个主机的数据,就需要使用到从机多地址的功能。本文是针对在MM32F013x
    发表于 02-08 17:10 3次下载
    MM32F013<b class='flag-5'>x</b>——<b class='flag-5'>I2C</b>从机多地址应用

    何在arduino中使用I2c LCD模块

    电子发烧友网站提供《如何在arduino中使用I2c LCD模块.zip》资料免费下载
    发表于 10-26 14:29 1次下载
    如<b class='flag-5'>何在</b>arduino中使用<b class='flag-5'>I2c</b> LCD模块

    使用 I2C 接口引导加载 BelaSigna® ​​300

    使用 I2C 接口引导加载 BelaSigna® ​​300
    发表于 11-15 20:21 0次下载
    使用 <b class='flag-5'>I2C</b> 接口引导加载 BelaSigna® ​​<b class='flag-5'>300</b>

    I2C扫描仪之如何在Arduino查找I2C地址

    电子发烧友网站提供《I2C扫描仪之如何在Arduino查找I2C地址.zip》资料免费下载
    发表于 01-31 10:19 1次下载
    <b class='flag-5'>I2C</b>扫描仪之如<b class='flag-5'>何在</b>Arduino<b class='flag-5'>上</b>查找<b class='flag-5'>I2C</b>地址

    何在Arduino中使用20x4 I2C字符LCD显示器

    电子发烧友网站提供《如何在Arduino中使用20x4 I2C字符LCD显示器.zip》资料免费下载
    发表于 06-28 15:57 0次下载
    如<b class='flag-5'>何在</b>Arduino中使用20<b class='flag-5'>x</b>4 <b class='flag-5'>I2C</b>字符LCD显示器

    何在I2C 128X32 OLED显示器滚动文本

    电子发烧友网站提供《如何在I2C 128X32 OLED显示器滚动文本.zip》资料免费下载
    发表于 06-28 15:59 0次下载
    如<b class='flag-5'>何在</b><b class='flag-5'>I2C</b> 128<b class='flag-5'>X</b>32 OLED显示器<b class='flag-5'>上</b>滚动文本

    用Verilog HDL实现I2C总线功能

    摘要: 简述了I2C总线的特点;介绍了开发FPGA时I2C总线模块的设计思想;给出并解释了用Verilog HDL实现部分I2C总线功能的程
    发表于 06-20 13:17 6509次阅读
    用Verilog HDL<b class='flag-5'>实现</b><b class='flag-5'>I2C</b>总线<b class='flag-5'>功能</b>

    MM32F013x实现I2C多地址的功能应用

    I2C中,通信是借助设备地址寻址实现的,大致可以分为两类:一对多、多对多通信。在多主机通信时,从机如果想接收多个主机的数据,就需要使用到从机多地址的功能。 本文是针对在MM32F013x
    发表于 01-05 11:43 1816次阅读

    什么是I2C通信协议?

    在本教程中,我们将学习如何在Raspberry Pi Pico中使用I2C引脚并遍历I2C扫描器代码。
    的头像 发表于 04-26 15:08 6648次阅读
    什么是<b class='flag-5'>I2C</b>通信协议?