Страница 1 из 1

STM32F4+I2C

Добавлено: Ср июл 10, 2013 01:18:50
osievskiy
Спойлер

Код: Выделить всё

#define SLAVE_ADDRESS 0x68 // the slave address (example)

void init_I2C1(void){

	GPIO_InitTypeDef GPIO_InitStruct;
	I2C_InitTypeDef I2C_InitStruct;

	// enable APB1 peripheral clock for I2C1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	// enable clock for SCL and SDA pins
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

	/* setup SCL and SDA pins
	 * You can connect I2C1 to two different
	 * pairs of pins:
	 * 1. SCL on PB6 and SDA on PB7
	 * 2. SCL on PB8 and SDA on PB9
	 */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // we are going to use PB6 and PB7
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;			// set pins to alternate function
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;		// set GPIO speed
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;			// set output to open drain --> the line has to be only pulled low, not driven high
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;			// enable pull up resistors
	GPIO_Init(GPIOB, &GPIO_InitStruct);					// init GPIOB

	// Connect I2C1 pins to AF
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);	// SCL
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA

	// configure I2C1
	I2C_InitStruct.I2C_ClockSpeed = 100000; 		// 100kHz
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;			// I2C mode
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;	// 50% duty cycle --> standard
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;			// own address, not relevant in master mode
	I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;		// disable acknowledge when reading (can be changed later on)
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
	I2C_Init(I2C1, &I2C_InitStruct);				// init I2C1

	// enable I2C1
	I2C_Cmd(I2C1, ENABLE);
}

/* This function issues a start condition and
 * transmits the slave address + R/W bit
 *
 * Parameters:
 * 		I2Cx --> the I2C peripheral e.g. I2C1
 * 		address --> the 7 bit slave address
 * 		direction --> the tranmission direction can be:
 * 						I2C_Direction_Tranmitter for Master transmitter mode
 * 						I2C_Direction_Receiver for Master receiver
 */
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
	// wait until I2C1 is not busy anymore
	while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

	// Send I2C1 START condition
	I2C_GenerateSTART(I2Cx, ENABLE);

	// wait for I2C1 EV5 --> Slave has acknowledged start condition
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

	// Send slave Address for write
	I2C_Send7bitAddress(I2Cx, address, direction);

	/* wait for I2C1 EV6, check if
	 * either Slave has acknowledged Master transmitter or
	 * Master receiver mode, depending on the transmission
	 * direction
	 */
	if(direction == I2C_Direction_Transmitter){
		while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	}
	else if(direction == I2C_Direction_Receiver){
		while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
	}
}

/* This function transmits one byte to the slave device
 * Parameters:
 *		I2Cx --> the I2C peripheral e.g. I2C1
 *		data --> the data byte to be transmitted
 */
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data){
	I2C_SendData(I2Cx, data);
	// wait for I2C1 EV8_2 --> byte has been transmitted
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}

/* This function reads one byte from the slave device
 * and acknowledges the byte (requests another byte)
 */
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
	// enable acknowledge of recieved data
	I2C_AcknowledgeConfig(I2Cx, ENABLE);
	// wait until one byte has been received
	while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
	// read data from I2C data register and return data byte
	uint8_t data = I2C_ReceiveData(I2Cx);
	return data;
}

/* This function reads one byte from the slave device
 * and doesn't acknowledge the recieved data
 */
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
	// disabe acknowledge of received data
	I2C_AcknowledgeConfig(I2Cx, DISABLE);
	// wait until one byte has been received
	while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
	// read data from I2C data register and return data byte
	uint8_t data = I2C_ReceiveData(I2Cx);
	return data;
}

/* This funtion issues a stop condition and therefore
 * releases the bus
 */
void I2C_stop(I2C_TypeDef* I2Cx){
	// Send I2C1 STOP Condition
	I2C_GenerateSTOP(I2Cx, ENABLE);
}


int main(void)
{
SystemInit();
init_I2C1 ();


I2C_start(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter); // start a transmission in Master transmitter mode
	I2C_write(I2C1, 0x00); // write one byte to the slave
	I2C_stop(I2C1); // stop the transmission


	I2C_start(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver); // start a transmission in Master receiver mode

	received_data[0] = I2C_read_ack(I2C1); // read one byte and request another byte
	received_data[1] = I2C_read_ack(I2C1); 
	received_data[2] = I2C_read_ack(I2C1);
	received_data[3] = I2C_read_ack(I2C1); 
	received_data[4] = I2C_read_ack(I2C1); 
	received_data[5] = I2C_read_ack(I2C1);
	received_data[6] = I2C_read_nack(I2C1); // read one byte and don't request another byte
	I2C_stop(I2C1); 




 while (1)
  {


  }
}
Вот таким вот макаром пытаюсь по I2C получить данные с DS1307 (RTC) , но ничего не получается.
Зависает на I2C_start(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter);
Перекопал все что мог... подскажите почему оно зависает и что можно сделать?

Re: STM32F4+I2C

Добавлено: Ср июл 10, 2013 05:09:47
optima
а линии подтянул к + через резюки?

Re: STM32F4+I2C

Добавлено: Ср июл 10, 2013 09:15:20
osievskiy
СпойлерИзображение
У меня вот такой модуль...

а вот его схема
СпойлерИзображение

То есть на сколько я понимаю подтяжка есть резисторами R2 и R3



-=======================-

Вопрос решился! Вот тут есть готовая библиотека для ds1307

Re: STM32F4+I2C

Добавлено: Сб июл 13, 2013 23:13:46
svs39
osievskiy писал(а):У меня вот такой модуль...
в ф4 есть ртс , зачем подцеплять дс1307? какая польза?

Re: STM32F4+I2C

Добавлено: Вс июл 14, 2013 01:41:43
osievskiy
Ну на сколько я понял то для того что бы запустить стандартный RTC, нужно допаивать кварц...

Re: STM32F4+I2C

Добавлено: Пт июл 26, 2013 12:11:08
SergeBS
А что, для DS1307 кварц не нужен? А ежели описание посмотреть? :)

Re: STM32F4+I2C

Добавлено: Сб июл 27, 2013 09:44:00
balmer
Для такого варианта необходимо +5 V питание, если батарейка стоит. Иначе он не будет отвечать по I2C. Возможно у вас все правильно, это так подрабатываю Капитаном Очевидность.

Re: STM32F4+I2C

Добавлено: Вс ноя 10, 2013 08:29:26
Rimsky
Во вложении результат моих экспериментов с I2C и DS1307, может чем поможет.:)

Re: STM32F4+I2C

Добавлено: Вт сен 16, 2014 10:53:11
vash_sa
Помогите! Имеется stm32vldiscovery. Хочу запрограммировать ее для общения с CMOS камерой OV7960 по протоколу i2c. Управлять регистрами камеры с адресами 300С, 5003 ... Настроил I2C1 пин 6 - SCL и 7 - SDA. Функции беру библиотечные. И не выходит. Плата не видит камеры. В чем дело не пойму. Может у кого есть опыт работы.
Зависает отладчик на строке:
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

Re: STM32F4+I2C

Добавлено: Ср сен 17, 2014 11:16:16
vash_sa
Уважаемые коты! Кто-нибудь настраивал I2C на плате stm32vldiscovery. Прошу сбросьте рабочий пример!!! А то полный казус у товарища на AVR и ассемблере работает с устройством, а у меня затыкается на стадии генерации стартового сигнала.

Re: STM32F4+I2C

Добавлено: Ср сен 17, 2014 11:31:30
Леонид Иванович
Делал на STM32F100 программный I2C ногодрыгом. Везде, где нужна высокая надежность, всегда делаю программный I2C, будь то STM32, будь то AVR.

Re: STM32F4+I2C

Добавлено: Сб мар 28, 2015 23:02:10
ewgeny7
Немножко пронекрофилирую тему, но надеюсь, кому-то она тоже понадобится, как понадобилась мне.
Привинчивал SHT21 к STM32F4, прикошачил в конце концов.
Почему-то в коде, размещенном в первом посте, оказалась "вредной" строка:

I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses

Если ее выпилить, то I2C вполне себе начинает работать. Не стал углубляться в дебри, просто "поставил галочку в уме".

Re: STM32F4+I2C

Добавлено: Сб мар 28, 2015 23:07:13
dosikus
ewgeny7 , Жень и не лень тебе с SPL мучаться, вся эта хрень легко выпиливаеться ...

Re: STM32F4+I2C

Добавлено: Вс мар 29, 2015 11:49:11
ewgeny7
У каждого свой стиль вырабатывается.
Я пользую голый Си для работы с пинами, но для работы с периферией - SPL. Вот такая вот каша получается. Но мне так удобно :)

Изображение

Re: STM32F4+I2C

Добавлено: Вс мар 29, 2015 16:37:48
jazz393
вот настраивал I2C на vldiscovery на передачу, на приём настраивал на L-discovery, только на работе проект остался, если надо - завтра поищу, надеюсь поможет...Но я через регистры делал, не люблю SPL...

Re: STM32F4+I2C

Добавлено: Пн мар 30, 2015 20:32:37
FantasyDD
osievskiy Спасибо за схему.
Добавлю R5 D1 R4 - Удалить, R6 замкнуть. Тогда работать долго будет, по другому этот примитивный зарядник будет убивать аккумулятор или батарею. Если почитать даташит DS1307Z от батареи до 10 лет автономно может работать, а такой зарядник убьет батарею за пол года!