我正在尝试通过Arduino Mega的I2C总线与该光传感器进行通信。我在网上找到了这个I2C库(用C ++编写),但是我不知道如何将其翻译为C语言。 我在Atmel Studio 7.0中编程。 我的arduino内部的微控制器是atmega2560。 我已经创建了Bootloader,以便从atmel IDE加载程序。
代码如下:
TCS3471.C:
#include "TCS3471.h"
TCS3471::TCS3471(void (*i2cWriteFunc)(byte,byte,byte*),void (*i2cReadFunc)(byte,byte,byte*))
{
_i2cWrite = i2cWriteFunc;
_i2cRead = i2cReadFunc;
_detected = false;
_i2cAddress = 0;
}
bool TCS3471::detect()
{
if (_detected)
return true;
else
{
_i2cAddress = TCS3471_ADDRESS_1;
byte tmpaddr = read8(TCS3471_ID_REG);
if (tmpaddr == 0x14 || tmpaddr == 0x1D)
{
_detected = true;
}
else
{
_i2cAddress = TCS3471_ADDRESS_2;
tmpaddr = read8(TCS3471_ID_REG);
if (tmpaddr == 0x14 || tmpaddr == 0x1D)
{
_detected = true;
}
else
{
_i2cAddress = 0;
}
}
}
return _detected;
}
bool TCS3471::enable()
{
detect();
if (_detected)
{
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) | TCS3471_PON_BIT);
delay(3);
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) | TCS3471_AEN_BIT);
return true;
}
else
return false;
}
void TCS3471::disable()
{
if (_detected)
{
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) & ~(TCS3471_PON_BIT | TCS3471_AEN_BIT));
}
}
void TCS3471::setIntegrationTime(float integrationTime)
{
if (_detected)
{
word aTime = (word)(integrationTime * 10);
aTime = aTime / 24;
if (aTime > 256)
aTime = 256;
aTime = aTime - 256;
write8(TCS3471_ATIME_REG, (byte)aTime);
}
}
void TCS3471::setWaitTime(float waitTime)
{
if (_detected)
{
int32_t wTime = (int32_t)(waitTime * 10);
if (wTime < 24)
{
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) & ~TCS3471_WEN_BIT);
return;
}
else if (wTime > 6144)
{
write8(TCS3471_CONFIG_REG, TCS3471_WLONG_BIT);
if (wTime > 73728)
wTime = 73728;
wTime = wTime / 288;
}
else
{
write8(TCS3471_CONFIG_REG, 0x00);
wTime = wTime / 24;
}
wTime = 256 - wTime;
write8(TCS3471_WTIME_REG, (byte)wTime);
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) | TCS3471_WEN_BIT);
}
}
void TCS3471::setGain(tcs3471Gain_t gain)
{
if (_detected)
{
write8(TCS3471_CONTROL_REG, gain);
}
}
void TCS3471::enableInterrupt()
{
if (_detected)
{
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) | TCS3471_AIEN_BIT);
}
}
void TCS3471::disableInterrupt()
{
if (_detected)
{
write8(TCS3471_ENABLE_REG, read8(TCS3471_ENABLE_REG) & ~TCS3471_AIEN_BIT);
}
}
void TCS3471::clearInterrupt()
{
if (_detected)
{
_i2cBuffer[0] = TCS3471_COMMAND_BIT | TCS3471_SPECIAL_BIT | TCS3471_INTCLEAR_BIT;
_i2cWrite(_i2cAddress,1,_i2cBuffer);
}
}
void TCS3471::interruptHighThreshold(word highThreshold)
{
if (_detected)
{
write16(TCS3471_AIHTL_REG,highThreshold);
}
}
void TCS3471::interruptLowThreshold(word lowThreshold)
{
if (_detected)
{
write16(TCS3471_AILTL_REG,lowThreshold);
}
}
void TCS3471::interruptPersistence(byte persistence)
{
if (_detected)
{
byte valueToWrite = persistence;
if (valueToWrite > 60)
valueToWrite = 60;
if (valueToWrite > 3)
valueToWrite = valueToWrite / 5 + 3;
write8(TCS3471_PERS_REG,valueToWrite & 0x0F);
}
}
byte TCS3471::getChipID()
{
detect();
if (_detected)
{
return read8(TCS3471_ID_REG);
}
else
return 0;
}
bool TCS3471::rgbcValid()
{
if (_detected)
{
return (read8(TCS3471_STATUS_REG) & TCS3471_AVALID_BIT) == TCS3471_AVALID_BIT;
}
else
return false;
}
word TCS3471::readCData()
{
if (_detected)
{
return read16(TCS3471_CDATA_REG);
}
return 0;
}
word TCS3471::readRData()
{
if (_detected)
{
return read16(TCS3471_RDATA_REG);
}
return 0;
}
word TCS3471::readGData()
{
if (_detected)
{
return read16(TCS3471_GDATA_REG);
}
return 0;
}
word TCS3471::readBData()
{
if (_detected)
{
return read16(TCS3471_BDATA_REG);
}
return 0;
}
void TCS3471::write8(byte reg, byte val)
{
_i2cBuffer[0] = TCS3471_COMMAND_BIT | reg;
_i2cBuffer[1] = val;
_i2cWrite(_i2cAddress,2,_i2cBuffer);
}
void TCS3471::write16(byte reg, word val)
{
_i2cBuffer[0] = TCS3471_COMMAND_BIT | TCS3471_AUTOINCR_BIT | reg;
_i2cBuffer[1] = val & 0xFF;
_i2cBuffer[2] = (val >> 8) & 0xFF;
_i2cWrite(_i2cAddress,3,_i2cBuffer);
}
byte TCS3471::read8(byte reg)
{
_i2cBuffer[0] = TCS3471_COMMAND_BIT | reg;
_i2cWrite(_i2cAddress, 1, _i2cBuffer);
_i2cRead(_i2cAddress, 1, _i2cBuffer);
return _i2cBuffer[0];
}
word TCS3471::read16(byte reg)
{
_i2cBuffer[0] = TCS3471_COMMAND_BIT | TCS3471_AUTOINCR_BIT | reg;
_i2cWrite(_i2cAddress, 1, _i2cBuffer);
_i2cRead(_i2cAddress, 2, _i2cBuffer);
word ret = _i2cBuffer[1] << 8;
ret |= _i2cBuffer[0];
return ret;
}
TCS3471.H
#ifndef TCS3471_h
#define TCS3471_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
// slave address
#define TCS3471_ADDRESS_1 0x29
#define TCS3471_ADDRESS_2 0x39
// registers
#define TCS3471_ENABLE_REG 0x00
#define TCS3471_ATIME_REG 0x01
#define TCS3471_WTIME_REG 0x03
#define TCS3471_AILTL_REG 0x04
#define TCS3471_AILTH_REG 0x05
#define TCS3471_AIHTL_REG 0x06
#define TCS3471_AIHTH_REG 0x07
#define TCS3471_PERS_REG 0x0C
#define TCS3471_CONFIG_REG 0x0D
#define TCS3471_CONTROL_REG 0x0F
#define TCS3471_ID_REG 0x12
#define TCS3471_STATUS_REG 0x13
#define TCS3471_CDATA_REG 0x14
#define TCS3471_CDATAH_REG 0x15
#define TCS3471_RDATA_REG 0x16
#define TCS3471_RDATAH_REG 0x17
#define TCS3471_GDATA_REG 0x18
#define TCS3471_GDATAH_REG 0x19
#define TCS3471_BDATA_REG 0x1A
#define TCS3471_BDATAH_REG 0x1B
// command register bits
#define TCS3471_COMMAND_BIT 0x80
#define TCS3471_AUTOINCR_BIT 0x20
#define TCS3471_SPECIAL_BIT 0x60
#define TCS3471_INTCLEAR_BIT 0x06
// enable register bits
#define TCS3471_AIEN_BIT 0x10
#define TCS3471_WEN_BIT 0x08
#define TCS3471_AEN_BIT 0x02
#define TCS3471_PON_BIT 0x01
// configuration register bits
#define TCS3471_WLONG_BIT 0x02
// control register bits
typedef enum
{
TCS3471_GAIN_1X = 0x00,
TCS3471_GAIN_4X = 0x01,
TCS3471_GAIN_16X = 0x02,
TCS3471_GAIN_60X = 0x03,
}
tcs3471Gain_t;
// ID register values
#define TCS3471_1_5_VALUE 0x14
#define TCS3471_3_7_VALUE 0x1D
// status register bits
#define TCS3471_AINT_BIT 0x10
#define TCS3471_AVALID_BIT 0x01
class TCS3471
{
public:
TCS3471(void (*i2cWriteFunc)(byte,byte,byte*),void (*i2cReadFunc)(byte,byte,byte*));
bool detect();
bool enable();
void disable();
void setIntegrationTime(float integrationTime);
void setWaitTime(float waitTime);
void setGain(tcs3471Gain_t gain);
void enableInterrupt();
void disableInterrupt();
void clearInterrupt();
void interruptHighThreshold(word highThreshold);
void interruptLowThreshold(word lowThreshold);
void interruptPersistence(byte persistence);
byte getChipID();
bool rgbcValid();
word readCData();
word readRData();
word readGData();
word readBData();
void write8(byte reg, byte val);
void write16(byte reg, word val);
byte read8(byte reg);
word read16(byte reg);
private:
byte _i2cBuffer[3];
bool _detected;
byte _i2cAddress;
void (*_i2cWrite)(byte,byte,byte*);
void (*_i2cRead)(byte,byte,byte*);
};
#endif
答案 0 :(得分:0)
关于公开的代码,该库似乎并不太依赖C ++ OOP功能。恕我直言,大多数代码都可以轻松地转换为C。因此,我想展示适用于此目的的原则。
C ++示例类CPlusPlusThing
:
#include <iostream>
class CPlusPlusThing {
private:
int member1;
int member2;
public:
CPlusPlusThing(int member1, int member2):
member1(member1), member2(member2)
{ }
void setMember1(int value) { member1 = value; }
void setMember2(int value) { member2 = value; }
void print();
};
void CPlusPlusThing::print()
{
std::cout
<< "CPlusPlusThing {\n"
<< " member1: " << member1 << '\n'
<< " member2: " << member2 << '\n'
<< "}\n";
}
和一个简短的应用示例:
int main()
{
{ CPlusPlusThing thing(123, 0);
thing.setMember2(321);
thing.print();
}
{ CPlusPlusThing *pThing = new CPlusPlusThing(234, 0);
pThing->setMember2(432);
pThing->print();
delete pThing;
}
return 0;
}
经过编译和测试:
CPlusPlusThing {
member1: 123
member2: 321
}
CPlusPlusThing {
member1: 234
member2: 432
}
将其音译为C时,必须考虑以下几点:
C中没有构造函数/析构函数。→如果构造函数仅初始化成员,则也可以执行简单的初始化。否则,应提供一个初始化函数。
C中没有成员函数。→撇开virtual
函数,成员函数不过是带有隐式this
参数的函数。因此,this
参数使用成员函数调用中.
或->
的左操作数的表达式进行初始化。在C中,分别。指针只是第一个参数。在适当的情况下,this
隐式地应用于成员函数内部,这在C语言中是不可能的。它必须显式地完成。
在C ++中,不同的类可能会提供具有相同名称的成员函数。成员函数调用将根据.
或->
的左操作数的类型选择右一个。 C中没有机会。不同的函数必须具有不同的名称。通常的解决方法是将类名称包含在C API的函数名称中。
因此,这就是上面的示例在C语言中的样子:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int member1;
int member2;
} CThing;
CThing* newCThing(int member1, int member2)
{
CThing *pThis = malloc(sizeof (CThing));
if (pThis) {
pThis->member1 = member1;
pThis->member2 = member2;
}
return pThis;
}
void deleteCThing(CThing *pThis)
{
free(pThis);
}
void setCThingMember1(CThing *pThis, int member1)
{
pThis->member1 = member1;
}
void setCThingMember2(CThing *pThis, int member2)
{
pThis->member2 = member2;
}
void printCThing(CThing *pThis)
{
printf(
"CThing {\n"
" member1: %d\n"
" member2: %d\n"
"}\n",
pThis->member1, pThis->member2);
}
以及相应的应用示例:
int main()
{
{ CThing thing = { 123, 0 };
setCThingMember2(&thing, 321);
printCThing(&thing);
}
{ CThing *pThing = newCThing(234, 0);
setCThingMember2(pThing, 432);
printCThing(pThing);
deleteCThing(pThing);
}
return 0;
}
经过编译和测试:
CThing {
member1: 123
member2: 321
}
CThing {
member1: 234
member2: 432
}