本帖最后由 kyzb001 于 2011-12-7 14:22 编辑
void DrcI2C_WriteByte(uint32_t address,uint8_t data )
{
uint32_t i;
SystemCoreClock = DrvSYS_GetHCLKFreq();
//Open I2C1 and set clock = 50Kbps
if(DrvI2C_Open(I2C_PORT1, 50000))
printf("Open i2c1 fail.\n");
//send i2c start state
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0); //设置开始
while (I2C1->I2CON.SI == 0); //等待...
I2C1->I2CDAT = 0xA0; //发送器件地址
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1,0 ); //clr si flag
while( I2C1->I2CON.SI == 0 ); //poll si flag
I2C1->I2CDAT = (address>>8)&0XFF; //send address high
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send address low
I2C1->I2CDAT = address&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send data
I2C1->I2CDAT = data; //write data to
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send i2c stop
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //send stop
while( I2C1->I2CON.STO);
//while( I2C1->CON.SI == 0 );
for(i=0;i<60;i++);
DrvI2C_Close(I2C_PORT1);
for(i=0;i<6000;i++);
for(i=0;i<6000;i++);
}
void DrcI2C_WriteData(uint32_t address,uint8_t *pBuffer ,uint32_t u32Num)
{
uint32_t i;
SystemCoreClock = DrvSYS_GetHCLKFreq();
if(DrvI2C_Open(I2C_PORT1, 50000)) //Open I2C1 and set clock = 50Kbps
printf("Open i2c1 fail.\n");
//send i2c start
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0); //set start
while (I2C1->I2CON.SI == 0); //poll si flag
//send writer command
I2C1->I2CDAT = address; //send writer command
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1,0 ); //clr si flag
while( I2C1->I2CON.SI == 0 ); //poll si flag
while(u32Num--)
{
//send data
I2C1->I2CDAT = *pBuffer; //write data to
pBuffer++;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
}
//send i2c stop
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //send stop
while( I2C1->I2CON.STO);
//while( I2C1->CON.SI == 0 );
for(i=0;i<60;i++);
DrvI2C_Close(I2C_PORT1);
for(i=0;i<6000;i++);
for(i=0;i<6000;i++);
}
uint8_t DrcI2C_ReadByte(uint32_t address)
{
uint8_t TEMP;
//Open I2C1 and set clock = 50Kbps
SystemCoreClock = DrvSYS_GetHCLKFreq();
DrvI2C_Open(I2C_PORT1, 50000);
//send i2c start
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0); //set start
while (I2C1->I2CON.SI == 0); //poll si flag
//send writer command
I2C1->I2CDAT = 0XA0;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //clr si
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send address high
I2C1->I2CDAT = (address>>8)&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send address low
I2C1->I2CDAT = address&0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //clr si and set ack
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send start flag
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0); //clr si and send start
while( I2C1->I2CON.SI == 0 ); //poll si flag
//send read command
I2C1->I2CDAT = 0XA1;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //clr si
while( I2C1->I2CON.SI == 0 ); //poll si flag
//resive data
I2C1->I2CDAT = 0XFF;
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //clr si
while( I2C1->I2CON.SI == 0 ); //poll si flag
TEMP= I2C1->I2CDAT;
//send i2c stop
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0); //clr si and set stop
while( I2C1->I2CON.STO);
DrvI2C_Close(I2C_PORT1);
return TEMP;
}
#include "DrvI2C_Int.h"
volatile I2C_HOT_T I2C1s;
void I2C1_INT_HANDLE (uint32_t status)
{
switch(status & 0xf8)
{
case I2C_START: //主机收到自己发送的开始信号
{
if(I2C1s.State == I2C_START)
{ //本次中断应该接收TW_START信号
I2C1->I2CDAT = I2C1s.u8SetAddress & 0xfe; //发送子机地址(写)
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0); //STA位必须清除,否则死机 清除中断标志
I2C1s.State = I2C_MT_SLA_ACK; //Status下次I2C_MT_SLA_ACK
}
else
I2C_Exit(); //通讯失败
break;
}
case I2C_REP_START: //主机收到自己发送的重新开始信号
{
if (I2C1s.State == I2C_REP_START)
{ //本次中断应该接收TW_RESTART信号
I2C1->I2CDAT = I2C1s.u8SetAddress; //发送子机地址(读)
I2C1s.State = I2C_MR_SLA_ACK; //Status下次I2C_MR_SLA_ACK
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1); //STA位必须清除,否则死机 清除中断标志
}
else
I2C_Exit(); //通讯失败
break;
}
case I2C_MT_SLA_ACK:
{ //主发机接收到从机的地址应答信号后发送命令
if(I2C1s.State == I2C_MT_SLA_ACK)
{ //本次中断应该接收TW_MT_SLA_ACK信号
I2C1s.State = I2C_MT_DATA_ACK; //Status下次应该收TW_MT_DATA_ACK
I2C1->I2CDAT = I2C1s.SubComm; //发送子机命令
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
}
else
I2C_Exit(); //通讯失败
break;
}
case I2C_MR_SLA_ACK:
{ //主收机接收到从机的地址应答信号
if ((I2C1s.State == I2C_MR_SLA_ACK) && I2C1s.u32SubCount)
{ //本次中断应该接收TW_MR_SLA_ACK信号
I2C1s.State = I2C_MR_DATA_ACK; //Status下次应该收TW_MR_DATA_ACK
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
}
else
I2C_Exit(); //通讯失败
break;
}
case I2C_MT_DATA_ACK:
{ //主收机接收到从机的数据应答信号
if ((I2C1s.State == I2C_MT_DATA_ACK) && (I2C1s.u32Count < I2C1s.u32MasterCount))
{ //本次中断应该接收TW_MT_DATA_ACK信号
I2C1->I2CDAT= I2C1s.u32TxBuffer[I2C1s.u32Count ++]; //发送子机数据
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
}
else
{
if ((I2C1s.State == I2C_MT_DATA_ACK) &&
(I2C1s.u32Count == I2C1s.u32MasterCount) &&
(I2C1s.u8SetAddress & 0x01))
{ //本次中断应该接收TW_MT_DATA_ACK信号
I2C_REStart();//
}
else
I2C_Stop(); //通讯成功
}
break;
}
case I2C_MR_DATA_ACK:
{
if ((I2C1s.State == I2C_MR_DATA_ACK) && (I2C1s.u32Count < I2C1s.u32SubCount))
{
I2C1s.u32TxBuffer[I2C1s.u32Count ++] = I2C1->I2CDAT;//接收子机数据
if (I2C1s.u32Count < I2C1s.u32SubCount)
{
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 1);
}
else
{
DrvI2C_Ctrl(I2C_PORT1, 0, 0, 1, 0);
I2C1s.State = I2C_MR_DATA_NACK; //下次进入I2C_MR_DATA_NACK,接收数据准备完成
}
}
else
I2C_Exit(); //通讯失败
break;
}
case I2C_MR_DATA_NACK: //数据接收结束
{
if((I2C1s.State == I2C_MR_DATA_NACK) && (I2C1s.u32Count == I2C1s.u32SubCount))
{
I2C_Stop(); //通讯成功
}
else
I2C_Exit(); //通讯失败
break;
}
default:
I2C_Exit(); //通讯失败
}
}
void Init_I2C(void)
{
/* Set I2C I/O */
DrvGPIO_InitFunction(E_FUNC_I2C1);
I2C1s.u8SetAddress = 0xA0;
}
void I2C_Start(void)
{
I2C1s.Busy = TRUE;
I2C1s.State = I2C_START; //主机准备发送启始位
I2C1s.u32Count = 0; //发送数据个数
//SystickCount = 0; //清除节拍计数器
/* Open I2C1, and set clock = 50Kbps */
DrvI2C_Open(I2C_PORT1,50000);
/* Enable I2C1 interrupt and set corresponding NVIC bit */
DrvI2C_EnableInt(I2C_PORT1);
/* Install I2C1 call back function for slave */
DrvI2C_InstallCallback(I2C_PORT1, I2CFUNC, I2C1_INT_HANDLE);
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 0, 0);
DrvSYS_Delay(8000);
}
void I2C_REStart(void)
{
I2C1s.Busy = TRUE;
I2C1s.State = I2C_REP_START; //主机准备发送启始位
I2C1s.u32Count = 0; //发送数据个数
DrvI2C_Ctrl(I2C_PORT1, 1, 0, 1, 0);
}
void I2C_Stop(void)
{
I2C1s.Busy= FALSE;
I2C1s.State = I2C_BUS_OK; //通讯成功
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
}
void I2C_Exit(void)
{
I2C1s.Busy = FALSE;
I2C1s.State = I2C_BUS_ERROR; //通讯失败
DrvI2C_Ctrl(I2C_PORT1, 0, 1, 1, 0);
printf("I2C talk is fail.\n");
}
unsigned char I2C_ReadByte(unsigned int Address, unsigned char *Data)
{
I2C1s.u8SetAddress |= 0x01;
I2C1s.u32MasterCount = 0; //发送0个数据(只读)
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
I2C1s.SubComm = Address; //读出地址
I2C1s.u32SubCount = 1; //接收1个数据
I2C_Start(); //启动I2C模块
if (I2C1s.State == I2C_BUS_OK) //通讯成功
{
Data[0] = I2C1s.u32TxBuffer[0]; //从接收缓冲区取出一个字节
}
return I2C1s.State; //(读出数据在RxBuffer[0]~RxBuffer[15])
}
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
unsigned char I2C_ReadBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
{
int i;
I2C1s.u8SetAddress |= 0x01;
I2C1s.u32MasterCount = 0; //发送0个数据(只读)
I2C1s.SubComm = Address; //读出地址
I2C1s.u32SubCount = (Cnt <= sizeof(I2C1s.u32TxBuffer)) ? Cnt : sizeof(I2C1s.u32TxBuffer);//接收Cnt个数据
I2C_Start(); //启动I2C模块
if (I2C1s.State == I2C_BUS_OK)
{ //通讯成功
for (i = 0; i < I2C1s.u32SubCount; i ++)
Data[i] = I2C1s.u32TxBuffer[i]; //从接收缓冲区取出Cnt个字节
}
return I2C1s.State; //(读出数据在RxBuffer[0]~RxBuffer[15])
}
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
unsigned char I2C_WriteByte(unsigned int Address, unsigned char Data)
{
I2C1s.u8SetAddress &=0xfe;
I2C1s.u32MasterCount = 1; //发送1个数据
I2C1s.SubComm = Address; //写入地址
I2C1s.u32TxBuffer[0] = Data; //写入1个数据到发送缓冲区
I2C1s.u32SubCount = 0; //接收0个数据
I2C_Start(); //启动I2C模块
DrvSYS_Delay(100);
return I2C1s.State;
}
//本程序为通用I2C,故发送器件后一般为命令,对EEPROM来说,命令实际是EEPROM地址
unsigned char I2C_WriteBuffer(unsigned int Address, unsigned char *Data, unsigned int Cnt)
{
int i;
I2C1s.u8SetAddress &= 0xfe; //发送Cnt个数据
I2C1s.u32MasterCount =Cnt ;
I2C1s.SubComm = Address; //写入地址
for (i = 0; i < Cnt; i ++)
{
I2C1s.u32TxBuffer[i] = Data[i]; //写入Cnt个数据到发送缓冲区
}
I2C1s.u32SubCount = 0; //接收0个数据
I2C_Start(); //启动I2C模块
DrvSYS_Delay(100);
return I2C1s.State;
}
其实我是复制黏贴的 - -~
废话不多说了,遇到一个变态的I2C器件...折腾了2天..显示出来了!!
贴上代码!
现在网速度很垃圾~ 贴不上去! 网速好了 在补!!! |