| :$附:从器件的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);                // 回传接收到的数据
 }
 }
 }
 |