:$附:从器件的7位I2C地址为0x20,寄存器0x00~0x35 是原始数据寄存器的地址,0x36是读取完成寄存器的地址。规定在读取或者处理完成原始数据之后,控制器要写入一个"0"到读取完成寄存器(0x36)中。我现在仅仅是读取的第一个寄存器0x00的数据;
(还望高人指点迷津!)
#include <reg52.h>
#include <intrins.h>
#define OP_WRITE 0x20 // 器件地址以及读取操作
#define OP_READ 0x21 // 器件地址以及写操作
#define OK_Register 0x36 //读取完成寄存器地址
sbit SDA=P2^3; //将串行数据总线SDA位定义在为P2.3引脚
sbit SCL=P2^2; //将串行时钟总线SDA位定义在为P2.2引脚
/*****************************************************
函数功能:微妙级别的延时函数
***************************************************/
void delay()
{;;}
/*****************************************************
函数功能:延时1ms
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/***************************************************
函数功能:开始数据传送
***************************************************/
void start()
{
SDA = 1; //SDA初始化为高电平“1”
SCL = 1; //开始数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 0; //SDA的下降沿被认为是开始信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
}
/***************************************************
函数功能:结束数据传送
***************************************************/
void stop()
{
SDA = 0; //SDA初始化为低电平“0” _n
SCL = 1; //结束数据传送时,要求SCL为高电平“1”
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA = 1; //SDA的上升沿被认为是结束信号
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SDA=0;
SCL=0;
}
/***************************************************
函数功能:器件的应答
***************************************************/
void response()
{
unsigned char i;
SCL=1;
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
while((SDA==1)&&(i<255)) i++;
SCL=0;
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
}
/***************************************************
函数功能:从TST120读取数据
出口参数:x
***************************************************/
unsigned char ReadData()
{
unsigned char i;
unsigned char x;
SCL=0;
delay();
SDA=1;
delay();
for(i = 0; i < 8; i++)
{
SCL = 1;
x<<=1;
x|=(unsigned char)SDA;
SCL = 0;
}
return(x);
}
/***************************************************
函数功能:向TST120的当前地址写入数据
***************************************************/
void WriteCurrent(unsigned char y)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SDA = (bit)(y&0x80);
_nop_();
SCL = 1;
_nop_();
_nop_();
SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
y <<= 1; //将y中的各二进位向左移一位
}
SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 1; //根据上述规定,SCL应为高电平
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
_nop_(); //等待一个机器周期
SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
}
/***************************************************
函数功能:从CY中的当前地址读取数据
***************************************************/
unsigned char ReadCurrent()
{
unsigned char date;
start();
WriteCurrent(OP_WRITE); //时序上要求是先发8位的0x20
response();
//这个0x00是寄存器的起始地址
WriteCurrent(0x00);
response();
start(); //需要重新开始
WriteCurrent(OP_READ); //发送读取数据指令
response();
//这个0x00是指明第零个寄存器
WriteCurrent(0x00); //写入要读取原始寄存器0x00的数据地址
delay();
stop(); //停止数据传递
date=ReadData(); //将读取的数据存入x
delay();
return date; //返回读取的数据
}
void send_char(unsigned char txd)
// 传送一个字符
{
SBUF = txd;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
/*********将0 写入读取完成寄存器当中 ****************/
void write_complete()
{
start();
WriteCurrent(OP_WRITE);
response();
WriteCurrent(OK_Register);
response();
WriteCurrent(0x00); //此时的0x00 代表是写入的数据0 而不是寄存器的地址
response();
stop();
}
void init_comm()
{
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xFD; // 波特率9600
TL1 = 0xFD;
SCON = 0x50; // 设定串行口工作方式
PCON &= 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
IE = 0x0; // 禁止任何中断
}
void main()
{
unsigned char date,tmp;
init_comm();
SDA = 1;
delay();
SCL = 1;
delay();
date=ReadCurrent();
delay();
while(1)
{
if(RI) // 是否有数据到来
{
RI = 0;
write_complete();
tmp = SBUF; // 暂存接收到的数据
//P0 = tmp; // 数据传送到P0口
send_char(tmp); // 回传接收到的数据
}
}
}
|