太费劲了 ! I2C 为什么不行? 51
时间:10-02
整理:3721RD
点击:
#include<reg51.h>
#include <intrins.h>
#define unchar unsigned char
sbit SCL=P2^0;
sbit SDA=P2^1;
sbit A0=ACC^0;
unchar jishu,ad_data;
/********************** COM ***********************/
void init_com()//初始化串口 T1
{TMOD=0x21;
SCON=0X40;
PCON=0X00;
TH1=0XFD;
TL1=0XFD;
TR1=1;
}
/********************** DELAY nop ***********************/
void delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void delays(unsigned int i)
{
for(;i>0;i--);
}
/********************* START *************************/
void i2c_start()
{
SCL=1;
SDA=1;
delay(); //确定总线空闲
SDA=0;
delay();//起始保持4.7us 以上延时差
SCL=0;
}
/********************* STOP *************************/
void i2c_stop()
{
SDA=0;
_nop_();
SCL=1;
delay();//结束保持4.0us 以上延时差
SDA=1;
delay();
}
/****************** W ****************************/
void i2c_w(unchar w_data)
{ACC=w_data;
for(jishu=8;jishu>0;jishu--)
{
if(ACC&0x80) SDA=1;
else SDA=0;
_nop_(); //确保SDA保持稳定
SCL=1; //拉高SCL发送一位
delay();
SCL=0;
delay();
ACC=w_data;
ACC<<=(8-jishu);
}
}
/********************* R *************************/
/*********** 重要:read后 必须紧跟ack或noack 3.4us ***********/
void i2c_r()
{
//SDA=1; //读入应答信号(拉高IO口)
for(jishu=8;jishu>1;jishu--)
{
delay();
SCL=1; //拉高SCL接收一位
A0=SDA;
delay();
ACC<<=1;
SCL=0;
}
delay();
SCL=1; //拉高SCL接收一位
A0=SDA;
delay();
ACC<<=1;
ad_data=ACC;
}
/********************* ack *************************/
void i2c_ack()
{
SCL=0;
SDA=0;//发送应答位 ***************************************
delay();
SCL=1;
delay();
SCL=0;//发完
delay();
}
/********************* noack *************************/
void i2c_noack()
{
SCL=0;
SDA=1;//发送应答位 ***************************************
delay();
SCL=1;
delay();
SCL=0;//发完
delay();
}
/********************* main *************************/
void main()
{
init_com();
while(1)
{i2c_start();
i2c_w(0x90); //addr
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
i2c_w(0x00); //cmd
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
/********************/
SDA=1;
_nop_();
i2c_start();
i2c_w(0x91); //addr
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
i2c_r();
i2c_noack();
i2c_stop();
SBUF=ad_data;
delays(100000);
}
}
#include <intrins.h>
#define unchar unsigned char
sbit SCL=P2^0;
sbit SDA=P2^1;
sbit A0=ACC^0;
unchar jishu,ad_data;
/********************** COM ***********************/
void init_com()//初始化串口 T1
{TMOD=0x21;
SCON=0X40;
PCON=0X00;
TH1=0XFD;
TL1=0XFD;
TR1=1;
}
/********************** DELAY nop ***********************/
void delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void delays(unsigned int i)
{
for(;i>0;i--);
}
/********************* START *************************/
void i2c_start()
{
SCL=1;
SDA=1;
delay(); //确定总线空闲
SDA=0;
delay();//起始保持4.7us 以上延时差
SCL=0;
}
/********************* STOP *************************/
void i2c_stop()
{
SDA=0;
_nop_();
SCL=1;
delay();//结束保持4.0us 以上延时差
SDA=1;
delay();
}
/****************** W ****************************/
void i2c_w(unchar w_data)
{ACC=w_data;
for(jishu=8;jishu>0;jishu--)
{
if(ACC&0x80) SDA=1;
else SDA=0;
_nop_(); //确保SDA保持稳定
SCL=1; //拉高SCL发送一位
delay();
SCL=0;
delay();
ACC=w_data;
ACC<<=(8-jishu);
}
}
/********************* R *************************/
/*********** 重要:read后 必须紧跟ack或noack 3.4us ***********/
void i2c_r()
{
//SDA=1; //读入应答信号(拉高IO口)
for(jishu=8;jishu>1;jishu--)
{
delay();
SCL=1; //拉高SCL接收一位
A0=SDA;
delay();
ACC<<=1;
SCL=0;
}
delay();
SCL=1; //拉高SCL接收一位
A0=SDA;
delay();
ACC<<=1;
ad_data=ACC;
}
/********************* ack *************************/
void i2c_ack()
{
SCL=0;
SDA=0;//发送应答位 ***************************************
delay();
SCL=1;
delay();
SCL=0;//发完
delay();
}
/********************* noack *************************/
void i2c_noack()
{
SCL=0;
SDA=1;//发送应答位 ***************************************
delay();
SCL=1;
delay();
SCL=0;//发完
delay();
}
/********************* main *************************/
void main()
{
init_com();
while(1)
{i2c_start();
i2c_w(0x90); //addr
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
i2c_w(0x00); //cmd
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
/********************/
SDA=1;
_nop_();
i2c_start();
i2c_w(0x91); //addr
SCL=1; //////// 等待应答
delay(); /////////
SCL=0; /////////
delay(); //////////
i2c_r();
i2c_noack();
i2c_stop();
SBUF=ad_data;
delays(100000);
}
}