📄 i2c.c
字号:
#include "msp430x14x.h"
#include "i2c.h"
#define add_max 0x7f //EEPROM换页判断
extern void delay(unsigned int time);//延时子程序
/**********************************************************************/
//函数功能: Stop_I2总线,即发送I2C起始条件.
//函数原型: void Start_I2c(void);
//入口:无C(); //写入完毕停止总线
//出口:无
/**********************************************************************/
void Start_I2C(void);
void Start_I2C(void)
{
iic_port_ini(); //初始化SDA,SCL输出高电平
delay(250);
CLR_SDA(); //发送起始信号
delay(250); //起始条件锁定时间大于4μs
CLR_SCL(); //钳住I2C总线,准备发送或接收数据
delay(100);
}
/**********************************************************************/
//函数功能: 结束I2C总线,即发送I2C结束条件.
//函数原型: void Stop_I2c();
//入口:无
//出口:无
/**********************************************************************/
void Stop_I2C(void);
void Stop_I2C(void)
{
SDA_OUT();
CLR_SDA();
SET_SCL(); //发送结束条件的时钟信号,结束条件建立时间大于4μs
delay(250);
SET_SDA(); //发送I2C总线结束信号
delay(100);
}
/**********************************************************************/
//函数功能:将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
// 此状态位进行操作.(不应答或非应答都使ack=0)
// 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
//函数原型: void SendByte(uchar c);
//入口:c--要发送的数据
//出口:返回0表示未接到应答,1表示接到应答
/**********************************************************************/
unsigned char SendByte(unsigned char cc);
unsigned char SendByte(unsigned char cc)
{
unsigned char BitCnt;
unsigned int i=0;
SDA_OUT();
CLR_SCL();//拉低时钟
for(BitCnt=0;BitCnt<8;BitCnt++)
{
CLR_SCL();//拉低时钟
if((cc&0x80)==0x80)
SET_SDA();
else
CLR_SDA();
delay(100);
SET_SCL();
delay(100);
cc=cc<<1;
}
CLR_SCL();//8位发送完后释放数据线,准备接收应答位
delay(200);
SDA_IN();
SET_SCL();
BitCnt = 0;
while((SDA&IICPORTIN)==SDA)
{
i++;
if(i>500)
{
BitCnt=1;
break;
}
}
CLR_SCL();
SDA_OUT();
return BitCnt;
}
/**********************************************************************/
//函数功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
// 发完后请用应答函数应答从机。
//函数原型: uchar RcvByte();带参数返回
//入口:无
//出口:返回读取到的总线数据
/**********************************************************************/
unsigned char RcvByte(void);
unsigned char RcvByte(void)
{
unsigned char retc;
unsigned char BitCnt;
retc=0;
SDA_IN(); //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SET_SCL();//置时钟线为高使数据线上数据有效
delay(100);
retc<<=1;
if((SDA&IICPORTIN)==SDA)
retc=retc+1;//读数据位,接收的数据位放入retc中
CLR_SCL();
delay(100);
}
SDA_OUT(); //置数据线为输出方式
return(retc);
}
/**********************************************************************/
//函数功能: 主控器进行应答信号(可以是应答或非应答信号,由参数a决定)
// a=0不发送应答信号应答子函数
//函数原型: void Ack_I2c(uchar a);
//入口:a--决定是否要发送应答信号,a=0不发送应答信号应答子函数
//出口:无
/**********************************************************************/
void Ack_I2c(unsigned char aa);
void Ack_I2c(unsigned char aa)
{
SDA_OUT();
CLR_SCL();
if(aa==0) SET_SDA(); //在此发出应答或不发送应答信号
else CLR_SDA();
delay(100);
SET_SCL();
delay(100); //时钟低电平周期大于4μs
CLR_SCL(); //清时钟线,钳住I2C总线以便继续接收
}
/**********************************************************************/
//函数功能:写数据到EEPROM
//函数原型:void write_in(uint addr,uchar data)
//入口:eaddr-EEPROM片地址,addr--所要写入数据的地址,wdata_addr--所要写入的数据首地址,lenth所要写入数据长度
//出口:无
/**********************************************************************/
void write_in(unsigned char eaddr,unsigned int addr,unsigned char *wdata_addr,unsigned int lenth);
void write_in(unsigned char eaddr,unsigned int addr,unsigned char *wdata_addr,unsigned int lenth)
{
_DINT();
Start_I2C();//启动总线
SendByte(0xa0+eaddr);//外部地址+控制数据
SendByte(addr/256);//寻址EEPROM写命令,写入地址高低字节地址
SendByte(addr%256);
for(;lenth>0;lenth--)
{
SendByte(*wdata_addr);//写入数据
if((addr&add_max)==add_max)//换页判断
{
Stop_I2C();
delay(20000);
Start_I2C();//启动总线
SendByte(0xa0+eaddr);
SendByte((addr+1)/256);//寻址EEPROM写命令,写入地址高低字节地址
SendByte((addr+1)%256);
}
wdata_addr++;
addr++;
}
Stop_I2C();
delay(7000);
_EINT();
}
/**********************************************************************/
//函数功能:从EEPROM某个地址读出数据
//函数原型:void read_out(uint addr)
//入口:eaddr-EEPROM片地址,addr--所要读出数据的地址,rdata_addr--RAM中存放数据的首地址,lenth--读取数据的长度
//出口:无
/**********************************************************************/
void read_out(unsigned char eaddr,unsigned int addr,unsigned char *rdata_addr,unsigned int lenth);
void read_out(unsigned char eaddr,unsigned int addr,unsigned char *rdata_addr,unsigned int lenth)
{
_DINT();
Start_I2C(); //启动总线
SendByte(0xa0+eaddr);//外部地址+控制数据
SendByte(addr/256);//寻址EEPROM写命令,写入地址高低字节地址
SendByte(addr%256);
Start_I2C(); //启动总线
SendByte(0xa0+eaddr+0x01);//寻址EEPROM读命令
for(;lenth>0;lenth--)
{
*rdata_addr=RcvByte();//读取数据
if(lenth==1)
Ack_I2c(0);
else
Ack_I2c(1);
rdata_addr++;
}
Stop_I2C(); //读完停止总线
_EINT();
}
/**********************************************************************/
//函数功能:写数据到EEPROM
//函数原型:void write_in(uint addr,uchar data)
//入口:addr--所要写入数据的地址,wdata_addr--所要写入的数据首地址,lenth所要写入数据长度
//出口:无
/**********************************************************************/
void write_in_byte(unsigned char eaddr,unsigned int addr,unsigned char dat);
void write_in_byte(unsigned char eaddr,unsigned int addr,unsigned char dat)
{
_DINT();
Start_I2C();//启动总线
SendByte(0xa0+eaddr);//外部地址+控制数据
SendByte(addr/256);//寻址EEPROM写命令,写入地址高低字节地址
SendByte(addr%256);
SendByte(dat);
Stop_I2C();
delay(700);
_EINT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -