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

51单片机学习之路 专栏收录该内容
6 篇文章 5 订阅

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

#include <reg52.h>
#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);
	
}


  • 2
    点赞
  • 1
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值