19. STM32. Програмування STM32F103. I2C Master
Шина I2C досить популярна і дуже багато сенсорів та інших пристроїв використовують саме I2C. Я не буду писати хто, коли і для чого винайшов цю шину та як по ній бігають байти. Цієї інформації повно у Інтернеті, для цього існує Вікіпедія. Коли Ви тримаєте в руках сенсор і бажаєте якнайшвидше отримати з нього дані, та вирішити поставлену задачу, Вам вистачить наступного мінімуму знань:
- Шина I2C - це двопровідна шина з лініями SCL, SDA. Теоретично, на одну шину I2C можна паралельно підключити до 112 пристроїв.
- Обидві лінії шини мають бути через резистори підключеними до живлення. Рекомендований номінал резисторів залежить від швидкості та інших параметрів шини. Зазвичай мало хто з цим морочиться і ставлять резистори у межах від 4.7кОм до 10кОм. Резисторів має бути по одному на кожну лінію. Якщо Ви підключаєте декілька модулів, а на кожному модулі вже впаяні підтягуючі резистори, то виходить, що резистори вмикаються паралельно і їх сумарний опір стає меншим. Це не дуже добре. Та, якщо ви вмикаєте лише два таких модуля і на кожному впаяні резистори по 10 кОм, тоді сумарний опір буде 5КОм, що попадає у межі допустимої норми і шина I2C, скоріш за все, буде працювати. Але повторюю: чіпляти на кожну лінію більше одного резистора - не дуже гарна ідея.
- Кожен пристрій на шині I2C має окрему адресу.
- На шині I2C може бути лише один Master і один, або декілька Slave.
- Швидкість шини може бути різною. Зазвичай використовують два стандарти 100 і 400 КГц. Швидкість лінії має визначатися по самому повільному пристрою на шині. Якщо Slave не встигає, він може "притримати" шину і всі його будуть чекати. Та такий підхід, хоч і є стандартом, але на практиці працює не завжди. У випадку, коли Master не вміє чекати (цим, наприклад страждають мікрокомп`ютери), на шині починається безлад. Тобто, некоректна робота одного з пристроїв на шині I2C (не важливо, у якій ролі - Master або Slave) може викликати проблеми у роботі усіх приладів.
- Якщо напруга живлення контролера відрізняється від напруги живлення датчика, вони мають вмикатися через двонаправлену схему узгодження логічних рівнів.
Розглянемо приклад використання датчика атмосферного тиску BMP280. Підключимо модуль датчика, як зазначено на схемі. На модулі датчика є запаяні резистори для кожної з ліній шини I2C, тому нам не треба нічого вигадувати. Схема підключення:
Налаштування шини виконується наступним чином:
1. Вмикається тактування потрібної шини I2C. У STM32 їх може бути декілька. У нашому мікроконтролері 2 шини I2C. 2. Вмикається тактування GPIO порту на якому висять SCL, SDA відповідної шини I2C. 3. Налаштовують GPIO виходи, як альтернативні для роботи у ролі SCL, SDA. 4. Вмикається шина I2C. 5. Налаштовуються параметри шини I2C.
Приклад:
void I2C1_init(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* Configure I2C_EE pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x38;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
/* I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);
/* Apply I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
}
Після чого можна приступати до роботи.
Для того, щоб звернутися до датчика, ми маємо знати його адресу. Знаючи адресу, ми зможемо посилати йому, або читати з нього, інформацію. Ми можемо звернутися до датчика і вказати адресу його регістра, з якого ми бажаємо отримати, або в який бажаємо записати, інформацію. У документації до датчиків вказані адреси регістрів та їх призначення. Керування датчиками виконується, зазвичай, записом у певний регістр певного числа (команди). Або відправкою певної команди на адресу датчика (без зазначення адреси регістра). Обмін інформацією залежить від реалізації того чи іншого датчика. Насправді це здається складним лише вперше. У багатьох випадках для різних датчиків функції запису та читання мало чим відрізняються. Наприклад, функція запису байта у регістр виглядає так:
void bmp280WriteByte(unsigned char address, unsigned char data)
{
I2C_GenerateSTART(I2C1,ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMP280_addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1,address);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1,ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
//----------------------------------------
Зазвичай, для інших датчиків вона виглядає аналогічно. Те саме стосується зчитування даних. Відмінності можуть бути у деталях. Наприклад, при зчитуванні багатобайтних даних у деяких датчиків першими йдуть старші розряди, а у інших - молодші розряди. Все стане зрозуміліше коли ви розглянете приклад. Повний текст програми наводити немає сенсу. Проект з назвою Example_i2C_Master можна скачати на сторінці прикладів.
Бажаю успіхів!
Дивись також:
- 1. STM32. Програмування STM32F103. Тестова плата. Прошивка через UART та через ST-Link
- 2. STM32. Програмування. IDE для STM32
- 3. STM32. Програмування STM32F103. GPIO
- 4. STM32. Програмування STM32F103. Тактування
- 5. STM32. Програмування STM32F103. USART
- 6. STM32. Програмування STM32F103. NVIC
- 7. STM32. Програмування STM32F103. ADC
- 8. STM32. Програмування STM32F103. DMA
- 9. STM32. Програмування STM32F103. TIMER
- 10. STM32. Програмування STM32F103. TIMER. Захоплення сигналу
- 11. STM32. Програмування STM32F103. TIMER. Encoder
- 12. STM32. Програмування STM32F103. TIMER. PWM
- 13. STM32. Програмування STM32F103. EXTI
- 14. STM32. Програмування STM32F103. RTC
- 15. STM32. Програмування STM32F103. BKP
- 16. STM32. Програмування STM32F103. Flash
- 17. STM32. Програмування STM32F103. Watchdog
- 18. STM32. Програмування STM32F103. Remap
- 19. STM32. Програмування STM32F103. I2C Master
- 20. STM32. Програмування STM32F103. I2C Slave
- 21. STM32. Програмування STM32F103. USB
- 22. STM32. Програмування STM32F103. PWR
- 23. STM32. Програмування STM32F103. Option bytes
- 24. STM32. Програмування STM32F103. Bootloader
- STM32. Скачати приклади
- System Workbench for STM32 Інсталяція на Ubuntu
- Keil uVision5 – IDE для STM32
- IAR Workbench – IDE для STM32
- Керування безколекторним двигуном постійного струму (BLDC) за допомогою STM32
- Керування PMSM за допомогою STM32
Недавні записи
- FOC - своя реалізація векторного керування. Підбиваю підсумки 2022 року
- Конструктор регуляторів моторів. Підбиваю підсумки 2022 року.
- Чому трифазні мотори стали такими популярними?
- FOC & Polar coordinates
- Конструктор регуляторів PMSM, BLDC двигунів
- Своя бібліотека для векторного керування безколекторними моторами
- Not Allowed
- Адаптивний ПІД регулятор
- Конструктор регуляторів моторів. Структура.
- Конструктор регуляторів моторів. Анонс.
Tags
st-link 3d-printer encoder servo solar java-script git wifi uart mpu-9250 sensors capture motor esp8266 nodemcu usb usart piezo rfid css atmega bmp280 bkp avr displays brushless watchdog battery sms rs-232 tim mpu-6050 barometer examples nvic pmsm dc-dc eb-500 soldering meteo rtc gpio books websocket docker dht11 led smd stm32 web timer dma lcd mpx4115a hih-4000 bldc ssd1306 adc mongodb python options eeprom raspberry-pi remap max1674 programmator ethernet foc ngnix ssd1331 gps flash exti bluetooth html bme280 i2c pwm flask
Архіви