I2C.h
#define AT24C64NW 0xA0
#define AT24C64NR 0xA1
#define MAX_TIMEOUT 0x00FFFFFF
#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */
#define I2CONSET_AA 0x00000004
#define I2CONSET_SI 0x00000008
#define I2CONSET_STO 0x00000010
#define I2CONSET_STA 0x00000020
#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
#define I2CONCLR_SIC 0x00000008
#define I2CONCLR_STAC 0x00000020
#define I2CONCLR_I2ENC 0x00000040
#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
#define I2SCLH_SCLH 0x00000080 /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL 0x00000080 /* I2C SCL Duty Cycle Low Reg */
#define SDA0 0x08000000 //p0.27
#define SCL0 0x10000000 //p0.28
#define SDA0CON 0x08000000
#define SCL0CON 0x10000000
extern DWORD I2CInit( UINT32 Fi2c );
extern DWORD I2CStart( void );
extern DWORD I2CStop( void );
extern DWORD I2CStartAgain( void );
extern DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData);
extern DWORD I2C_SendNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length);
extern DWORD I2C_ReadNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length);
I2C.c
DWORD I2CInit( UINT32 Fi2c )
{
if (Fi2c > 400000)
Fi2c = 400000;
PINSEL1 &= ~0x03C00000;
PINSEL1 |= 0x01400000; /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */
I20SCLH = (Fpclk/Fi2c + 1) / 2;/* 设定I2C时钟 */
I20SCLL = (Fpclk/Fi2c)/2;
I20CONCLR = 0x2C;// clear STA, SI,AA
I20CONSET = 0x40;// SET I2EN /* 使能主I2C */
return( TRUE );
}
DWORD I2CStart( void )
{
DWORD timeout = 0;
DWORD returnValue = FALSE;
/*--- Issue a start condition ---*/
I20CONCLR=I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC;
I20CONSET=I2CONSET_STA|I2CONSET_I2EN; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if (I20STAT==0x08)
{
returnValue = TRUE;
break;
}
if ( timeout >= MAX_TIMEOUT )
{
returnValue = FALSE;
break;
}
timeout++;
}
return( returnValue );
}
DWORD I2CStartAgain( void )
{
DWORD timeout = 0;
DWORD returnValue = FALSE;
/*--- Issue a start condition ---*/
I20CONCLR = I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC;//发送重复起始条件前一定要清零SI
I20CONSET = I2CONSET_STA|I2CONSET_I2EN; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if ( I20STAT == 0x10 )
{
returnValue = TRUE;
break;
}
if ( timeout >= MAX_TIMEOUT )
{
returnValue = FALSE;
break;
}
timeout++;
}
return( returnValue );
}
DWORD I2CStop( void )
{
I20CONSET = I2CONSET_STO; /* Set Stop flag */
I20CONCLR = I2CONCLR_SIC|I2CONCLR_STAC|I2CONCLR_AAC; /* Clear SI flag */// modified
/*--- Wait for STOP detected ---*/
while( I20CONSET & I2CONSET_STO );
return TRUE;
}
void I2C_SendByte(UINT8 SData)
{
I20DAT=SData;
I20CONCLR =0x28; /* 清零SI,STA */
while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag ( waiting for SI==1 )
}
DWORD I2C_SendNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length)
{
BYTE i;
I2CStart();
if(I20STAT==0x08) /* 已发送起始条件 */
{
I2C_SendByte(AT24C64NW); // Device Address
if(I20STAT==0x18) /* 已发送SLA+W,已接收ACK */
{
I2C_SendByte((SubAddr>>8)&(0x00FF));
if(I20STAT==0x28) /* 已发送SubAddr_H,已接收ACK */
{
I2C_SendByte(SubAddr&(0x00FF));
if(I20STAT==0x28) /* 已发送SubAddr_L,已接收ACK */
{
for(i=0;i { do{ I2C_SendByte(Data[i]); }while(I20STAT!=0x28); } if(I2CStop()) { DelayNS(5); //10ms return TRUE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData) { if (ACK==1) // send ACK { I20CONSET=I2CONSET_AA; } else // send NOACK if(ACK==0) { I20CONCLR=I2CONCLR_AAC; } I20CONCLR=I2CONCLR_SIC|I2CONCLR_STAC; // clear SI SAT while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag ( waiting for SI==1 ) if(ACK==1) { if((I20STAT&0xF8)==0x50) // receive data and get ack { *RcvData=I20DAT; return TRUE; } else return FALSE ; } else if(ACK==0) { if((I20STAT&0xF8)==0x58) // receive data and get NoAck (the last data you want to get) { *RcvData=I20DAT; return TRUE; } else return FALSE ; } return FALSE ; } DWORD I2C_ReadNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length) { BYTE i; if (!I2CStart()) { return FALSE; } if(I20STAT==0x08) /* 已发送起始条件 */ { I2C_SendByte(AT24C64NW); // Device Address if(I20STAT==0x18) /* 已发送SLA+W,已接收ACK */ { I2C_SendByte((SubAddr>>8)&(0x00FF)); if(I20STAT==0x28) /* 已发送SubAddr_H,已接收ACK */ { I2C_SendByte(SubAddr&(0x00FF)); if(I20STAT==0x28) /* 已发送SubAddr_L,已接收ACK */ { if (I2CStartAgain())//发送重复起始条件 切换为主接受模式 { I2C_SendByte(AT24C64NR); if(I20STAT==0x40)/*已发送SLA+R,已接收ACK*/ { for(i=0;i { if(!(I2C_ReadByte(1,&Data[i]))) { return FALSE; } } if( !( I2C_ReadByte(0, &Data[Length-1]) ) ) //读最后一个数据 { return FALSE; } if (I2CStop())//发送停止条件 { return TRUE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; }
上一篇:ARM 汇编中的立即数
下一篇:LPC23xx的ADC功能实现
推荐阅读最新更新时间:2024-03-16 15:01
设计资源 培训 开发板 精华推荐
- 有奖直播|瑞萨电子 RA 系列产品开发工具之 FSP4.0.0 新特性介绍
- 【已结束】R&S 直播【PCI Express Gen 3 一致性测试(含demo演示)】
- 福禄克首款热成像万用表Fluke-279FC 即将上市!填写问卷赢好礼喽!
- 有奖直播:使用 NI CompactDAQ 和 LabVIEW构建基于传感器的测试系统
- EEWorld下载中心大批技术资料等你来领,还有好礼相助
- Microchip 直播|时间同步的必要性及其解决方案
- 泰克送你三板斧,招招解决电源测试大难题!答题赢好礼喽!
- 高达270MHz!恩智浦LPC3000系列全套资料
- 有奖下载:邂逅大师——福禄克全新专家级红外热像仪