从C+转换+;语言转换为C(从类到结构),以将HDC1080传感器与ATTiny841一起使用

从C+转换+;语言转换为C(从类到结构),以将HDC1080传感器与ATTiny841一起使用,c,struct,C,Struct,今天,我尝试转换这个库:要将它与ATTiny841一起使用,我要使用Fleury的库,将ATTiny841用作主,将HDC1080用作从 我的问题是,我有一些问题需要从Arduino的HDC1080库中使用的C++语言转换为使用C语言的ATTiny,因为我会向您展示头文件来解释我自己 HDC1080_Registers; class ClosedCube_HDC1080 { public: ClosedCube_HDC1080(); void begin(uint8_t ad

今天,我尝试转换这个库:要将它与ATTiny841一起使用,我要使用Fleury的库,将ATTiny841用作主,将HDC1080用作从

我的问题是,我有一些问题需要从Arduino的HDC1080库中使用的C++语言转换为使用C语言的ATTiny,因为我会向您展示头文件来解释我自己

HDC1080_Registers;

class ClosedCube_HDC1080 {
public:
    ClosedCube_HDC1080();

    void begin(uint8_t address);
    uint16_t readManufacturerId(); // 0x5449 ID of Texas Instruments
    uint16_t readDeviceId(); // 0x1050 ID of the device

    HDC1080_Registers readRegister();   
    void writeRegister(HDC1080_Registers reg);

    void heatUp(uint8_t seconds);

    float readTemperature();
    float readHumidity();

    float readT(); // short-cut for readTemperature
    float readH(); // short-cut for readHumidity

private:
    uint8_t _address;
    uint16_t readData(uint8_t pointer);

};

#endif
这是来自HDC1080传感器的头文件(.h),我读到C语言中没有class函数,所以我决定使用struct函数,我在C语言中看到了struct函数,但在我在Internet上看到的示例中,他们只使用struct函数声明变量,函数不象:

  • 闭合管_HDC1080()
  • 无效开始(uint8\t地址)
  • HDC1080_寄存器读取寄存器()
  • 无效写入寄存器(HDC1080_寄存器寄存器寄存器)
  • 无效加热(uint8秒)
它们是在struct函数之外定义的,所以我对类函数内部的void感到困惑,这就是我寻求帮助的原因。我只想知道:

  • 如何声明这些函数与结构一起使用
  • 以后在C(.C)文件中定义它们会容易得多吗

感谢您的时间和耐心,这是我第一次从一种语言转换到另一种语言。

因为该类中唯一的内部状态是单个
uint8\t
,并且该代码在微控制器上运行,所以最好只将该地址作为参数提供给每个函数

首先,请注意,我的以下建议是的衍生产品,因此根据相同的许可证进行许可:

/*
Arduino Library for Texas Instruments HDC1080 Digital Humidity and Temperature Sensor
Originally written by AA for ClosedCube; this suggested conversion by Nominal Animal
---
The MIT License (MIT)
Copyright (c) 2016-2017 ClosedCube Limited
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
ATtinys是小型8位微控制器,因此最好避免使用
float
类型。相反,我建议你使用1/1000摄氏度的单位来表示温度(25000表示25摄氏度),1/100000表示湿度(50000表示50%的相对湿度)

调整后的库的界面可以非常简单:

void     HDC1080_begin(const uint8_t address);
void     HDC1080_heater(const uint8_t address, const uint8_t seconds);
uint16_t HDC1080_manufacturer(const uint8_t address);
uint16_t HDC1080_device_id(const uint8_t address);
int32_t  HDC1080_temperature(const uint8_t address);
uint32_t HDC1080_humidity(const uint8_t address);
如果我们假设温度和湿度精度保持在14位(由
HDC1080\u begin()
配置),则不需要用户设置或读取配置寄存器

示例代码显示
HDC1080\u manufacturer()
应返回
0x5449
,而
HDC1080\u device\u id()
应返回
0x1050

由于我们不知道“Fleury's Library”有什么样的接口,我将用注释(从
/*I2C:
开始)而不是实际的库调用来展示上述函数的实现

静态
是仅由上述功能使用的内部功能,而不是“用户”代码

#定义HDC1080_温度((uint8_t)0x00)
#定义HDC1080_湿度((uint8_t)0x01)
#定义HDC1080_配置((uint8_t)0x02)
#首先定义HDC1080_串行_ID_((uint8_t)0xFB)
#定义HDC1080_串行_ID_MID((uint8_t)0xFC)
#定义HDC1080_串行_ID_LAST((uint8_t)0xFD)
#定义HDC1080_制造商_ID((uint8_t)0xFE)
#定义HDC1080_设备_ID((uint8_t)0xFF)
/*HDC1080配置的位15..8。
加热器禁用,14位精度用于
温度和相对湿度。
见第15页,共页
http://www.ti.com/lit/ds/symlink/hdc1080.pdf
其他可能性。
*/
#定义HDC1080\u配置\u HI((uint8\u t)0)
静态uint16_t HDC1080_读取(常量uint8_t地址,常量uint8_t项)
{
uint8_t hi,lo;
/*I2C:准备发送到I2C地址“地址”*/
/*I2C:发送8位“项目”*/
/*I2C:终端传输*/
/*延迟9毫秒(0.009秒)*/
/*I2C:准备从I2C地址'address'读取2个字节*/
hi=/*I2C:读取字节*/
lo=/*I2C:读取字节*/
返回((uint16_t)hi)>2;
返回(整数)(整数)40000;
}
uint32\u t HDC1080\u湿度(常数uint8\u t地址)
{
uint16_t temp1=HDC1080_读取(地址,HDC1080_);
返回((uint32_t)3125*temp1+(uint32_t)1024)>>11;
}
请注意,相对湿度范围为0至99998,即0%相对湿度至99.998%相对湿度。这不是一个错误,公式取自,并无损缩放至新范围。类似地,可能的温度范围为-40000至+124989,对应于-40°C至+124.989°C,这也符合TI数据表,无损缩放至新的范围。两者中的
+(uint32_t)1024
项确保正确的舍入(最接近)


您仍然需要使用手头的任何库来实现
/*I2C:
/*Delay
注释。

是的。您必须将结构实例作为参数(或指向某个函数的指针)显式传递到这些函数中。HDC1080的唯一状态就是地址,因此,与其将其放入结构中,不如将地址作为第一个参数来实现函数,并将
HDC1080\u
前置到函数名,以防止与其他函数冲突。例如,
HDC1080\u寄存器HDC1080\u读取\u寄存器(uint8\u t address)
作废hdc1080_写入_寄存器(uint8_t地址,hdc1080_寄存器);
,等等。您的主要工作是更改从Arduino
切换到Fleury的库(无论是什么):这几乎肯定不仅仅是替换函数名。@NominalAnimal那么,让我看看我是否能理解你的意思:我必须用我要定义的所有函数创建另一个结构,并将HDC1080的addres值添加到那些需要它的人身上,就像你之前向我展示的一样?比如:
HDC1080_瑞吉
#define  HDC1080_TEMPERATURE      ((uint8_t)0x00)
#define  HDC1080_HUMIDITY         ((uint8_t)0x01)
#define  HDC1080_CONFIGURATION    ((uint8_t)0x02)
#define  HDC1080_SERIAL_ID_FIRST  ((uint8_t)0xFB)
#define  HDC1080_SERIAL_ID_MID    ((uint8_t)0xFC)
#define  HDC1080_SERIAL_ID_LAST   ((uint8_t)0xFD)
#define  HDC1080_MANUFACTURER_ID  ((uint8_t)0xFE)
#define  HDC1080_DEVICE_ID        ((uint8_t)0xFF)

/* Bits 15..8 of the HDC1080 configuration.
   Heater disabled, 14 bit precision for
   both temperature and relative humidity.
   See page 15 of
       http://www.ti.com/lit/ds/symlink/hdc1080.pdf
   for other possibilities.
*/
#define  HDC1080_CONFIG_HI  ((uint8_t)0)

static uint16_t HDC1080_read(const uint8_t address, const uint8_t item)
{
    uint8_t hi, lo;

    /* I2C: Prepare to send to i2c address 'address'. */
    /* I2C: Send 8 bits 'item'. */
    /* I2C: End transmission. */

    /* Delay for 9 ms (0.009 seconds). */

    /* I2C: Prepare to read 2 bytes from i2c address 'address'. */
    hi = /* I2C: Read byte. */
    lo = /* I2C: Read byte. */

    return (((uint16_t)hi) << 8) | lo;
}

void HDC1080_begin(const uint8_t address)
{
    /* I2C: Prepare to send to i2c address 'address'. */
    /* I2C: Send 8 bits: HDC1080_CONFIGURATION (=0x02). */ 
    /* I2C: Send 8 bits: HDC1080_CONFIG_HI (=0x00). */
    /* I2C: Send 8 bits: 0. */
    /* I2C: End transmission. */
    /* Delay for 10 ms = 0.01 seconds. */
}

void HDC1080_heater(const uint8_t address, const uint8_t seconds)
{
    uint8_t s, i;

    /* I2C: Prepare to send to i2c address 'address'. */
    /* I2C: Send 8 bits: HDC1080_CONFIGURATION (=0x02). */ 
    /* I2C: Send 8 bits: 48 (=0x30). */
    /* I2C: Send 8 bits: 0. */
    /* I2C: End transmission. */

    /* Delay for 10 ms = 0.01 seconds. */

    for (s = 0; s < seconds; s++) {
        for (i = 0; i < 66; i++) {

            /* I2C: Prepare to send to i2c address 'address'. */
            /* I2C: Send 8 bits 'item'. */
            /* I2C: End transmission. */

            /* Delay for 20 ms (0.020 seconds). */

            /* I2C: Prepare to read 4 bytes from i2c address 'address'. */
            /* I2C: Read byte. (Ignore the value.) */
            /* I2C: Read byte. (Ignore the value.) */
            /* I2C: Read byte. (Ignore the value.) */
            /* I2C: Read byte. (Ignore the value.) */
        }
    }

    /* I2C: Prepare to send to i2c address 'address'. */
    /* I2C: Send 8 bits: HDC1080_CONFIGURATION (=0x02). */ 
    /* I2C: Send 8 bits: HDC1080_CONFIG_HI (=0x00). */
    /* I2C: Send 8 bits: 0. */
    /* I2C: End transmission. */

    /* Delay for 10 ms = 0.01 seconds. */
}

uint16_t HDC1080_manufacturer(const uint8_t address)
{
    return HDC1080_read(address, HDC1080_MANUFACTURER_ID);
}

uint16_t HDC1080_device_id(const uint8_t address)
{
    return HDC1080_read(address, HDC1080_DEVICE_ID);
}

int32_t HDC1080_temperature(const uint8_t address)
{
    uint16_t temp1 = HDC1080_read(address, HDC1080_TEMPERATURE) >> 2;
    return (int_t)(((uint32_t)20625 * temp1 + (uint32_t)1024) >> 11) - (int32_t)40000;
}

uint32_t HDC1080_humidity(const uint8_t address)
{
    uint16_t temp1 = HDC1080_read(address, HDC1080_HUMIDITY);
    return ((uint32_t)3125 * temp1 + (uint32_t)1024) >> 11;
}