IIC

IIC总线


//程序


#include <REG51.h>
#include <intrins.h>
#define uc unsigned char
uc a;
//IIC总线串行数据线
sbit SDA=P1^0;
//IIC总线串行时钟线
sbit SCL=P1^1;
sbit AS=P1^2;
sbit AB=P1^3;
bit NackFlag;
//延时子程序,大约延时5us
void delay()
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}
//延时子程序,延时大约count ms
void DelayX1ms(uc count)
{
	uc i,j;
	for(i=0;i<count;i++)
	{
		for(j=0;j<120;j++);
	}

}

//启动IIC总线
void start(void)
{
	SDA=1;
	SCL=1;
	delay();
	SDA=0;
	delay();
	SCL=0;
}

//停止IIC总线
void stop(void)
{
	SDA=0;
	SCL=1;
	delay();
	SDA=1;
	delay();
	SCL=0;
}

//检查应答位子函数
void chkAck(void)
{
	SDA=1;
	SCL=1;
	NackFlag=0;
	if(SDA==1)		//SDA==1表示器件没有应答
		NackFlag=1;	//置位非应答标志NackFlag
	SCL=0;

}

//发送8bit(1字节)数据子函数
void send8bit(uc num)
{
	uc i=8;
	uc temp;
	temp=num;
	for(i=8;i>0;i--) //根据IIC协议应从最高位开始发
	{
		SDA=temp&0x80;
		SCL=1;
		delay();
		SDA=temp&0x80;
		SCL=1;
		delay();
		SCL=0;
		temp=temp<<1; //待发数据左移,准备发送下一位
	}
}

//发送1字节数据到从器件子程序
void sendbyte(uc num,uc addr,uc N)
{
	//启动IIC总线
	start();
	//发送从器件地址
	send8bit(N);
	//检查应答位,每发送一字节都要检查应答位
	chkAck();
	//发送数据地址
	send8bit(addr);
	chkAck();
	//发送待发数据
	send8bit(num);
	chkAck();
	stop();
	//全部发送完毕后停止
	DelayX1ms(10);
}

unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
    uc i;
    uc Data;       //定义一个缓冲寄存器。
    for(i=0;i<8;i++)//有8位数据
    {
        SCL=1;//拉高时钟线,为读取下一位数据做准备。
        delay();
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
        delay();
        
        if(SDA)//如果数据线为高平电平。
            Data=Data|0x1;//则给缓冲字节的最低位写1。
        SCL=0;//拉低时钟线,为读取下一位数据做准备。
        delay();
    }
    return Data;//返回读取的一个字节数据。
}


uc IIC_single_byte_read(uc Daddr,uc Waddr)
{//从任意地址读取一个字节数据函数
    uc Data;//定义一个缓冲寄存器。

    start();//产生起始信号
    send8bit(Daddr);//写入设备地址(写)
    chkAck();//等待设备的应答
    send8bit(Waddr);//写入要操作的单元地址。
    chkAck();//等待设备的应答。
    
    start();//产生起始信号
    send8bit(Daddr+1);//写入设备地址(读)。之所以加1,见24c02资料,最后一位为R/(/w),从24c02读,最后一位为1;向24c02写,最后一位为0
    chkAck();//等待设备的应答。 
    Data=IIC_read_byte();//写入数据。
    stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}
//初始化串口
void serial_port_initial()//
{
    PCON=0x00; //波特率bu加倍
    SCON    =   0x50;   //0101,0000 8位可变波特率,无奇偶校验位
    TMOD    =   0x20;   //0011,0001 设置定时器1为8位自动重装计数器
    TH1     =   0xfd;   //设置定时器1自动重装数   9600bps@11.0592MHz
    TL1     =   0xfd;
    ES      =   0;    //串口中断关闭
    ET1     =   0;    //定时器1中断关闭
    TR1     =   1;    //打开串口
    EA      =   0;    //关总中断
}



//主函数,实现IIC总线的数据发送
void main(void)
{
	unsigned char i,Da,d=0xff;
	serial_port_initial();//初始化串口

	//按要求产生并循环发送所有待发送的数据
	for(i=0;i<0xff;i++)
	{
		//向从器件发送一字节数据
		sendbyte(0xff,i,0xae);
		DelayX1ms(5);
	}

	//按要求产生并循环发送所有待发送的数据
	for(i=0;i<0xff;i++)
	{
		//向从器件发送一字节数据
		sendbyte(0x05,i,0xa0);
		DelayX1ms(5);
	}
		for(i=0;i<0xff;i++)
	{
		Da=IIC_single_byte_read(0xa0 , i);
		SBUF=Da;
		if((Da&0x01)!=0x01)
			AS=1;
		else
			AS=0;
	}
	while(1)
	{;}//发送完毕,停止等待

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值