⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 I2C总线读写程序,C51单片机读写,很好用的.
💻 C
字号:
/*****************************************/
/* Copyright (c) 2005, 通信工程学院      */
/* All rights reserved.                  */
/* 作    者:戴 佳				  	     */
/*****************************************/
/* 延时约5微秒,对于12M时钟 */
#include <at898252.h>

#define uint unsigned int
#define uchar unsigned char
//I2C总线位定义////////////////////////
sbit SDA = P2^3;			// 串行数据
sbit SCL = P2^2;			// 串行时钟
bit  fb;
uchar idata SLAdd;    		// 从器件地址0X9A
uchar idata sbuf[8];   		// 数据发送缓冲区
uchar idata rbuf[8];   		// 数据接收缓冲区
bit   bdata NACK;    		// 器件坏或错误标志位
bit   bdata nackFlag;   	// 非应答标志位


void delay5us()
{
	uint i;
	for (i=0;i<12;i++)
		_nop_();	
}

/* 起始条件子函数 */
void start(void)
{
	SDA = 1;SCL = 1;			// 启动I2C总线
	delay5us();
	SDA = 0;
	delay5us();
	SCL = 0;
}

/* 停止条件子函数 */
void stop(void)
{
	SDA = 0;SCL = 1;			// 停止I2C总线数据传送
	delay5us();
	SDA = 1;
	delay5us();
	SCL = 0;
}

/* 发送应答子函数 */
void ack(void)
{
	SDA = 0;			// 发送应答位
	SCL = 1;
	delay5us();
	SDA = 1;
	SCL = 0;
}

/* 发送非应答子函数 */
void n_ack(void)
{
	SDA = 1;			// 发送非应答位
	SCL = 1;
	delay5us();
	SDA = 0;
	SCL = 0;
}

/* 应答位检查子函数 */
void checkack(void)
{ 
	SDA = 1;    		// 应答位检查(将p1.0设置成输入,必须先向端口写1)
	SCL = 1;
	nackFlag = 0;
	if(SDA == 1)    	// 若SDA=1表明非应答,置位非应答标志F0
	nackFlag = 1;
	SCL = 0;
}

/* 发送一个字节数据子函数 */
void sendbyte(uchar idata *ch)
{ 
	uchar idata n = 8;  
	uchar idata temp;
	temp = *ch;
	while(n--)
	{ 
		if((temp&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
		{
			SDA = 1;    // 传送位1
			SCL = 1;
			delay5us();
			SDA = 0;
			SCL = 0;    
		}
		else
		{  
			SDA = 0;    // 否则传送位0
			SCL = 1;
			delay5us();
			SCL = 0;  
		}
		temp = temp<<1;    // 数据左移一位
	}
}

/* 接收一字节子程序 */
void recbyte(uchar idata *ch)
{
	uchar idata n=8;    // 从SDA线上读取一位数据字节,共8位
	uchar idata temp = 0;
	while(n--)
	{
		SDA = 1;
		SCL = 1;
		temp = temp<<1;    // 左移一位
		if(SDA == 1)
			temp = temp|0x01;    // 若接收到的位为1,则数据的最后一位置1
		else 
			temp = temp&0xfe;    // 否则数据的最后一位置0
		SCL=0;
	}
	*ch = temp;
}

/* 发送n字节数据子程序 */
/*void sendnbyte(uchar idata *sla, uchar n)
{          
	uchar idata *p;
	start();				// 发送启动信号
	sendbyte(sla);    		// 发送从器件地址字节
//	checkack();    			// 检查应答位
//    if(F0 == 1)
//	{ 
//		NACK = 1;
//		return;    		// 若非应答表明器件错误或已坏,置错误标志位NACK
///	}
	p = sbuf;
	while(n--)
	{ 
		sendbyte(p);
		checkack();    	// 检查应答位
		if (nackFlag == 1)
		{
			NACK=1;
			return;    	// 若非应答表明器件错误或已坏,置错误标志位NACK
		}
		p++;
	}
	stop();    			// 全部发完则停止
}
*/
/* 接收n字节数据子程序 */
void recnbyte(uchar idata *sla, uchar n)
{ 
	uchar idata *p;
	start();			// 发送启动信号
	sendbyte(sla);		// 发送从器件地址字节
//	checkack();			// 检查应答位
//	if(nackFlag == 1)
//	{
//		NACK = 1;
//		return;
//	}
	p = rbuf;			// 接收字节存放在rbuf中
	while(n--)
	{ 
		recbyte (p);
		ack();    		// 收到一个字节后发送一个应答位
		p++;
	}
	n_ack();    		// 收到最后一个字节后发送一个非应答位
	stop();
}
/* 主函数,模拟实现I2C总线的数据收发 */
void REDI2C(void)
{
	uchar i, numbyte;
	numbyte =2;
 
	SLAdd = 0x9a;//9b;//0x58;		// 从器件地址
	recnbyte(&SLAdd,numbyte);	// 由从器件接收8字节数据,存放在rbuf中
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -