📄 iic.c
字号:
//=================================================================
//
//IIC.C开始
//
//=================================================================
//===========================================================
extern unsigned int *P_IOB_Data;
extern unsigned int *P_IOB_Dir;
#define Set_IIC_SCL 0x0001 //IOB0 SCL
#define Clear_IIC_SCL 0xfffe
#define Set_IIC_SDA 0x0002 //IOB1 SDA
#define Clear_IIC_SDA 0xfffd
void IIC_Start(void); //启动信号
void IIC_Stop(void); //停止信号
void IIC_Ack(void); //应答信号
void IIC_Unack(void); //非应答信号
unsigned int IIC_Cack(void); //应答信号检测
void IIC_Wrbyte(unsigned int data); //写一字节
unsigned int IIC_Rdbyte(void); //读一字节
void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N);//写N字节
void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N);//读N字节
//===========================================================
//===========================================================
//函数名称:void Delay1us(unsigned int counter)
//函数功能:延时1us
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void delay1us(unsigned int counter)
{
unsigned int i;
for(;counter>0;counter--)
for(i=20;i>0;i--);
}
//===========================================================
//===========================================================
//函数名称:void IIC_Start(void)
//函数功能:IIC的启动信号 时序:在SCL高电平期间SDA发生负跳变
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Start(void)
{
unsigned int IOB;
IOB=*P_IOB_Data; //SDA=1
IOB=IOB|Set_IIC_SDA;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
delay1us(6);
IOB=*P_IOB_Data; //SDA=0
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB;
delay1us(5);
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
}
//===========================================================
//===========================================================
//函数名称:void IIC_IIC_Stop(void)
//函数功能:IIC的启动信号 时序:在SCL高电平期间SDA发生正跳变
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//============================================================
void IIC_Stop(void)
{
unsigned int IOB;
IOB=*P_IOB_Data; //SDA=0
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
delay1us(5);
IOB=*P_IOB_Data; //SDA=1
IOB=IOB|Set_IIC_SDA;
*P_IOB_Data=IOB;
delay1us(6);
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SDA=0
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB;
}
//===========================================================
//===========================================================
//函数名称:void IIC_Ack(void)
//函数功能:IIC的启动信号 时序:在SDA负电平期间SCL发生一个正脉冲
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Ack(void)
{
unsigned int IOB;
IOB=*P_IOB_Data; //SDA=0
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
delay1us(5);
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SDA=1
IOB=IOB|Set_IIC_SDA;
*P_IOB_Data=IOB;
}
//===========================================================
//===========================================================
//函数名称:void IIC_Unack(void)
//函数功能:IIC的启动信号 时序:在SDA高电平期间SCL发生一个正脉冲
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Unack(void)
{
unsigned int IOB;
IOB=*P_IOB_Data; //SDA=1
IOB=IOB|Set_IIC_SDA;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
delay1us(5);
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SDA=0
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB;
}
//===========================================================
//===========================================================
//函数名称:unsigned int IIC_Cack(void)
//函数功能:IIC的应答位检测子程序
//输入参数:无
//输出参数:正常应答返回0,否则返回1
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
unsigned int IIC_Cack(void)
{
unsigned int IOB;
unsigned int result;
IOB=*P_IOB_Dir; //SDA为输入线
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Dir=IOB;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
if(*P_IOB_Data&Set_IIC_SDA)
result=1; //非正常应答返回1
else
result=0; //正常应答返回0
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Dir; //SDA为输出线
IOB=IOB|Set_IIC_SDA;
*P_IOB_Dir=IOB;
return result;
}
//===========================================================
//===========================================================
//函数名称:void IIC_Wrbyte(unsigned int data)
//函数功能:IIC的发送一字节子程序
//输入参数:要发送的数据
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void IIC_Wrbyte(unsigned int data)
{
unsigned int i;
unsigned int IOB;
data=data<<8; //数据整体左移八位
for(i=8;i>0;i--)
{
IOB=*P_IOB_Data;
if(data&0x8000)
IOB=IOB|Set_IIC_SDA;
else
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Data=IOB; //送数据位到SDA
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
data=data<<1;
}
}
//===========================================================
//===========================================================
//函数名称:unsigned int IIC_Rdbyte(void)
//函数功能:从IIC总线上读取一字节的数据
//输入参数:无
//输出参数:从IIC总线上读取一字节的数据
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
unsigned int IIC_Rdbyte(void)
{
unsigned int i;
unsigned int IOB;
unsigned int result=0;
IOB=*P_IOB_Dir; //SDA为输入线
IOB=IOB&Clear_IIC_SDA;
*P_IOB_Dir=IOB;
for(i=8;i>0;i--)
{
IOB=*P_IOB_Data;
if(IOB&Set_IIC_SDA)
result=result|0x0001;
result=result<<1;
IOB=*P_IOB_Data; //SCL=1
IOB=IOB|Set_IIC_SCL;
*P_IOB_Data=IOB;
IOB=*P_IOB_Data; //SCL=0
IOB=IOB&Clear_IIC_SCL;
*P_IOB_Data=IOB;
}
result=result>>1;
IOB=*P_IOB_Dir; //SDA为输出线
IOB=IOB|Set_IIC_SDA;
*P_IOB_Dir=IOB;
return result;
}
//===========================================================
//===========================================================
//函数名称:void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N)
//函数功能:从IIC总线上写N字节的数据
//输入参数:Addr为器件地址,*P为要写数据的起始地址,N为要写的数据的字节数
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N)
{
IIC_Start();
//启动IIC总线
do
{
IIC_Wrbyte(Addr); //发送器件地址和写命令
}while(IIC_Cack!=0);
for(;N>0;N--) //发送N字节数据
{
do
{
IIC_Wrbyte(*P);
}while(IIC_Cack()!=0); //等待发送完成
P++;
}
IIC_Stop(); //停止IIC总线
}
//===========================================================
//===========================================================
//===========================================================
//函数名称:void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N)
//函数功能:从IIC总线上读取N字节的数据
//输入参数:*P为要读取数据的起始地址Addr为器件地址,N为要读取的数据的字节数
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N)
{
//unsigned int IOB;
IIC_Start(); //启动IIC总线
do
{
IIC_Wrbyte(Addr); //发送器件地址和写命令
}while(IIC_Cack!=0);
for(;N>0;N--) //读N字节数据
{
do
{
*P=IIC_Rdbyte();
}while(IIC_Cack()!=0); //等待读完成
P++;
}
IIC_Unack();
IIC_Stop(); //停止IIC总线
}
//===========================================================
//=================================================================
//
//IIC.C结束
//
//=================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -