Étape 7: Implémentation du Code ATTiny USI I2C - USI I2C esclave
Alors, comme un utilisateur final, vous êtes probablement plus intéressés à la façon d’interfacer la bibliothèque à votre propre code ! C’est facile, et Voici pourquoi. J’ai fait disparaître les tampons de réception/émission qui ont été utilisés dans d’autres implémentations de USI I2C (principalement ceux basés sur AVR312 app-note) et au lieu de cela mis en place le Registre protocole bancaire décrit au début de ce tutoriel. La Banque est stockée sous forme de tableau de pointeurs, pas les valeurs de données, donc vous devez joindre des variables locales dans votre code à des adresses de mémoire dans l’I2C registre banque en définissant les pointeurs pour pointer vers votre variables. Cela signifie que votre code de la canalisation principale ne doit jamais un sondage I2C tampons ou gérer des arrivées de données, les valeurs sont mises à jour instantanément chaque fois qu’ils arrivent. Il permet également aux variables de programme à être interrogé à tout moment par l’interface I2C sans affecter le code de la canalisation principale (autre que le retard en raison de l’interruption). Il s’agit d’un système assez soigné. Prenons encore un exemple bref.
Par exemple, disons que nous avons un générateur PWM logiciel très basique qui est le moteur une LED. Nous voulons être en mesure de changer la valeur PWM (d’une valeur de 16 bits, juste pour le plaisir de connaître de pointeurs) sans faire la boucle principale compliquée. Grâce à la magie du asynchrone I2C esclave, nous pouvons faire exactement cela !
#include « usi_i2c_slave.h »
Définir une référence à la matrice de pointeur I2C esclave registre banque
extern char * USI_Slave_register_buffer [] ;
int main()
{
Créer de la valeur PWM 16 bits
unsigned int pwm_val = 0 ;
Assigner l’octet de poids faible valeur pwm à I2C interne adresse 0 x 00
Assigner l’octet haut de valeur pwm à I2C interne adresse 0 x 01
USI_Slave_register_buffer [0] = (unsigned char *) & pwm_val ;
USI_Slave_register_buffer [1] = (unsigned char *)(&pwm_val) + 1 ;
Initialiser l’I2C esclave avec l’adresse du périphérique esclave 0 x 40
USI_I2C_Init(0x40) ;
Mis en place des broches A0 en sortie pour LED (nous supposerons que quelque puce nous sommes a broches A0 disponible)
DDRA | = 0 X 01 ;
while(1)
{
PORTA | = 0 X 01 ; Allumer la LED
pour (unsigned int i = 0; i < pwm_val; i ++)
{
PORTA & = ~ (0 x 01) ; Éteindre la LED
}
}
}
Et là vous l’avez ! La boucle principale ne fait aucune référence à I2C du tout, mais sur l’envoi d’une valeur PWM à l’emplacement de 16 bits I2C interne adresse 0 x 00/0 x 01, nous pouvons contrôler totalement le PWM de la LED ! Pour plus de stabilité (pour s’assurer que seules les valeurs de pointeur que vous utilisez sont disponibles et pour empêcher les pointeurs errants) je vous suggère de changer le #define USI_SLAVE_REGISTER_COUNT comme le nombre de pointeurs de registre dont vous avez besoin, ni plus, ni moins. Lorsqu’un accès (lecture ou écriture) est tenté sur un index de registre en dehors de la plage 0 x 00 à USI_SLAVE_REGISTER_COUNT - 1, rien n’est écrit et zéro est retournée.