STC89C52_模拟IIC通讯驱动

写的不知道好不好,有什么不对的地方还请指出,谢了。

1、对于IIC通讯,我觉的有2种通讯方案。

    方案1:每次函数结束后未释放SDA线,且SCL=1;

    方案2:每个函数结束后释放SDA线,且SCL=0;

    本次采用方案1,方案2有时间在试试。

2、对于IIC时序,也就6种:开始信号、结束信号、写1字节、读1字节、接收ACK、发送ACK/NO_ACK

3、由于AT24C02IIC通讯时序很快,51单片机软件模式IIC时序速度慢,故,不用延迟就可以,在这里我均延迟了5us时间。

4、这只是IIC驱动,后面在贴AT24C02驱动代码。

#ifndef __IIC_H__
#define	__IIC_H__

#include <reg52.h>

sbit SCL = P2^1;//时钟连接P2.1口
sbit SDA = P2^0;//时钟连接P2.0口

void START_IIC(void);//1、IIC开始信号
void STOP_IIC(void);//2、结束IIC通讯

//器件的地址共计7位,第8位为0表示要写数据给设备
//为1表示要读取设备的数据
void write_1_byte_IIC(unsigned char);//3、写1字节数据
unsigned char read_1_byte_IIC(void); //4、读取1字节数据
bit read_ACK_IIC(void);//5、读取ACK信号,为1表示no-ack 为0表示ack
void write_ACK_IIC(bit);//6、主机发送ACK信号,为1表示no-ack 为0表示ack

#endif // !__IIC_H__
#include "delay.h"
#include "iic.h"
//金丝草;使用iic通讯方案1
//方案1:每个函数结束后未释放SDA线,且SCL=1; STOP信号均为高。起始前面处理一下
//方案2:每个函数结束后释放SDA线,且SCL=0;STOP信号均为高。后面信号处理一下。
//本次采用方案1
//1、IIC开始信号
void START_IIC(void)
{
	SCL = 0;
	SDA = 1;
	delay_5us();
	SCL = 1;
	delay_5us();
	SDA = 0;
	delay_5us();
}

//2、IIC结束信号
void STOP_IIC(void)
{
	SCL = 0;
	SDA = 0;
	delay_5us();
	SCL = 1;
	delay_5us();
	SDA = 1;
	delay_5us();
}

//器件的地址共计7位,第8位为0表示要写数据给设备
//为1表示要读取设备的数据
//3、IIC写数据
void write_1_byte_IIC(unsigned char datax)
{
	unsigned char i;
	for (i = 0x80;i != 0;i >>= 1)
	{
		SCL = 0;
		delay_5us();
		if ((datax & i) == i)  //马来逼,这个地方原始数据为datax&i==1  &的结果为16进制应该与i比较,并且&没有==优先级高
			SDA = 1;
		else
			SDA = 0;
		delay_5us();
		SCL = 1;
		delay_5us();
	}
}

//4、IIC读数据 
unsigned char read_1_byte_IIC(void) //读取1字节数据
{
	unsigned char i;
	unsigned char datax = 0;
	for (i = 0x80;i != 0;i >>= 1)
	{
		SCL = 0;
		SDA = 1;  //释放SDA线
		delay_5us();
		SCL = 1;
		delay_5us();
		if (SDA)
			datax |= i;//读取SDA线上的数据
		delay_5us();
	}
	return(datax);
}

//5、读取接收ACK应答信号
bit read_ACK_IIC(void)
{
	bit ACK = 0;
	SCL = 0;
	SDA = 1;
	delay_5us();
	SCL = 1;
	delay_5us();
	ACK = SDA;	
	return(ACK);//如果ACK=1,则未收到应答   //如果ACK=0,则收到应答
}

//6、发送应答ACK信号
void write_ACK_IIC(bit ACK)
{
	SCL = 0;
	SDA = ACK; //ACK=1,表示不发送应答,=0表示发送应答
	delay_5us();
	SCL = 1;
	delay_5us();
}

猜你喜欢

转载自blog.csdn.net/qq_44829055/article/details/107430003
今日推荐