📄 iic.c
字号:
#include <pic.h>
/****************************************
iic引脚功能定义
****************************************/
#define WP RC1
#define SCL RC3
#define SDA RC4
/***************************************************************************************
全局变量说明
**************************************************************************************/
unsigned char ACK; //应答标志
/********************************************************************
功 能:延时
说 明:i=1为24us ,2为34us,3为44us
入口参数:unsigned char i
***********************************************************************/
void delay(unsigned char i) //延时
{
while(i--)
{
NOP();
CLRWDT();
NOP();
NOP();
}
}
///////////////////////////////////////////////////////////////////////////////
////// I2C总线在标准的方式下最高时钟为100KHZ, ///////
////时钟信号最小低电平时段为4.7us,高电平时段不得小于4us. ///////
////(1) 只有在总线空闲时才允许启动数据伟送 ///////
////(2) 在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态 ///////
////不允许有跳变。否将看作总线的起始或停止 ///////
///////////////////////////////////////////////////////////////////////////////
/********************************************************************
功能: I2C开始
说明:时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C总路线的起始信号
********************************************************************/
void iic_start (void)
{
TRISC3=1; //置输入
TRISC4=1;
NOP();
TRISC3=1; //在至少4u秒期间SDA从高电平到低电平
NOP();
NOP();
NOP();
SDA=0;
TRISC4=0;
NOP();
NOP();
NOP();
SCL=0;
TRISC3=0;
NOP();
NOP();
}
/*************************************************************
功能: I2C结束
说明:时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C的停止信号
*************************************************************/
void iic_stop(void)
{
SDA=0;
TRISC4=0; //置输出
NOP();
NOP(); //在至少4u秒期间SDA从低电平到高电平
TRISC3=1;
NOP();
NOP();
NOP();
TRISC4=1;
NOP();
NOP();
NOP();
SCL=0;
TRISC3=0;
NOP();
NOP();
TRISC3=1;
}
/**********************************************************
功能: 检查应答信号
备注: 每成功地传送一个字节数据后,接收器都必须产生一个应答
信号。应答的器件在第9个时钟周期时将SDA线拉低,表示其已收到
一个8位数据
说明: ACK为0说明发送成功,否为错
******************************************************/
unsigned char iic_check(void)
{
TRISC4=1;
SCL=0;
TRISC3=0;
NOP();
NOP();
TRISC3=1;
if (SDA)ACK = 1;
else ACK = 0;
SCL=0;
TRISC3=0;
return(ACK);
}
/******************************************************
功能:主器件向从器件发送一个字节,同时检查从器件应答位
说明:入口参数是DATA,是将要发送到从器件的数据
数据是高位先发,即用左移一位<<1
***********************************************************/
void iic_send(unsigned char data)
{
unsigned char bitcount=8; //发送8位
do
{
SCL=0;
TRISC3=0; //置输出
if((data&0x80)==0x80) TRISC4=1; //发送 1
else
{
SDA=0; //发送 0
TRISC4=0;
}
TRISC3=1;
NOP();
NOP();
NOP();
NOP();
NOP();
SCL=0;
TRISC3=0;
data<<=1;
bitcount--;
} while(bitcount);
TRISC4=1 ; //释放总线等待应答
NOP();
NOP();
NOP();
NOP();
NOP();
}
/*************************************************************
功能: 接受一个字节
*************************************************************/
unsigned char iic_recive(void)
{
unsigned char temp1=0;
unsigned char bitcount1=8;
TRISC4=1; //置输入
SCL=0;
TRISC3=0;
do
{
TRISC3=1;
NOP();
NOP();
NOP();
NOP();
if(SDA) //读 1
{
temp1=temp1|0x01;
}
else //读 0
{
temp1=temp1&0xfe;
}
SCL=0;
TRISC3=0;
if(bitcount1-1)
{
temp1<<=1;
}
bitcount1--;
}while(bitcount1);
return(temp1);
}
//停止继续读
void iic_nack(void)
{
SCL=0;
TRISC3=0;
TRISC4=1;
TRISC3=1;
NOP();
NOP();
NOP();
NOP();
NOP();
SCL=0;
TRISC3=0;
}
/*********************************************************
功能: 给24LC01写数据
备注: address:是待写入首地址 采用连续写模式
*********************************************************/
void iic_writebyte(unsigned address)
{
unsigned char i,j;
CLRWDT();
iic_start(); //起始信号
iic_send(0xa0); //写从器件识别地址00xa0;0xa2;0xa4;0xa6;0xa8;0xaa;0xac;0xae;
for(i=10;i>0;i--)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
iic_send(address); //0x00--0xff;
for(i=10;i>0;i--)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
CLRWDT();
for(j=0;j<16;j++) //hour[j]连续存入
{
iic_send(MM[j]); //发送数据
for(i=0;i<10;i++)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
}
CLRWDT();
iic_stop(); //停止
delay(100); //延时,下次发数据
}
/*******************************************************************
功能: 从24C01中读数据
*******************************************************************/
unsigned char iic_readbyte(unsigned char address)
{
unsigned char pdata,i;
NOP();
CLRWDT();
iic_start(); //开始
iic_send(0xa0); //写主控器识别地址(写)
for(i=10;i>0;i--)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
iic_send(address); //送地址
for(i=10;i>0;i--)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
iic_start(); //开始读数据
iic_send(0xa1); //写主控器识别地址(读)
for(i=10;i>0;i--)
{
CLRWDT();
if(iic_check()==0) break;
NOP();
NOP();
NOP();
NOP();
NOP();//10ms扬时
}
CLRWDT();
pdata=iic_recive();
iic_nack();
iic_stop();
return pdata;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -