Accéléromètre (4 points)
Protocole d'échange
Le protocole I2C ne permet que d'échanger des octets entre un maître et un esclave identifié par une adresse.
Pour permettre d'accéder à ses différentes fonctionnalités, l'accéléromètre dispose d'un protocole de communication construit au dessus du protocole basic I2C. Ce protocole est expliqué dans la section 6.3.1 pages 38 et 39 de la datasheet du composant.
L'accéléromètre est un esclave I2C situé à l'adresse 0b1101010
(la pin SA0
étant connectée à la masse).
Au sein de l'accéléromètre, il y a des registres, identifiés par une adresse sur 8 bits. Le protocole de communication permet au maître de lire ou d'écrire dans un de ces registres (ou éventuellement dans plusieurs en même temps).
La table 14 explique comment écrire dans le registre d'adresse SUB
la données DATA
. On notera qu'il s'agit là d'une transaction d'écriture I2C classique de deux octets (SUB
puis DATA
) terminée par une condition STOP
classique.
La table 16 explique comment lire depuis le registre d'adresse SUB
. La données lue est DATA
. On notera ici qu'il s'agit de deux échanges I2C, le premier d'écriture d'un octet (SUB
), sans STOP
suivi d'une lecture d'un octet.
Travail à faire
Dans un fichier approprié, vous allez écrire les fonctions nécessaires pour manipuler l'accéléromètre.
Protocole
Pour les deux fonctions suivantes, vous utiliserez notamment les fonctions I2C que vous avez déjà écrites précédemment.
❎ Écrivez une fonction void accel_write(uint8_t reg, uint8_t value)
Cette fonction prend les arguments suivants :
reg
: adresse du registre au sein de l'accéléromètrevalue
: valeur à écrire dans le registre
Cette fonction écrit la valeur value
dans le registre reg
de l'accéléromètre.
❎ Écrivez une fonction uint8_t accel_read(uint8_t reg)
Cette fonction prend l'argument suivant :
reg
: adresse du registre au sein de l'accéléromètre
Cette fonction retourne la valeur du registre reg
de l'accéléromètre.
Initialisation de base de l'accéléromètre
❎ Écrivez une fonction void accel_init()
Cette fonction :
- Appelle la fonction
i2c_init
pour initialiser le bus I2C utilisé par l'accéléromètre - Effectue un reset logiciel de l'accéléromètre (en utilisant le registre
CTRL3_C
de l'accéléromètre, cf. page 62 de la datasheet de l'accéléromètre) - Lit la valeur du registre
WHO_AM_I
de l'accéléromètre et compare la valeur lue à la valeur attendue. Si cette valeur n'est pas correcte, rentrez dans une boucle infinie (pour vous permettre de détecter que vous n'arrivez pas à communiquer avec l'accéléromètre)
Activation de l'accéléromètre
❎ Complétez votre fonction accel_init
pour activer l'accéléromètre (i.e. faire en sorte qu'il mesure l'accélération sur les trois axes régulièrement).
Dans notre cas, nous n'avons pas besoin d'effectuer des mesures trop souvent. Vous configurerez l'accéléromètre avec la fréquence d'échantillonnage la plus basse (1,6 Hz), cf. registres CTRL1_XL
et CTRL6_C
.
Lecture d'un échantillon
Un échantillon est composé de la mesure de l'accélération sur 3 axes : X, Y, Z. L'accélération sur chaque axe est codé sur 16 bits en complément à 2 (signé).
❎ Définissez une structure accel_value_s
permettant de stocker l'accélération mesurée sur chacun des trois axes.
❎ Écrivez une fonction void accel_value_read(accel_value_s *val)
qui attend qu'un échantillon soit disponible puis récupère l'accélération sur les 3 axes depuis l'accéléromètre et stocke les valeurs lues dans la structure pointée par val
. Indice : regardez le registre STATUS_REG
ainsi que OUTX_L_XL
et les suivants.
❎ Faites quelques tests et regardez les valeurs que vous obtenez en fonction des différentes orientations de la carte de TP.