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