|
原程序是用I/O口模拟的I2C代码如下:
在应用调用的时候使用:double angle_process(unsigned char command)其中command是对应的指令值.我使用44来采集第一通道,64来采集第二通道.
代码:
#define P1 0.000641667 //P1=2.048/8192*(3+4.7)/3=0.000641667采用14位
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C起动,注意起动前,保证scl=1,data=1,data =>out(i/o输出)
*/
void ads1112_start(void)
{
scl = 1; //scl为高电平
io_data = 0; //数据线设置为输出
out_data = 1;
time_delay_us(2);
out_data = 0;
time_delay_us(2);
scl = 0;
time_delay_us(2);
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:I2C停止
*/
void ads1112_stop(void)
{
io_data = 0; //数据线设置为输出
out_data=0;
time_delay_us(2);
scl=1;
time_delay_us(2);
out_data=1;
time_delay_us(2);
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:i2c从器件(ads1100) 应答
*/
BYTE ackby_ads1112(void)
{
UCHAR times=0;
out_data = 1;
io_data = 1; //数据线设置为输入
time_delay_us(2);
scl=1;
while((out_data==1)&&(times<100)) //wait for ads ack data=0
{
times++;
}
scl=0; //ready for next
time_delay_us(2);
if(times>100)
return 0;
else
return 1;
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:主机应答
////////////////////////////////////////////////////////////////////////////////////////////
*/
void ackby_master(void)
{
scl=0;
io_data = 0; //数据线设置为输出
out_data=0;
time_delay_us(2);
scl=1; //wait for ads1112 receive
time_delay_us(2);
scl=0; //ready for next
time_delay_us(2);
}
/*========================================================================================
函数功能:向I2C从器件发送一帧(8bit)
=========================================================================================*/
void send_frame(UCHAR framedata)
{
unsigned char i;
scl=0;
io_data = 0; //数据线设置为输出
time_delay_us(2);
for(i=0;i<8;i++)
{
scl=0;
if( ( (framedata << i) & 0x80) ==0 )
{
out_data=0;
}
else
{
out_data=1;
}
time_delay_us(1); //稳定数据
scl=1;
time_delay_us(1);
}
scl=0;
}
/*===============================================================
函数功能:向I2C从器件读取一帧(8bit)
===============================================================*/
BYTE read_frame(void)
{
unsigned char data=0,i;
scl=0;
io_data = 1; //数据线设置为输入
time_delay_us(1); //wait for ads ready data
for(i=0;i<8;i++)
{
scl=1;
data=data<<1; //bit0=0
time_delay_us(1); //等待数据稳定
if(out_data==1)
{
data=data+1;
}
scl=0;
time_delay_us(1); //wait for ads ready data
}
return data;
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:写一个命令码到ADS1112
*/
void ads1100_write(unsigned char addr,unsigned char command)
{
//addr=0x90; //1001(固定) 000(器件编号) 0(写)
ads1112_start();
send_frame(addr);
ackby_ads1112();
send_frame(command);
ackby_ads1112();
ads1112_stop();
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:读写一次转换数据从ADS1112
参数说明:addr器件地址
////////////////////////////////////////////////////////////////////////////////////////////
*/
unsigned int ads1100_read(unsigned char addr)
{
UINT data;
BYTE datah,datal,datac;
// addr=0x91; //1001(固定) 000(器件编号) 1(读)
ads1112_start();
send_frame(addr);
ackby_ads1112();
datah=read_frame();
ackby_master();
datal=read_frame();
ackby_master();
datac=read_frame();
ackby_master();
ads1112_stop();
data=(((UINT)datah)<<8) +(UINT)datal;
return data;
}
/*
////////////////////////////////////////////////////////////////////////////////////////////
函数功能:进行一次角度转换处理,对角度传感器分别顺序采集AIN0,AIN1通道,然后进行电压转角度处理,
*/
double angle_process(unsigned char command)
{
UINT codetmp;
double adcount;
TRISEbits.TRISE0 = 0;
PORTEbits.RE0 = 1;//启动ad
time_delay_us(10);
ads1100_write(0x90,command); //准备处理AIN0或AIN1通道
codetmp = ads1100_read(0x91);//读一次AD转换
adcount = (double)(codetmp*P1);//(double)P);
return(adcount);
}
|
|