- 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天..显示出来了!!
贴上代码!
现在网速度很垃圾~ 贴不上去! 网速好了 在补!!!