STM32F4+I2C

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

STM32F4+I2C

Сообщение 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);
Перекопал все что мог... подскажите почему оно зависает и что можно сделать?
Аватара пользователя
optima
Прорезались зубы
Сообщения: 232
Зарегистрирован: Вт май 08, 2012 10:42:29

Re: STM32F4+I2C

Сообщение optima »

а линии подтянул к + через резюки?
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: STM32F4+I2C

Сообщение osievskiy »

СпойлерИзображение


У меня вот такой модуль...

а вот его схема

СпойлерИзображение



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



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

Вопрос решился! Вот тут есть готовая библиотека для ds1307
svs39
Встал на лапы
Сообщения: 95
Зарегистрирован: Вс авг 22, 2010 09:23:08

Re: STM32F4+I2C

Сообщение svs39 »

osievskiy писал(а):У меня вот такой модуль...

в ф4 есть ртс , зачем подцеплять дс1307? какая польза?
Аватара пользователя
osievskiy
Открыл глаза
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Re: STM32F4+I2C

Сообщение osievskiy »

Ну на сколько я понял то для того что бы запустить стандартный RTC, нужно допаивать кварц...
Аватара пользователя
SergeBS
Вымогатель припоя
Сообщения: 683
Зарегистрирован: Пт апр 11, 2008 11:24:53
Откуда: Владимир

Re: STM32F4+I2C

Сообщение SergeBS »

А что, для DS1307 кварц не нужен? А ежели описание посмотреть? :)
Человек - это звучит гордо, а обезьяна - объективно...
Аватара пользователя
balmer
Это не хвост, это антенна
Сообщения: 1433
Зарегистрирован: Вс дек 02, 2012 03:13:48
Откуда: Калининград

Re: STM32F4+I2C

Сообщение balmer »

Для такого варианта необходимо +5 V питание, если батарейка стоит. Иначе он не будет отвечать по I2C. Возможно у вас все правильно, это так подрабатываю Капитаном Очевидность.
Аватара пользователя
Rimsky
Грызет канифоль
Сообщения: 299
Зарегистрирован: Вт июн 15, 2010 07:16:42
Откуда: Иркутск
Контактная информация:

Re: STM32F4+I2C

Сообщение Rimsky »

Во вложении результат моих экспериментов с I2C и DS1307, может чем поможет.:)
Вложения
rtc_dr.zip
(3.92 КБ) 666 скачиваний
vash_sa
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт сен 04, 2014 13:22:44

Re: STM32F4+I2C

Сообщение vash_sa »

Помогите! Имеется stm32vldiscovery. Хочу запрограммировать ее для общения с CMOS камерой OV7960 по протоколу i2c. Управлять регистрами камеры с адресами 300С, 5003 ... Настроил I2C1 пин 6 - SCL и 7 - SDA. Функции беру библиотечные. И не выходит. Плата не видит камеры. В чем дело не пойму. Может у кого есть опыт работы.
Зависает отладчик на строке:
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
Вложения
main.c
(2.61 КБ) 699 скачиваний
vash_sa
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт сен 04, 2014 13:22:44

Re: STM32F4+I2C

Сообщение vash_sa »

Уважаемые коты! Кто-нибудь настраивал I2C на плате stm32vldiscovery. Прошу сбросьте рабочий пример!!! А то полный казус у товарища на AVR и ассемблере работает с устройством, а у меня затыкается на стадии генерации стартового сигнала.
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

Re: STM32F4+I2C

Сообщение Леонид Иванович »

Делал на STM32F100 программный I2C ногодрыгом. Везде, где нужна высокая надежность, всегда делаю программный I2C, будь то STM32, будь то AVR.
ewgeny7
Родился
Сообщения: 17
Зарегистрирован: Вт мар 04, 2008 22:17:19

Re: STM32F4+I2C

Сообщение ewgeny7 »

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

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

Если ее выпилить, то I2C вполне себе начинает работать. Не стал углубляться в дебри, просто "поставил галочку в уме".
КиберКот
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F4+I2C

Сообщение dosikus »

ewgeny7 , Жень и не лень тебе с SPL мучаться, вся эта хрень легко выпиливаеться ...
ewgeny7
Родился
Сообщения: 17
Зарегистрирован: Вт мар 04, 2008 22:17:19

Re: STM32F4+I2C

Сообщение ewgeny7 »

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

Изображение
КиберКот
jazz393
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Re: STM32F4+I2C

Сообщение jazz393 »

вот настраивал I2C на vldiscovery на передачу, на приём настраивал на L-discovery, только на работе проект остался, если надо - завтра поищу, надеюсь поможет...Но я через регистры делал, не люблю SPL...
Вложения
i2c_1.h
(2.14 КБ) 356 скачиваний
Аватара пользователя
FantasyDD
Нашел транзистор. Понюхал.
Сообщения: 165
Зарегистрирован: Чт фев 19, 2015 17:26:19
Откуда: СССР

Re: STM32F4+I2C

Сообщение FantasyDD »

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

Вернуться в «ARM»