📄 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 + -