//****************************************************************************
//LPC2103(主機)與AT24C02(從機)的I2C傳輸
//功能:將A數組中的n各字節寫入AT24C02,再從AT24C02裏讀回數據到B數組
#include<lpc2103.h>
//I2C控制寄存器的相應位:
#define AA 1<<2 //應答位
#define SI 1<<3 //中斷標誌
#define STO 1<<4 //停止標誌
#define STA 1<<5 //起始標誌
#define I2EN 1<<6 //I2C使能
#define AT24C02_device_address 0XA0
#define u8 unsigned char
//函數聲明
void initialize(void);
void send(u8 device_address,u8 *A,u8 memory_address,u8 number);
void start(void);
void start_repeat(void);
void stop(void);
void send_slave_address(u8 device_address);
void send_data(u8 byte);
void receive(u8 device_address,u8 memory_address,u8 *B,u8 number);
int receive_data(u8);
void delay(int k);
u8 A[10]={0,1,2,3,4,5,6,7,8,9},B[10]={0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99};
int main()
{
initialize(); //I2C接口初始化
//向器件地址為AT24C02_device_address的器件發送字節,源地址為A,目標地址(AT24C02的數據指針)為0,字節數:10個
send(AT24C02_device_address,A,0,10);
delay(100000); //延時,手冊上說兩次寫間隔至少5ms
//向器件地址為AT24C02_device_address的器件接收字節,源地址(AT24C02的數據指針)為1,目標地址為B,字節數:6個
receive(AT24C02_device_address,1,B,6);
while(1);
}
void initialize() //I2C接口初始化
{
I2C0CONCLR=AA|SI|STA|I2EN; // I2C0CO所有位清0
I2C0CONSET=I2EN; //I2C接口使能
PINSEL0=0X50; //選擇P0.2為SCL0,P0.3為SDA0
I2C0SCLH=15;
I2C0SCLL=15; //位頻率=PCLK/(I2C0SCLH+I2C0SCLL)
}
//向器件地址為device_address的器件發送字節,源地址為A,目標地址為memory_address,字節數:number個
void send(u8 device_address,u8 *A,u8 memory_address,u8 number)
{
unsigned char i;
start(); //起始信號
send_slave_address(AT24C02_device_address); //發送器件地址+寫
send_data(memory_address); // 發送24C02片內的數據地址
for(i=0;i<number;i++) //發送number個字節
{
send_data(A[i]); //發送字節A[i]
}
stop(); //停止信號
}
void start() //起始信號
{
I2C0CONSET=STA; //發送起始信號
I2C0CONCLR=SI; //中斷標誌清0
while(I2C0STAT!=0x08); //發送起始信號完畢
I2C0CONCLR=STA; //關閉起始信號
}
void start_repeat() //“重復起始”信號
{
I2C0CONSET=STA; //發送起始信號
I2C0CONCLR=SI; //中斷標誌清0
while(I2C0STAT!=0x10); //發送“重復起始”信號完畢
I2C0CONCLR=STA; //關閉起始信號
}
void stop() //發送停止信號
{
I2C0CONSET=STO; //發送停止信號
I2C0CONCLR=SI; //中斷標誌清0
}
void send_slave_address(u8 device_address) //發送器件地址device_address
{
I2C0DAT=device_address; //發送器件地址
I2C0CONCLR=SI; //中斷標誌清0
if((device_address&0x01)==0)while(I2C0STAT!=0x18); //如果是寫操作,等待:發送地址和收到應答
else while(I2C0STAT!=0x40); //如果是讀操作,等待:發送地址和收到應答
}
void send_data(u8 byte) //發送壹個字節
{
I2C0DAT=byte; //發送壹個字節
I2C0CONCLR=SI; //中斷標誌清0
while(I2C0STAT!=0x28); //等待:發送字節和收到應答
}
//向器件地址為device_address的器件接收字節,源地址為memory_address,目標地址為B,字節數:number個
void receive(u8 device_address,u8 memory_address,u8 *B,u8 number)
{
unsigned char i;
start(); //發送起始信號
send_slave_address(device_address); //發送器件地址
send_data(memory_address); //發送器件的片內地址
start_repeat(); //發送“重復起始”信號
send_slave_address(device_address|1); //發送器件地址
for(i=0;i<number;i++) //發送number個字節
{ //將收到的字節放入B數組,i==(number-1)表示是否為最後壹個字節
B[i]=receive_data(i==(number-1));
}
stop(); //發送停止信號
}
int receive_data(u8 last) //接收壹個字節,發送應答或非應答
{
if(last) //如果是最後壹個字節
{
I2C0CONCLR=AA;//發送壹個非應答
I2C0CONCLR=SI;//中斷標誌清0
while(I2C0STAT!=0x58);//等待:接收數據直接和發出非ACK
}
else
{
I2C0CONSET=AA;//發送壹個應答位
I2C0CONCLR=SI;//中斷標誌清0
while(I2C0STAT!=0x50);//等待:接收數據直接和ACK
}
return (I2C0DAT); //返回接收的字節
}
void delay(int k) //延時
{ while(k--);}
//*************************************************************************