4,436
社区成员
发帖
与我相关
我的任务
分享
#include "StdAfx.h"
class CI2C //I2C接口设备的底层程序,包括键盘,温度控制器
{
private:
CI2C ( void ){}
~CI2C ( void ){}
static CI2C m_Instance;
//CI2C &operator=(CI2C&); //disallowed
//CI2C ( const CI2C& ); //disallowed
public:
static CI2C &GetInstance ( void ) { return m_Instance; }
void Initial ( void );
void Cleanup ( void );
int GetTmp ( void );
int GetLastKey ( void );
private:
void ReadI2C ( UCHAR device_addr, UCHAR reg_addr, int read_len, UCHAR *out_buf );
void WriteI2C ( USHORT device_addr, UCHAR reg_addr, UCHAR data );
struct i2c_msg
{
USHORT addr; //从设备地址
USHORT flags; //1:读,0:写
USHORT len; //数据长度
UCHAR *buf; //数据
};
struct i2c_rdwr_ioctl_data
{
i2c_msg *msgs; //
int nmsgs; //nmsgs这个数量决定了有多少开始信号,对于“单开始时序”,取1
};
int m_nfd; //设备节点 /dev/i2c-1
CLock m_Lock; //互斥锁,包含不能同时读写I2C
};
namespace i2c_namespace
{
//common
const int I2C_RETRIES = 0x0701;
const int I2C_TIMEOUT = 0x0702;
const int I2C_RDWR = 0x0707;
const int MAX_MSG_NUM = 2; //一次连续可以发多少条消息
const int MAX_BUF_NUM = 2; //每条消息最多带几个数据
//key
const int ADDR_KEY = 0x34;
//temperature
const int ADDR_TMP = 0x4f;
}
extern CI2C &g_I2C;
/////////////////////////I2C.cpp///////////////////////
#include "I2C.h"
using namespace i2c_namespace;
CI2C CI2C::m_Instance;
CI2C &g_I2C = CI2C::GetInstance();
/*/////////////////////////////////////////////////////////////////////////////
Function: Initial
Description: 初始化I2C和互斥锁
Calls: ---
Called By: ---
Input: ---
Output: ---
Return: ---
Others: public
/////////////////////////////////////////////////////////////////////////////*/
void CI2C::Initial ( void )
{
m_nfd = open("/dev/i2c-1",O_RDWR);
ioctl(m_nfd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(m_nfd,I2C_RETRIES,2);/*重复次数*/
//key:
WriteI2C ( ADDR_KEY, 0x01, 0x2d );
WriteI2C ( ADDR_KEY, 0x1d, 0x3f );
WriteI2C ( ADDR_KEY, 0x1e, 0x3f );
WriteI2C ( ADDR_KEY, 0x1f, 0x00 );
WriteI2C ( ADDR_KEY, 0x23, 0xc0 );
WriteI2C ( ADDR_KEY, 0x24, 0xc0 );
WriteI2C ( ADDR_KEY, 0x25, 0x03 );
//temperature
WriteI2C ( ADDR_TMP, 0x01, 0x60 );
m_Lock.Initialize();
}
/*/////////////////////////////////////////////////////////////////////////////
Function: Cleanup
Description: 数据清理
Calls: ---
Called By: ---
Input: ---
Output: ---
Return: ---
Others: public
/////////////////////////////////////////////////////////////////////////////*/
void CI2C::Cleanup ( void )
{
m_Lock.Destroy();
close ( m_nfd );
}
/*/////////////////////////////////////////////////////////////////////////////
Function: GetTmp
Description: 取得温度(摄氏度)
Calls: ---
Called By: ---
Input: ---
Output: ---
Return: 温度
Others: public
/////////////////////////////////////////////////////////////////////////////*/
int CI2C::GetTmp ( void )
{
UCHAR buf[2];
ReadI2C ( ADDR_TMP, 0, 2, buf );
return ( ( ( ( buf[0] << 8 ) | buf[1] ) & 0xffff) >> 8 );
}
/*/////////////////////////////////////////////////////////////////////////////
Function: GetLastKey
Description: 取得键值
Calls: ---
Called By: ---
Input: ---
Output: ---
Return: 键值
Others: public
/////////////////////////////////////////////////////////////////////////////*/
int CI2C::GetLastKey ( void )
{
int data;
UCHAR buf[1];
ReadI2C ( ADDR_KEY, 0x03, 1, buf );
data = ( buf[0] & 0xff); //缓存的个数
for ( int i = 0 ; i < data ; i++ )
{
ReadI2C ( ADDR_KEY, 0x04, 1, buf );
}
data = ( buf[0]& 0xff);
return data ;
}
/*/////////////////////////////////////////////////////////////////////////////
Function: WriteI2C
Description: 写I2C设备
Calls: ---
Called By: ---
Input: device_addr: 设备地址
reg_addr: 寄存器地址
data: 要写的数据
Output: ---
Return: 键值
Others: private
/////////////////////////////////////////////////////////////////////////////*/
void CI2C::WriteI2C ( USHORT device_addr, UCHAR reg_addr, UCHAR data )
{
m_Lock.Enter();
i2c_rdwr_ioctl_data msgbuf;
msgbuf.nmsgs = 1;
msgbuf.msgs = new i2c_msg[msgbuf.nmsgs];
msgbuf.msgs[0].len = 2;
msgbuf.msgs[0].flags=0;//write
msgbuf.msgs[0].addr=device_addr;
msgbuf.msgs[0].buf = new UCHAR[2];
msgbuf.msgs[0].buf[0]=reg_addr;// 写入目标的地址
msgbuf.msgs[0].buf[1]=data;// 写入目标的地址
ioctl(m_nfd,I2C_RDWR, &msgbuf);
delete [] msgbuf.msgs[0].buf;
delete [] msgbuf.msgs;
m_Lock.Leave();
}
/*/////////////////////////////////////////////////////////////////////////////
Function: ReadI2C
Description: 读I2C设备
Calls: ---
Called By: ---
Input: device_addr: 设备地址
reg_addr: 寄存器地址
read_len:数据长度
Output: out_buf:数据
Return: ---
Others: private
/////////////////////////////////////////////////////////////////////////////*/
void CI2C::ReadI2C ( UCHAR device_addr, UCHAR reg_addr, int read_len, UCHAR *out_buf )
{
m_Lock.Enter();
int i;
i2c_rdwr_ioctl_data msgbuf;
msgbuf.nmsgs=2;
msgbuf.msgs = new i2c_msg[msgbuf.nmsgs];
msgbuf.msgs[0].len=1; // 目标数据的地址
msgbuf.msgs[0].addr=device_addr; // 设备地址
msgbuf.msgs[0].flags=0;//write
msgbuf.msgs[0].buf = new UCHAR[1];
msgbuf.msgs[0].buf[0]=reg_addr;//数据地址
msgbuf.msgs[1].len= read_len;//读出的数据
msgbuf.msgs[1].addr=device_addr;// 设备地址
msgbuf.msgs[1].flags = 1;//read
msgbuf.msgs[1].buf = new UCHAR[read_len];
ioctl( m_nfd, I2C_RDWR, &msgbuf );
for ( i = 0 ; i < read_len ; i++ )
out_buf[i] = msgbuf.msgs[1].buf[i];
delete [] msgbuf.msgs[0].buf;
delete [] msgbuf.msgs[1].buf;
delete [] msgbuf.msgs;
m_Lock.Leave();
}