郭天祥51单片机教程--- IIC总线

郭天祥51单片机教程— IIC总线

#include 
#define uchar unsigned char

sbit SDA = P2^0; //数据总线
sbit SCL = p2_1; //时钟总线

void delay() //大概延时5us
{
     
	;;
}

void delay1(uchar x)
{
     
	uchar a,b;
	for(a=x;a>0;a--)
	  for(b=100;b>0;b--);
}

//这是一个写数据的整体过程
void wirte_add(uchar address,uchar date)
{
     
	start();
	write_byte(0xa0); //写器件的地址(其中0代表下一个操作是写)
	respons();
	write_byte(address); //往芯片第三个地址写(器件内部存储器的地址)
	respons();
	wirte_byte(date); //真正的数据
	respons();
	stop();
}

//这是一个读数据的整体过程
uchar read_add(uchar address)
{
     
	uchar date;
	start();
	write_byte(0xa0); //写入器件的地址
	respons();
	write_byte(address); //写器件内部存储器的地址
	respons();
	start();
	write_byte(0xa1); //写器件的地址(下一个数据操作是读)
    respons();
	
	date = read_byte(); //读出数据
	stop();
	return date;
}

//起始信号
void start()
{
     
	SDA = 1;
	delay();
	SCL = 1;
	delay();
	SDA = 0;
	delay();
}


//终止信号
void stop()
{
     
    SDA = 0;
	delay();
	SCL = 1;
	delay();
	SDA = 1;
	delay();
}

//应答信号
void respons()
{
     
  uchar i;
	SCL = 1; //高电平(数据稳定,允许读数据)
	delay();
	
   /*收到应答信号(SDA会被置0,表示数据总线被应答数据占用),或者时间超   过,才退出while循环*/
	while( (SDA == 1) && (i < 250) ) i++;  
	
	/*第九个时钟结束(一个字节8位数据传输完毕,第九位是应答信号);把SCL置为0,允许数据变化,不能读数据*/
	SCL = 0; 
	delay();	
}

void init()
{
     
	SDA = 1; //初始化数据总线为空闲
	SCL = 1; //初始化时钟总线为数据稳定,可读数据
}

//写入一个字节--8位
void write_byte(uchar date)
{
     
	 uchar i,temp;
	 temp = date;

	 for(i = 0;i < 8;i++)
	 {
     
	 //左移一位就把最高位移到了CY中(CY是左移的溢出位,temp的最高位)
		 temp = temp << 1; 
		 SCL = 0; //允许数据改变
	     delay();
		 
		 SDA = CY; //把左移溢出的一位数据写入SDA数据总线中
		 delay();
		 
       //写好数据到指定地址之后,把SCL置1,不允许变化,把数据稳定一段时间,然后进行下一个位的写操作。
		 SCL = 1; 
		 delay();
	 }
	 
	 SCL = 0; //允许SDA数据变化,等待回应数据到来
	 
	 //等待回应
	 SDA = 1; //数据总线被释放,等待应答信号占领总线
	 delay();
}

uchar read_byte()
{
     
	uchar i,j,k;
	
	SCL = 0; //允许SDA传输数据,数据变化
	delay();
	
	SDA = 1; //让数据总线处于空闲状态,允许数据传输
	delay();
	for(i = 0;i < 8;i++)
	{
     
		SCL = 1; //SCL置为1,让数据稳定一段时间后,才可以读取数据
		delay();
		
		/* K左移之后最低位补为0;SDA要么为0要么为1,按位或之后,就可以把SDA放入K的最低位*/
		k = (k << 1) | SDA; 
		
		SCL = 0; //允许数据改变,以便读取数据总线SDA上面的下一位数据
		delay();
	}
	return k;
}

void main()
{
     
	init();
	
    wirte_add(23,0xaa);
	  delay1(100); //必须要延时,否则写和读操作间隔太短,机器反应不过来
	P1 = read_add(23);

	while(1);
	
}


你可能感兴趣的:(51单片机学习之路)