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

📄 i2c.c

📁 I2c的通信协议 主控端。 没有写从端。不好意思
💻 C
字号:
/*
//+-------------------------------------------------------------------------
//  Project: 8051 core
//  Module:  I2c 主模式
//
//  File:       i2c.c
//
//  Contents:   iic的一些基本操作函数
//              
//  Useage :    具体函数参见函数头
//
//
//  History:    Thursday, July 14, 2005 1:06:34 PM 建立基本方法(肖轶翔)
//  
//	ver:0.9bata
//--------------------------------------------------------------------------
//  备注:      参见核心板原理图,P1.6=SCL;P1.7=SDA;晶震应该小于12m
//				+数据寄存器 S1DAT 接收发送数据用
//				+控制寄存器 S1CON 用于硬件I2C 的设置使能启动结束
//				+状态寄存器 S1STA 指示I2C 总线的操作状态码
//				若I2C 中断志置位可查询此寄存器判断总线情况
//
//  S1CON说明:
//			=0xc5 启动/清除SI
//			=0xd5 停止位
//			=0XC1 发送无应答位
//			=0XE5 重启总线
//
//	等待解决的问题:
//			可能在等待应答时,系统会等待响应,所以可能在以后要加上看门狗。
*******************************************************************/
#include "REG552.h" 
#define uchar unsigned char


/////[7/14/2005]///////////////////////////////////////////////////////////
///功能:申请总线
///函数原形:void GetBus()
///return null
///说明:
///by 肖轶翔[7/14/2005]
void GetBus()
{
	S1CON=0xc5; //启动i2c BUS
	STA=1; //申请成为主机并起动总线
	while(SI==0); //等待起始位的发送(参见TP38.1 Z198 p.189.)
}


///功能:向总线发送数据
///函数原形:void SendByte(uchar c)
///uchar c 要发送的byte
///return null
///by 肖轶翔[7/14/2005]
void SendByte(uchar c)
{
	S1DAT=c;
	S1CON=0Xc5; //清除SI 位
	while(SI==0); //等待起始位的发送
}

///功能:向无子地址器件发送字节数据
///函数原形:bit ISendByte(uchar sla,uchar c)
///		uchar sla 器件地址
///		uchar c   要发送的数据
/// return bit   return 1表成功发送
///by 肖轶翔[7/14/2005]
bit ISendByte(uchar sla,uchar c)
{
	GetBus(); 
	SendByte(sla); //发送器件地址
	if(S1STA!=0X18){//无应答则返回
		S1CON=0XD5;
		return(0);
		}
	SendByte(c); //发送数据
	/*
	0x28=b101000   
	*/
	if(S1STA!=0X28){
		S1CON=0XD5;
		return(0);
	}
	S1CON=0XD5;
	return(1);
}

///功能:向有子地址器件发送多字节数据
///函数原形:bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
///		uchar sla 器件地址
///		uchar suba 发送子地址
///		ucahr *s 发送数据
///		uchar no 数据字节数
///	return bit =1 表示成功
/// by 肖轶翔[7/14/2005]
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	GetBus(); 
	SendByte(sla); 
	if(S1STA!=0X18){
		S1CON=0XD5;
		return(0);
	}
	SendByte(suba); //发送子地址
	if(S1STA!=0X28){
		S1CON=0XD5;
		return(0);
	}
	for(i=0;i<no;i++){
		SendByte(*s); /*发送数据*/
		if(S1STA!=0X28){
			S1CON=0XD5;
			return(0);
		}
		s++;
	}
	S1CON=0XD5; 
	return(1);
}

///功能:向无子地址器件读字节数据
///函数原形:bit IRcvByte(uchar sla,uchar *c)
///		uchar sla 地址
///		uchar *c 读出数据放在这里
///		return bit=1表成功
/// by 肖轶翔[7/14/2005]
bit IRcvByte(uchar sla,uchar *c)
{
	GetBus(); 
	SendByte(sla+1); //发送器件地址(这里+1的理由,见Z198的page 212)
	if(S1STA!=0X40){
		S1CON=0XD5;
		return(0);
	}
	S1CON=0XC1; //接收一字节数据即发送非应答位
	while(SI==0); //等待接收数据
	if(S1STA!=0X58){
		S1CON=0XD5;
		return(0);
	}
	*c=S1DAT; //读取数据
	S1CON=0XD5; 
	return(1);
}

///功能:向有子地址器件读取多字节数据
///函数原形:bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
///		uchar sla 器件地址
///		uchar suba 子地址
///		ucahr *s 读入的内容
///		uchar no 读多少字节
///		retrun bit=1表成功
/// by 肖轶翔[7/14/2005]
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	GetBus(); 
	SendByte(sla); 
	if(S1STA!=0X18){
		S1CON=0XD5;
		return(0);
	}
	SendByte(suba);
	if(S1STA!=0X28){
		S1CON=0XD5;
		return(0);
	}
	S1CON=0XE5; //重新启动总线
	while(SI==0);
	SendByte(sla+1);//立即地址读取
	if(S1STA!=0X40){
		S1CON=0XD5;
		return(0);
	}
	for(i=0;i<no-1;i++){
		S1CON=0XC5; //接收一字节数据并发送应答位
		while(SI==0); //等待接收数据
		if(S1STA!=0X50){
			S1CON=0XD5;
			return(0);
		}
		*s=S1DAT; //读取数据
	s++;
	}
	/*
		这里要牵涉寻址问题,在Z198的212页有,属于随即地址读取,最后一位不应答,最后加停止位
	*/
	S1CON=0XC1; //接收最后一字节数据并发送非应答位
	while(SI==0);
	*s=S1DAT;
	S1CON=0XD5; //停止位
	return(1);
}

⌨️ 快捷键说明

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