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
Недавні записи
- Фільтрація Back-EMF. Безсенсорні BLDC мотори
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
Tags
barometer dht11 wifi bmp280 meteo ssd1306 uart books dc-dc lcd tim ssd1331 timer programmator battery exti mpx4115a motor flask nodemcu usb dma html java-script rs-232 st-link 3d-printer rfid esp8266 nvic encoder gpio piezo eb-500 brushless docker sms pmsm ngnix servo examples avr led smd i2c bkp eeprom usart solar soldering python flash stm32 raspberry-pi bme280 mpu-9250 hih-4000 foc bldc sensors rtc pwm capture adc max1674 atmega gps bluetooth remap mongodb mpu-6050 websocket css git watchdog displays ethernet web options
Архіви