📄 wri2c.c
字号:
#ifndef WRI2C_C
#define WRI2C_C
#include "config.h"
#define IIC_24C01 0
#define IIC_24C02 0
#define IIC_24C04 0
#define IIC_24C16 0 //2K bytes
#define IIC_24C32 1
#define IIC_24C64 1
#define IIC_24C128 1
#define IIC_24C256 1
//定义对24C16访问的页,共8页,每页256个字节,每次页读、写可操做16个字节
#define C16_PAGE1 0
#define C16_PAGE2 2
#define C16_PAGE3 4
#define C16_PAGE4 6
#define C16_PAGE5 8
#define C16_PAGE6 10
#define C16_PAGE7 12
#define C16_PAGE8 14
/*==============================
;本程序应用于有,无高位子地址的IIC器件,通过SubAddrHiBit设定
;bit SubAddrHiBit=1说明器件为16位数据地址,=0说明器件为8位数据地址。
================================*/
//延时:用于w77e58,18.432M ,每指令=4/18.432=0.217us
void F1us(void){
nop();nop();nop();nop();nop();nop();
}
void F5us(void){
uchar x=2;
while(x--){
F1us();
F1us();
F1us();
F1us();
F1us();
}
}
void Delay10us(uchar x){
while(x--){
F5us();
F5us();
}
}
void Delay1ms(uchar x){
while(x--){
Delay10us(100);
}
}
//extern void F1us(void); //产生1us的延时时间
//extern void Delay5us(register uchar x); //5us延时
//extern void Delay10us(register uchar x); //10us延时
//extern void Delay1ms(register uchar x); //1ms延时
//#define F5us() Delay5us(1)
/********************************
功能:i2c总线启动程序
入口:无
出口:无
反回:无
日期:03-9-29
***********************************/
void Start_I2c(void){
pinSDA=1;F1us();
pinSCL=1;F5us(); //发送起始条件的数据信号,发送起始条件的时钟信号
pinSDA=0;F5us(); //发送起始信号
pinSCL=0;F1us();F1us(); //钳住i2c 总线准备发送或接收数据
}
/*********************************
描述:停止i2c 总线子程序--发送i2c 总线停止条件
入口:无
出口:无
反回:无
日期:03-9-29
**********************************/
void Stop_I2c(void){
pinSDA=0;F1us(); //发送结束条件时钟信号
pinSCL=1;F5us(); //发送停止条件的数据信号,发送停止条件的时钟信号
pinSDA=1;F5us(); //发送i2c 总线停止信号
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
bit SendByte(uchar c)small{
uchar idata BitCnt=8;
bit bdata ack;
while(BitCnt--){ /*要传送的数据长度为8位*/
if(c&0x80)pinSDA=1; /*判断发送位*/
else pinSDA=0;
c<<=1;
pinSCL=1; /*置时钟线为高,通知被控器开始接收数据位*/
F5us();
pinSCL=0;
}
F1us(); F1us();
pinSDA=1; /*8位发送完后释放数据线,准备接收应答位*/
F1us();F1us();
pinSCL=1;
F1us();F1us();F1us();
if(pinSDA==1)ack=0;
else ack=1; /*判断是否接收到应答信号*/
pinSCL=0;
F1us(); F1us();
return (ack);
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte(){
uchar idata retc=0;
uchar idata BitCnt;
pinSDA=1; /*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++) {
F1us();
pinSCL=0; /*置时钟线为低,准备接收数据位*/
F5us();
pinSCL=1; /*置时钟线为高使数据线上数据有效*/
F5us();
retc=retc<<1;
if(pinSDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
F1us();F1us();
}
pinSCL=0;
F1us();
F1us();
return(retc);
}
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a){
if(a==0)pinSDA=0; /*在此发出应答或非应答信号 */
else pinSDA=1;
F5us();
pinSCL=1;
F5us();
pinSCL=0; /*清时钟线,钳住I2C总线以便继续接收*/
F1us();F1us();
}
/*************************************
描述:发送bytecnt 个字节给被控器,
发送的数据在以xmtdat的内容为地址的缓冲区中
入口:uchar slvadr,subadr_hi,subadr_low,SlvAdr,byteCnt,xmtdat
出口:无
反回:返回bit,=1发送数据正常,=0表示被控器无应答或损坏
全局:SubAddrHiBit(如器件单元地址为16位则置1,否则置0)
日期:04-7-1
*****************修正*******************
04-12-27:加SubAddrHiBit进行器件地址控制,及数据结构
**************************************/
bit SendDatai2c(bit SubAddrHiBit,uchar slvadr,uchar ByteCount,uchar SadrHi,uchar SadrLow,uchar * xmtdat)
{
uchar i;
EnableWriteI2c(); //关闭写保护
Delay10us(5);
Start_I2c();
slvadr&=0xfe; //说明进行写操作
if(SendByte(slvadr)==0) //发送器件地址
goto Sendi2cFalse;
if(SubAddrHiBit) //发送单元地址hi
{
if(SendByte(SadrHi)==0)
goto Sendi2cFalse;
}
if(SendByte(SadrLow)==0) //发送单元地址low
goto Sendi2cFalse;
Delay1ms(6);
for(i=0;i<ByteCount;i++){ //发送缓冲区内的数据
if(SendByte(*xmtdat)==0)
goto Sendi2cFalse;
xmtdat++;
}
Stop_I2c(); //;发送i2c 总线停止条件
Delay1ms(10); //;延时10ms,等待数据写完
DisableWriteI2c(); //写保护
//TR2=1;
return(TRUE);
Sendi2cFalse:
//TR2=1;
DisableWriteI2c(); //写保护
return(FALSE);
}
/**********************************
描述:接收bytecnt 个到缓冲区,
接收的数据在以rcvdat的内容为地址的缓冲区
入口:uchar slvadr,subadr_hi,subadr_low,bytecnt,rcvdat
出口:无
全居:ByteCount,slvadr
反回:返回bit,=1发送数据正常,=0表示被控器无应答或损坏
全局:SubAddrHiBit(如器件单元地址为16位则置1,否则置0)
日期:04-7-1
*****************修正*******************
04-12-27:加SubAddrHiBit进行器件地址控制,及数据结构
************************************/
bit RcvDatai2c(bit SubAddrHiBit,uchar slvadr,uchar ByteCount,uchar SadrHi,uchar SadrLow,uchar * rcvdat)
{
uchar i;
//TR2=0; //在读I2C时不允许定时器2中断
pinSCL=1;
pinSDA=1;
Delay10us(5);
Start_I2c();
//说明进行写操作
if(SendByte(slvadr&0xfe)==0) //发送器件地址
goto Rcvi2cFalse;
if(SubAddrHiBit)
if(SendByte(SadrHi)==0) //发送单元地址hi
goto Rcvi2cFalse;
if(SendByte(SadrLow)==0) //发送单元地址low
goto Rcvi2cFalse;
Start_I2c(); /*重新启动总线*/
//进行读操做
if(SendByte(slvadr|1)==0)
goto Rcvi2cFalse;
for(i=0;i<ByteCount-1;i++){ //发送缓冲区内的数据
*rcvdat=RcvByte();
Ack_I2c(0); /*发送就答位*/
rcvdat++;
}
*rcvdat=RcvByte();
Ack_I2c(1); /*发送非应位*/
Stop_I2c();
Delay1ms(10);
//TR2=1;
return(TRUE);
Rcvi2cFalse:
//TR2=1;
Delay1ms(10);
return(FALSE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -