/************************* Copyright (c) 2014 SmartMcu Team *****************************
*项目名称:ARM Cortex-M0
*描 述:I2C测试
*******************************************************************************************/
#include "SmartM_M0.h"
#define EEPROM_SLA 0xA0
#define EEPROM_WR 0x00
#define EEPROM_RD 0x01
#define I2C_CLOCK 13
#define PAGE_SIZE 8
/*****************************************
*函数名称:Timed_Write_Cycle
*输 入:无
*输 出:无
*功 能:同步的写周期
******************************************/
void Timed_Write_Cycle(void)
{
while (I2STATUS != 0x18)
{
//启动
I2CON |= STA;
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA) & (~SI));
//设备地址
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
}
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
}
/*****************************************
*函数名称:I2CInit
*输 入:无
*输 出:无
*功 能:I2C初始化
******************************************/
VOID I2CInit(VOID)
{
P3_PMD &= ~(Px4_PMD | Px5_PMD);
P3_PMD |= (Px4_OD | Px5_OD); //使能I2C0引脚
P3_MFP &= ~(P34_T0_I2CSDA | P35_T1_I2CSCL);
P3_MFP |= (I2CSDA | I2CSCL); //选择P3.4,P3.5作为I2C0功能引脚
APBCLK |= I2C0_CLKEN; //使能I2C0时钟
I2CLK = I2C_CLOCK;
I2CON |= ENSI; //使能I2C
}
/*****************************************
*函数名称:I2CWrite
*输 入:unAddr 写地址
pucData 写数据
unLength 写长度
*输 出:TRUE/FALSE
*功 能:AT24C0X写数据
******************************************/
BOOL I2CWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i;
I2CON |= STA; //启动
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x08)
{
return FALSE;
}
//进入读写控制操作
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x18)
{
return FALSE;
}
//写地址
I2DAT = unAddr;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
return FALSE;
}
//写数据
for(i=0; i<unLength; i++)
{
I2DAT = *(pucData+i);
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
return FALSE;
}
}
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
Timed_Write_Cycle();
return TRUE;
}
/*****************************************
*函数名称:I2CRead
*输 入:unAddr 读地址
pucData 读数据
unLength 读长度
*输 出:TRUE/FALSE
*功 能:AT24C0X读数据
******************************************/
BOOL I2CRead(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i;
I2CON |= STA; //启动
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x08)
{
return FALSE;
}
//进入读写控制操作
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x18)
{
return FALSE;
}
//写入读地址
I2DAT = unAddr;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
return FALSE;
}
// 重新启动
I2CON |= STA;
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x10)
{
return FALSE;
}
//进入读操作
I2DAT = EEPROM_SLA | EEPROM_RD;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x40)
{
while (1);
}
//读取数据
I2CON |= AA;
for(i=0; i<unLength; i++)
{
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x50)
{
return FALSE;
}
*(pucData+i) = I2DAT;
}
//发送NACK到AT24C02,执行断开连接操作
I2CON &= (~AA);
I2CON |= SI;
while ((I2CON & SI) != SI);
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
return TRUE;
}
/****************************************
*函数名称:main
*输 入:无
*输 出:无
*功 能:函数主体
******************************************/
INT32 main(VOID)
{
UINT32 i=1;
UINT8 buf[32]={0};
/*1.MCU频率初始化,频率为50MHz*/
McuInit(MCU_FREQUENCY);
/*2.串口初始化,波特率为115200bps*/
UartInit(115200);
/*3.I2C初始化*/
I2CInit();
printf("\r\n================================================\r\n");
printf("\r\n I2C Test \r\n");
printf("\r\n================================================\r\n");
while(1)
{
/*4.buf缓冲区置前9字节置为同一样的数据*/
memset(buf,i+'0',9);
/*5.I2C执行写操作*/
I2CWrite(0,buf,9);
/*6.打印当前状态*/
printf("写入9字节数据-%d\r\n",i);
Delayms(1000);
//==================================================
/*7.buf缓冲区置前9字节置为同一样的数据*/
memset(buf,0,sizeof buf);
/*8.I2C执行读操作*/
I2CRead(0,buf,9);
/*9.打印当前读取到的数据*/
printf("读入9字节数据:%s\r\n",buf);
Delayms(1000);
/*10.i为当前写入的值*/
if(++i>9)
{
i=1;
}
}
}
|