void I2CStop(void) { SDA = 0; // i2c stop bit sequence I2CDelay(); SCL = 1; I2CDelay(); SDA = 1; I2CDelay(); }
void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB, I2C_SCL_PIN); I2CDelay(SystemCoreClock / 3 / 100000); GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB, I2C_SDA_PIN); I2CDelay(SystemCoreClock / 3 / 100000); GPIO_SetBits(GPIOB, I2C_SCL_PIN); I2CDelay(SystemCoreClock / 3 / 100000); GPIO_SetBits(GPIOB, I2C_SDA_PIN); I2CDelay(SystemCoreClock / 3 / 100000); GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_DeInit(I2C); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDR; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; I2C_Init(I2C, &I2C_InitStructure); I2C_Cmd(I2C, ENABLE); if (I2C->SR2 & 0x02) //检测I2C { while (1) //DEBUG { } } }
char I2CStop(void) { SDA_LOW; SCL_HIGH; /* Let SCL go up */ I2CDelay(I2CDELAY); SDA_HIGH; /* ...and then SDA up -> stop condition. */ I2CDelay(I2CDELAY); return (SCL_IN && SDA_IN); /* Both will be up, if everything is fine */ }
void I2CStart() { SDA = 1; I2CDelay(); SCL = 1; I2CDelay(); SDA = 0; I2CDelay(); SCL = 0; I2CDelay(); }
char I2CStart(void) { SDA_HIGH; SCL_HIGH; I2CDelay(I2CDELAY); SDA_LOW; /* Pull SDA down... */ I2CDelay(I2CDELAY); SCL_LOW; /* ...and then SCL -> start condition. */ I2CDelay(I2CDELAY); return 0; }
// put SCL to high-z and wait until line is really hi // returns != 0 if ok uns8 I2CWaitClkHi(void) { uns8 nii=1; I2CDelay(); I2C_CIO=1; // set SCL to input, output a high while( I2C_SCL == 0 ) // wait for line to come hi { nii++; if( nii == 0 ) break; } I2CDelay(); return(nii); }
// send a stop condition void I2CStop(void) { I2C_DIO=0; // set SDA to output I2C_SDA = 0; // output a low I2CWaitClkHi(); I2C_DIO=1; // set SDA to input, output a high, STOP condition I2CDelay(); // leave clock high }
char BitInI2C(void) { char bin; // SDA is opencollector, so: SDA_HIGH; SCL_HIGH; /* Let SCL go up */ while(!SCL_IN) /* Wait for other devices */ { // should do a timeout here } bin = SDA_IN; /* Read in data */ I2CDelay(I2CDELAY); SCL_LOW; /* Pull SCL back up */ I2CDelay(I2CDELAY); return bin; /* Return the sampled bit */ }
// send a start condition void I2CStart(void) { I2C_DIO=1; // set SDA to input, output a high I2CWaitClkHi(); I2C_SDA = 0; // start condition I2C_DIO = 0; // output a low I2CDelay(); I2C_SCL = 0; I2C_CIO = 0; // set SCL to output, output a low }
unsigned char I2CGet(char ack) { char x, d=0; SDA = 1; for(x=0; x<8; x++) { d <<= 1; do { SCL = 1; } while(SCL_IN==0); // wait for any SCL clock stretching I2CDelay(); if(SDA_IN) d |= 1; SCL = 0; } if(ack) SDA = 0; else SDA = 1; SCL = 1; I2CDelay(); // send (N)ACK bit SCL = 0; SDA = 1; return d; }
char BitOutI2C(unsigned char bout) { SDA_OUT(bout); /* Put data out on SDA */ I2CDelay(I2CDELAY); SCL_HIGH; /* Let SCL go up */ while(!SCL_IN) /* Wait until all other devices are ready */ { // should do a timeout here } if (SDA_IN != bout) /* Arbitration lost, release bus and return */ { SDA_HIGH; /* Should be up anyway, but make sure */ i2cError = I2CERR_LOST; I2CDumpError(i2cError); return 1; } I2CDelay(I2CDELAY); SCL_LOW; /* Pull SCL back down */ I2CDelay(I2CDELAY); return 0; /* OK */ }
unsigned char I2CPut(unsigned char d) { char x; unsigned char b; for(x=8; x; x--) { if(d&0x80) SDA = 1; else SDA = 0; SCL = 1; d <<= 1; SCL = 0; } SDA = 1; SCL = 1; I2CDelay(); b = SDA_IN; // possible ACK bit SCL = 0; return b; }
char I2CSendReceive(char addr, char tx_count, char rx_count) { if (I2CSendStop(addr, tx_count, 0)) { /* If send fails, abort but don't send a stop condition if we lost arbitration */ if (i2cError != I2CERR_LOST) I2CStop(); return 1; } SDA_HIGH; /* One of these may be low now, in which case the next */ SCL_HIGH; /* start condition wouldn't be detected so make */ I2CDelay(I2CDELAY); /* sure that they're up and wait for one delay slot */ if (i2c_recv((char)(addr|0x01), rx_count)) return 1; return (i2cError ? 1 : 0); }