Thread 中讨论的其他器件:CC2640、 SYSBIOS
你好。 从 Sensirion SCD30 I2C 传感器读取任何数据时遇到问题。 使用 i2ctmp 示例和 I2C.h 文件参考中的示例、 我已经成功连接 了一个 SHT30传感器和 CCS811传感器。 但是、我很难对 SCD30传感器执行相同的操作。
例如、 要读取 固件版本、我首先在 第一个 I2C 事务中发送"读取固件"命令0xD100、然后在第二个事务中读取2个字节(因为 SCD30不支持重复启动条件)。
但是、我 每次都会得到不正确的数据:
我已经使用 Arduino 测试了相同的传感器、它在那里工作正常。
我的问题:
最大 I2C 速度为100kHz、主器件必须支持时钟扩展。 Sensirion 建议以50kHz 或更低的波特率运行 SCD30。 写入帧和读取帧的时钟拉伸周期为30ms、但是、由于内部校准过程、最大时钟拉伸可达150ms、每天一次。 有关 I2C 协议的详细信息,请参阅 NXP I2C-bus 说明1。 SCD30不支持重复起始条件。 时钟拉伸是启动微控制器所必需的、并且可能在每次 ACK 前发生。 需要根据 NXP 规范实现 I2C 主时钟扩展。 启动时间< 2s
在时钟拉伸方面、我是否需要更改代码中的任何内容、例如更改任何时钟拉伸限制? 对于 CC2640的时钟扩展、我找不到任何东西。
否则、您还有其他建议吗?
我的代码以蓝色显示(仅用于读取固件版本):
/*
*版权所有(c) 2016-2017、德州仪器(TI)公司
*保留所有权利。
*
*以源代码和二进制形式重新分发和使用、有无
*如果满足以下条件、则允许进行修改
符合*:
*
**源代码的重新分发必须保留上述版权
*注意、此条件列表和以下免责声明。
*
**二进制形式的再发行必须复制上述版权
*请注意、中的此条件列表和以下免责声明
*随分发提供的文档和/或其他材料。
*
**德州仪器公司的名称和名称均不相同
*其贡献者可用于认可或推广衍生产品
*未经特定的事先书面许可。
*
*本软件由版权所有者和贡献者"按原样"提供
*以及任何明示或暗示的保证、包括但不限于:
*特定适销性和适用性的隐含保证
*不承认目的。 在任何情况下、版权所有者不得或
*派遣国应对任何直接、间接、偶然、特殊、
*典型或必然的损害(包括但不限于
*采购替代货物或服务;丧失使用、数据或利润;
*或业务中断)、无论原因是什么以及任何责任理论、
*无论是合同、严格责任还是侵权行为(包括疏忽或)
*否则)因使用本软件而以任何方式产生、
*即使被告知可能会发生此类损坏。
*
/*
*==== i2ctmp007.c ===
*
#include
#include
#include
/*驱动程序头文件*/
#include
#include
#include
/* BIOS 模块标题*/
#include
#include
#include
#include
#include
#include
/*示例/板头文件*/
#include "Board.h"
#define TASKSTACKSIZE 640
#define TMP007_DIE_TEMP 0x0001 /*裸片温度结果寄存器*
#define TMP007_obj_TEMP 0x0003 //对象温度结果寄存器*/
静态 Display_Handle 显示;
uint8_t crc8scd30 (void const*输入、size_t len);
/*
*==== mainThread ====
*
void * mainThread (void * arg0)
{
unsigned int i;
//uint16_t 温度;
uint8_t txBuffer[5];
uint8_t rxBuffer[18];
I2C_Handle i2c;
I2C_Params i2cParams;
I2C_Transaction i2cTransaction;
bool status = true;
//SCD30
静态常量 uint8_t SCD30_I2C_address = 0x61;
//浮点 SCD30_CO2_ppm、SCD30_temperature、SCD30_hum湿度;
unsigned int tempU32;
// int16_t err;
// uint16_t interval_in_seconds = 2;
// uint8_t crc_input[2]= 0;
// uint8_t crc_result[2]= 0;
/*调用驱动程序初始化函数*/
display_init();
GPIO_init();
I2C_init();
/*配置 LED 引脚*/
GPIO_setConfig (Board_GPIO_LED0、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/*打开主机显示屏以输出*/
Display = Display_open (Display_Type_UART、NULL);
if (display =NULL){
while (1);
}
/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、Board_GPIO_LED_ON);
display_printf (display、0、0、"开始 i2c SCD30测试\n");
/*创建 I2C 以供使用*/
I2C_Params_init (&i2cParams);
i2cParams.bitrate = I2C_100kHz;// SCD30的最大 I2C 速度为100kHz;
I2C = I2C_open (Board_I2C_TMP、&i2cParams);
if (i2c == NULL){
Display_printf (display、0、0、"Error Initializing I2C\n");
while (1);
}
否则{
display_printf (display、0、0、"I2C initialized!\n"\});
}
//SCD30
/*重置传感器*/
Task_sleep (2000 *(1000 / Clock_tickPeriod));//暂停5000ms
Display_printf (display、0、0、"Reset sensor \n");
TxBuffer[0]= 0xD3;//开始命令= 0xD304
TxBuffer[1]= 0x04;
i2cTransaction.slaveAddress = SCD30_I2C_address;//默认从地址
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 2;
i2cTransaction.readBuf =空;
i2cTransaction.ReadCount = 0;
STATUS = I2C_TRANSF传输(i2c、&i2cTransaction);
如果(status == false){
// I2C 传输失败
}
/*读取固件版本*/
display_printf (display、0、0、"读取固件版本\n");
//写入命令
TxBuffer[0]= 0xD1;//开始命令= 0xD100
TxBuffer[1]= 0x00;
i2cTransaction.slaveAddress = SCD30_I2C_address;//默认从地址
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 2;
i2cTransaction.readBuf =空;
i2cTransaction.ReadCount = 0;
I2C_transfer (i2c、&i2cTransaction);
//读取固件版本
i2cTransaction.slaveAddress = SCD30_I2C_address;//默认从地址
i2cTransaction.writeBuf =空;
i2cTransaction.writeCount = 0;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.ReadCount = 2;
I2C_transfer (i2c、&i2cTransaction);
Display_printf (display、0、0、"固件版本:%x、%x \n"、rxBuffer[0]、rxBuffer[1]);
/*已取消初始化 I2C */
I2C_Close (i2c);
display_printf (display、0、0、"I2C closed!\n"\});
返回(空);
}
//SCD30功能
uint8_t const table []={
0x00、0x31、0x62、0x53、0xc4、 0xf5、0xa6、0x97、0xb9、0x88、 0xdb、0xEA、0x7d、
0x4c、0x1f、0x2e、0x43、0x72、 0x21、0x10、0x87、0xb6、0xe5、 0xd4、0xfa、0xcb、
0x98、0xa9、0x3E、0x0F、0x5c、 0x6d、0x86、0xb7、0xe4、0xd5、 0x42、0x73、0x20、
0x11、0x3f、0x0E、0x5d、0x6c、 0xfb、0xca、0x99、0xa8、0xc5、 0xf4、0xa7、0x96、
0x01、0x30、0x63、0x52、0x7c、 0x4d、0x1E、0x2F、0xb8、0x89、 0xda、0xeb、0x3D、
0x0C、0x5f、0x6e、0xf9、0xc8、 0x9b、0xAA、0x84、0xb5、0xe6、 0xd7、0x40、0x71、
0x22、0x13、0x7E、0x4f、0x1c、 0x2D、0xBA、0x8b、0xd8、0xe9、 0xc7、0xf6、0xA5、
0x94、0x03、0x32、0x61、0x50、 0xbb、0x8a、0xd9、0xe8、0x7f、 0x4e、0x1d、0x2C、
0x02、0x33、0x60、0x51、0xc6、 0xf7、0xa4、0x95、0xf8、0xc9、 0x9a、0xab、0x3c、
0x0D、0x5e、0x6f、0x41、0x70、 0x23、0x12、0x85、0xb4、0xe7、 0xd6、0x7a、0x4b、
0x18、0x29、0xbe、0x8F、0xdc、 0xED、0xc3、0xF2、0xa1、0x90、 0x07、0x36、0x65、
0x54、0x39、0x08、0x5b、0x6A、 0xFD、0xcc、0x9f、0xae、0x80、 0xb1、0xe2、0xd3、
0x44、0x75、0x26、0x17、0xFC、 0xcd、0x9e、0xaf、0x38、0x09、 0x5a、0x6b、0x45、
0x74、0x27、0x16、0x81、0xb0、 0xe3、0xd2、0xbf、0x8e、0xdd、 0xEC、0x7B、0x4a、
0x19、0x28、0x06、0x37、0x64、 0x55、0xC2、0xf3、0xa0、0x91、 0x47、0x76、0x25、
0x14、0x83、0xb2、0xe1、0xd0、 0xFE、0xCF、0x9C、0xAD、0x3a、 0x0B、0x58、0x69、
0x04、0x35、0x66、0x57、0xc0、 0xF1、0xa2、0x93、0xbd、0x8c、 0xdf、0xee、0x79、
0x48、0x1b、0x2a、0xc1、0xf0、 0xa3、0x92、0x05、0x34、0x67、 0x56、0x78、0x49、
0x1a、0x2b、0xbc、0x8d、0xde、 0xef、0x82、0xb3、0xe0、0xD1、 0x46、0x77、0x24、
0x15、0x3b、0x0a、0x59、0x68、 0xFF、0xce、0x9d、0xac
};
uint8_t crc8scd30 (void const*输入、size_t len){
uint8_t CRC = 0xff;
uint8_t const* data =输入;
if (数据==空)
返回 CRC;
CRC &= 0xff;
while (len-)
CRC = table[CRC ^*数据++];
返回 CRC;
}
感谢你的帮助。