This shows you the differences between two versions of the page.
pm:lab:lab6-2023-2024 [2024/04/14 21:53] irina_cristina.nita [1. I2C (Inter-Integrated Circuit)] |
pm:lab:lab6-2023-2024 [2024/04/15 18:35] (current) victor.stoica0203 [3. Registre configurare I2C] |
||
---|---|---|---|
Line 7: | Line 7: | ||
===== Laboratorul 6: I2C (Inter-Integrated Circuit) ===== | ===== Laboratorul 6: I2C (Inter-Integrated Circuit) ===== | ||
- | Acest laborator acoperă noțiunea de I2C. Pentru aprofundarea acestui topic, consultați [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Datasheet ATmega328P]] și {{https://en.wikipedia.org/wiki/I%C2%B2C|Inter-Integrated Circuit}}. | + | Acest laborator acoperă noțiunea de I2C. Pentru aprofundarea acestui topic, consultați [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42743-ATmega324P_Datasheet.pdf|Datasheet ATmega324P]] și [[https://en.wikipedia.org/wiki/I%C2%B2C|Inter-Integrated Circuit]]. |
===== 1. I2C (Inter-Integrated Circuit) ===== | ===== 1. I2C (Inter-Integrated Circuit) ===== | ||
Line 59: | Line 59: | ||
===== 3. Registre configurare I2C ===== | ===== 3. Registre configurare I2C ===== | ||
- | Arduino poate funcționa atât în modul I2C Master cât și I2C Slave. | + | ATMega324P poate funcționa atât în modul I2C Master cât și I2C Slave. |
==== TWI Bit Rate Register ==== | ==== TWI Bit Rate Register ==== | ||
Line 116: | Line 116: | ||
Plăcuța de laborator este dotată cu un senzor de presiune atmosferică și temperatură care poate comunica cu microprocesorul nostru prin protocolul I2C, acesta fiind și usecase-ul la care vom lucra astăzi. | Plăcuța de laborator este dotată cu un senzor de presiune atmosferică și temperatură care poate comunica cu microprocesorul nostru prin protocolul I2C, acesta fiind și usecase-ul la care vom lucra astăzi. | ||
+ | Pinout-ul pentru I2C este: | ||
- | Comunicarea cu senzorul se va face prin citirea/scrierea registrelor senzorului, folosind I2C. | + | ^ I2C ^ GPIO Pin ^ |
+ | | I2C Enable | PA6 | | ||
+ | | SCL | PC0 | | ||
+ | | SDA | PC1 | | ||
+ | |||
+ | |||
+ | Comunicarea cu senzorul se va face prin citirea/scrierea registrelor senzorului, folosind I2C. Pentru accesarea unui registru, atât pentru scriere | ||
+ | cât și pentru citire, este necesară transmiterea adresei acestuia înainte de operație. Tabela cu registrele si adresele acestora, se găsește | ||
+ | în [[https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf|Datasheet]], în secțiunea ''14''. | ||
+ | |||
+ | {{ :pm:lab:lab6:mpl3115a2-registers.jpeg?400 |}} | ||
===== 6. Exerciții ===== | ===== 6. Exerciții ===== | ||
- | Descărcați {{:pm:lab:lab6:lab6-skel.zip|arhiva cu scheletul de cod}}. Urmăriți indicațiile din ''TODO''-uri. | + | Descărcați {{:pm:lab:lab6:lab6-skel-2023-2024.zip|arhiva cu scheletul de cod}}. Urmăriți indicațiile din ''TODO''-uri. |
**Task 0.** Completați corpul funcțiilor ''twi_init'', ''twi_start'' și ''twi_stop'' din fișierul ''twi.c''. | **Task 0.** Completați corpul funcțiilor ''twi_init'', ''twi_start'' și ''twi_stop'' din fișierul ''twi.c''. | ||
+ | <note> | ||
+ | Definițiile constantelor le găsiți în [[https://www.nongnu.org/avr-libc/user-manual/group__util__twi.html|avr-libc util/twi.h]]! | ||
+ | </note> | ||
**Task 1.** Completați corpul funcțiilor ''twi_read_ack'', ''twi_read_nack'' și ''twi_write'' din fișierul ''twi.c''. | **Task 1.** Completați corpul funcțiilor ''twi_read_ack'', ''twi_read_nack'' și ''twi_write'' din fișierul ''twi.c''. | ||
Line 142: | Line 156: | ||
</note> | </note> | ||
- | **Task 3** În următoarele task-uri, vom folosi senzorul **MPL3115A2**, prezentat anterior. Pentru a putea configura și citi valorile | + | <note important> |
- | registrelor senzorului, vom urmării pașii din diagrama de stări de mai jos, preluată din [[https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf|Datasheet MPL3115A2]]. | + | Pentru a indica faptul că urmează să se facă o citire de tipul //Master Receiver//, trebuie trimisă prima dată **adresa dispozitivului** de pe magistrala I2C |
+ | de la care dorim să primim date. Dacă dispozitivul "își recunoaște" adresa, ne va trimite un ACK. Pentru că dorim doar să descoperim dispozitivele, este suficient | ||
+ | doar un "ping" de acest fel, fără o citire de date ulterioară. | ||
+ | |||
+ | * Adresă pentru citire: <code c> (DEVICE_ADDRESS << 1) | 1 </code> | ||
+ | * Adresă pentru scriere: <code c> DEVICE_ADDRESS << 1 </code> | ||
+ | |||
+ | Conform documentației, adresa senzorului nostru este **0x60** (deci, adresa pentru citire este 0xC1, iar cea pentru scriere este 0xC0). | ||
+ | </note> | ||
+ | |||
+ | **Task 3.** În următoarele task-uri, vom folosi senzorul **MPL3115A2**, prezentat anterior. Pentru a putea configura și citi valorile | ||
+ | registrelor senzorului, vom urmări pașii din diagrama de stări de mai jos, preluată din [[https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf|Datasheet MPL3115A2]]. | ||
{{ :pm:lab:lab6:mpl3115a2-statemachine.png?500 |}} | {{ :pm:lab:lab6:mpl3115a2-statemachine.png?500 |}} | ||
- | **Task 3.1** Pentru început, vrem să inițializăm senzorul. Completați corpul funcției ''mpl3115a2_init'' din fișierul ''mpl3115a2.c''. Aceasta va trebui apelată în cadrul | + | <note important> |
+ | **HINT:** Exemplul oferit setează registrul **CTRL_REG1** astfel încât senzorul să se comporte ca un altimetru. Pentru că dorim să calculăm | ||
+ | presiunea, setați corespunzător bit-ul **ALT**. | ||
+ | </note> | ||
+ | |||
+ | **Task 3.1.** Pentru început, vrem să inițializăm senzorul. Completați corpul funcției ''mpl3115a2_init'' din fișierul ''mpl3115a2.c''. Aceasta va trebui apelată în cadrul | ||
funcției ''main'', înainte de loop. | funcției ''main'', înainte de loop. | ||
- | **Task 3.2** Completați corpul funcțiilor ''mpl3115a2_read_pressure'' și ''mpl3115a2_read_temperature'' din fișierul ''mpl3115a2.c''. Acestea vor trebui apelate în cadrul | + | **Task 3.2.** Completați corpul funcțiilor ''mpl3115a2_read_pressure'' și ''mpl3115a2_read_temperature'' din fișierul ''mpl3115a2.c''. Acestea vor trebui apelate în cadrul |
funcției ''main'', în interiorul loop-ului. Afișați valorile citite pe serial. | funcției ''main'', în interiorul loop-ului. Afișați valorile citite pe serial. | ||
<note> | <note> | ||
- | **HINT** În secțiunea ''14'' a Datasheet-ului găsiți descrierea registrelor. Partea întreagă și partea fracționară a valorilor citite sunt detaliate acolo. | + | **HINT 1:** În secțiunea ''14'' a [[https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf|Datasheet]]-ului găsiți semnificația registrelor. |
+ | |||
+ | **HINT 2:** Formula pentru a calcula presiunea în //Pa// este: | ||
+ | |||
+ | <code c> | ||
+ | /* Q18.2 fixed point format where there are 18 integer bits and two fractional bits */ | ||
+ | PRESSURE = ((OUT_P_MSB << 12) | (OUT_P_CSB << 4) | (OUT_P_LSB >> 4)) >> 2 | ||
+ | </code> | ||
</note> | </note> | ||
+ | <note important> | ||
+ | Pașii pentru a citi dintr-un registru, folosind funcțiile din task-urile 0 și 2, sunt: | ||
+ | |||
+ | <code c> | ||
+ | /* Send START condition */ | ||
+ | twi_start(); | ||
+ | |||
+ | /* Write SLA_W on the I2C bus because we're going to send the register address next */ | ||
+ | twi_write(DEVICE_ADDRESS << 1); | ||
+ | |||
+ | /* Write the register address */ | ||
+ | twi_write(REGISTER_ADDRESS); | ||
+ | |||
+ | /* Send REPEATING START condition */ | ||
+ | twi_start(); | ||
+ | |||
+ | /* Write SLA_R on the I2C bus because we're going to read */ | ||
+ | twi_write((DEVICE_ADDRESS << 1) | 1); | ||
+ | |||
+ | /* Read from the sensor. The last read must be sent with NACK */ | ||
+ | uint8_t data = 0x00; | ||
+ | twi_read_nack(&data); | ||
+ | |||
+ | /* If we're not going to do anything next, send STOP condition */ | ||
+ | twi_stop(); | ||
+ | |||
+ | </code> | ||
+ | |||
+ | </note> | ||
<hidden> | <hidden> | ||
Line 164: | Line 231: | ||
</hidden> | </hidden> | ||
- | ===== 4. Linkuri utile ===== | + | ===== 7. Linkuri utile ===== |
* [1] [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42743-ATmega324P_Datasheet.pdf|Datasheet ATmega324P]] | * [1] [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42743-ATmega324P_Datasheet.pdf|Datasheet ATmega324P]] | ||
Line 170: | Line 237: | ||
* [3] [[https://learn.sparkfun.com/tutorials/i2c/all|I2C]] | * [3] [[https://learn.sparkfun.com/tutorials/i2c/all|I2C]] | ||
+ | ===== 8. Responsabili laborator ===== | ||
+ | * [[irina_cristina.nita@stud.acs.upb.ro|Irina-Cristina Niță]] | ||
+ | * [[sebastian.severin@stud.acs.upb.ro|Sebastian Severin]] | ||