История изменений
Исправление KivApple, (текущая версия) :
Спасибо большое. Создал на основе твоего проекта пустой свой. Разобрался с миганием светодиодом и USART, а теперь уже полдня мучаюсь и не могу заставить работать I2C. У тебя нет примера работы с ним?
Сделал так:
void i2c_init() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef pin;
GPIO_StructInit(&pin);
pin.GPIO_Pin = GPIO_Pin_6;
pin.GPIO_Mode = GPIO_Mode_AF_OD;
pin.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &pin);
pin.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &pin);
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
I2C_InitTypeDef i2c;
i2c.I2C_ClockSpeed = 400000;
i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_DutyCycle = I2C_DutyCycle_2;
i2c.I2C_OwnAddress1 = 0;
i2c.I2C_Ack = I2C_Ack_Disable;
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
}
void i2c_start(uint8_t addr) {
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr & ~1, (addr & 1) ? I2C_Direction_Receiver : I2C_Direction_Transmitter);
if (addr & 1) {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
} else {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
}
}
void i2c_stop() {
I2C_GenerateSTOP(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
void i2c_write(uint8_t data) {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
I2C_SendData(I2C1, data);
}
uint8_t i2c_read(uint8_t ack) {
if (ack) {
I2C_AcknowledgeConfig(I2C1, ENABLE);
} else {
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
}
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
uint8_t data = I2C_ReceiveData(I2C1);
return data;
}
Всё это дело зависает на последнем цикле функции i2c_start как только я хочу обратиться к своему датчику MPU6050 после вызова i2c_init. При этом SCL опускается в низкое состояние (если не делать i2c_start и дальнейший обмен, а только инициализацию, то SCL в высоком уровне как и положено при бездействии).
Исходная версия KivApple, :
Спасибо большое. Превратил твой проект в пустышку, теперь могу создавать на основе такого шаблона свои проекты. Разобрался с миганием светодиодом и USART, а теперь уже полдня мучаюсь и не могу заставить работать I2C. У тебя нет примера работы с ним?
Сделал так:
void i2c_init() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef pin;
GPIO_StructInit(&pin);
pin.GPIO_Pin = GPIO_Pin_6;
pin.GPIO_Mode = GPIO_Mode_AF_OD;
pin.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &pin);
pin.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &pin);
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
I2C_InitTypeDef i2c;
i2c.I2C_ClockSpeed = 400000;
i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_DutyCycle = I2C_DutyCycle_2;
i2c.I2C_OwnAddress1 = 0;
i2c.I2C_Ack = I2C_Ack_Disable;
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
}
void i2c_start(uint8_t addr) {
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, addr & ~1, (addr & 1) ? I2C_Direction_Receiver : I2C_Direction_Transmitter);
if (addr & 1) {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
} else {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
}
}
void i2c_stop() {
I2C_GenerateSTOP(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
void i2c_write(uint8_t data) {
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
I2C_SendData(I2C1, data);
}
uint8_t i2c_read(uint8_t ack) {
if (ack) {
I2C_AcknowledgeConfig(I2C1, ENABLE);
} else {
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
}
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
uint8_t data = I2C_ReceiveData(I2C1);
return data;
}
Всё это дело зависает на последнем цикле функции i2c_start как только я хочу обратиться к своему датчику MPU6050 после вызова i2c_init.