//--------------------------------------------------------------------------------
#include <stdio.h> /* prototype declarations for I/O functions */
#include <LPC2103.H> /* LPC21xx definitions */
#include "Main.h"
//--------------------------------------------------------------------------------
#define WRITE_NUM 12
#define MEMWRITE 0xa0 //写命令
#define MEMREAD (MEMWRITE+1) //读命令
#define STA (1<<5) //起始位
#define I2CEN (1<<6) //允许位
#define STO (1<<4) //停止位
#define SI (1<<3) // 中断标志
#define AA (1<<2) // 响应标志
#define LASTBYTE 1 //最后字节标志
void i2cInit(void);//I2C初始化程序
void i2cStart(void);//I2C发送起始位
void i2cStop(void);//I2C发送停止位
void writeByte(UINT8 data);//写一个字节的数据到总线上
void writeAddr(UINT8 mode);//写 地址和方向标志 到总线上
void writeData(UINT8 data);//完整的写数据,包括开始,清除标志等操作
unsigned char readByte(unsigned char last);//读字节数据,返回读到的值
void writeMem(UINT8 page_start,UINT8 count_byte,UINT8 *message_out);//写存储器的整体操作
void readMem(UINT8 page_start,UINT8 count_byte,UINT8 *message_in);//读存储器的整体操作
void delayMs(int dly);//延时
void UART1_Init (void)
{
UINT16 Fdiv;
PINSEL0 = 0x00050000;
U1LCR = 0x83; // DLAB = 1,可设置波特率
Fdiv = (Fpclk / 16)/ UART_BPS; // 设置波特率
U1DLM = Fdiv / 256;
U1DLL = Fdiv % 256;
U1LCR = 0x03;
}
/*****************************PLL初始化**************************************/
void PLL_Init(void)
{
/* 设置系统各部分时钟 */
#if (Fcco / Fcclk) == 2
PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
#endif
#if (Fcco / Fcclk) == 4
PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
#endif
#if (Fcco / Fcclk) == 8
PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
#endif
#if (Fcco / Fcclk) == 16
PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
#endif
PLLFEED = 0xaa;
PLLFEED = 0x55;
while((PLLSTAT & (1 << 10)) == 0);
PLLCON = 3;
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
static UINT8 i2c_buf_w[WRITE_NUM];
static UINT8 i2c_buf_r[WRITE_NUM];
int main (void)
{
UINT8 i = 0;
PLL_Init();
UART1_Init();
printf("---- Program start ----\n");
for(i=0; i<WRITE_NUM; i++)
i2c_buf_w[i] = i;
for(i=0; i<WRITE_NUM; i++)
i2c_buf_r[i] = 0;
i2cInit();//I2C初始化
writeMem(100,WRITE_NUM,i2c_buf_w);
delayMs(1000);
readMem(100,WRITE_NUM,i2c_buf_r);
printf("==== Write ====");
for(i=0; i<WRITE_NUM; i++)
{
if(i % 32 == 0)
printf("\n");
printf("%02d ",i2c_buf_w[i]);
}
printf("\n==== Read ====");
for(i=0; i<WRITE_NUM; i++)
{
if(i % 32 == 0)
printf("\n");
printf("%02d ",i2c_buf_r[i]);
}
printf("\n");
while(TRUE);
}
void i2cInit(void)
{
PINSEL0 &= ~((3 << 4) | (3 << 6));
PINSEL0 |= ((1 << 4) | (1 << 6));
I2C0SCLH = 15; //Set bit rate 12Mhz/VPBDIV+SCLH+SCLL = 12/4/(15+15) = 100Khz
I2C0SCLL = 15;
I2C0CONCLR = 0XFF;
I2C0CONSET = I2CEN;
}
//I2C发送起始位
void i2cStart(void)
{
I2C0CONSET=STA;
do{}
while(I2C0STAT!=0x08);//等待起始条件发送完成
I2C0CONCLR=STA;
}
//I2C发送停止位
void i2cStop(void)
{
I2C0CONSET=STO;//启动发送stop位,STO位是自动清除的,不必判断是否结束
I2C0CONCLR=SI; //只能清除SI,如果同时清除STO会导致返回到初始化状态
}
//写一个字节的数据到I2CDAT中
void writeByte(unsigned char data)
{
I2C0DAT=data;
I2C0CONCLR=SI;//启动发送
}
//发送控制字,其中mode为 MEMWRITE 或 MEMREAD
void writeAddr(unsigned char mode)
{
writeByte(mode);
if(mode==MEMREAD)
do{}
while(I2C0STAT!=0x40);//如果发送的是读控制字(地址),等待从机响应
else
do{}
while(I2C0STAT!=0x18);//如果发送的是写控制字(地址),等待从机响应
}
//写数据
void writeData(unsigned char data)
{
writeByte(data);
do{}while(I2C0STAT!=0x28);//0x28——已发送I2CDAT中的字节,已经接受ACK
}
//读数据
unsigned char readByte(unsigned char last)
{
if(last)//如果读的是最后一个字节,不需要发送应答位
{
I2C0CONCLR=AA;
I2C0CONCLR=SI;
do{}
while(I2C0STAT!=0x58);//等待接收数据直接和非ACK
}
else
{
I2C0CONSET=AA;//发送一个应答位
I2C0CONCLR=SI;
do{}
while(I2C0STAT!=0x50);//等待接收数据直接和ACK
}
return (I2C0DAT);
}
/*
写24C01
入口: page_start——起始地址,count_byte——需要写的字节数,
message_out——需要写入的数据缓冲区头指针
*/
void writeMem(UINT8 page_start,UINT8 count_byte,UINT8 *message_out)
{
UINT8 i;
i2cStart();//发送起始位
writeAddr(MEMWRITE);//发送写控制字
writeData(page_start);//发送写的起始地址
for(i=0;i<count_byte;i++,message_out++)//写数据
writeData(*message_out);
i2cStop();//发送停止位
}
/*
读24C01,模式——顺序读(SEQUENTIAL READ)
入口:page_start——读起始地址,count_byte——需要读的字节数,
message_in——读缓冲区头指针
出口:
*/
void readMem(UINT8 page_start,UINT8 count_byte,UINT8 *message_in)
{
UINT8 i;
//设置读指针
i2cStart();//发送起始位
writeAddr(MEMWRITE);//发送写控制字
writeData(page_start);//发送读的起始地址
i2cStop();//发送停止位
delayMs(1);
//开始读数据
i2cStart();//发送起始位
writeAddr(MEMREAD);//发送读控制字
for(i=0;i<count_byte;i++,message_in++)//接收数据
*message_in=readByte(!LASTBYTE);
*message_in=readByte(LASTBYTE);
i2cStop();//发送停止位
}
void delayMs(int dly)
{
int i;
for(;dly>0;dly--)
for(i=0;i<1000;i++);
}