Étape 7: Codage du maître
Enfin, nous avons assez de compréhension de ce qui se passe dans les coulisses que nous pouvons passer par mon code, ligne par ligne, pour le maître et l’esclave de microcontrôleurs. Veuillez noter que si vous regardez le code ci-joint, vous trouverez des commentaires abondants autour de tout ce que nous discutons ici.
Commençons par quelques nouvelles lignes que nous ajoutons à notre section de réinitialisation :
lds temp,PRR<br>andi temp,0b01011111<br>sts PRR,temp<br>ldi temp,255<br>sts TWBR,temp<br>ldi temp,(1--TWPS1)|(1--TWPS0)<br>sts TWSR,temp<br>ldi temp, (1--TWINT)|(1--TWEN)<br>sts TWCR,temp
où vous vous souviendrez que le "-" signes doivent être laissés opérateurs de décalage.
Très bien. Nous savons déjà ce que fait le code ci-dessus puisque nous en avons discuté plus tôt. La première partie désactive simplement les bits de registre de réduction de puissance pour le timer/compteur et la DHT. La deuxième partie définit le débit binaire SCL et puis s’éteint l’interruption TW et permet à la DHT.
La prochaine chose à que faire est d’ajouter une ligne à notre routine principale qui appelle la sous-routine TWI. Ici ' tis :
main:<br>rcall button_push<br>rcall random<br>rcall dice<br>rcall cycle<br>rcall tw_transmit<br>rcall display<br>rjmp main
Notez que nous appelons la sous-routine tw_transmit juste après que, nous montrons les animés dés rouler et juste avant que nous affichons le résultat des dés rouler sur le rouleau dés LEDs.
Maintenant, nous arrivons à notre sous-routine TWI Master :
tw_transmit:<br>ldi temp, (1--TWINT)|(1--TWSTA)|(1--TWEN)<br>sts TWCR,temp
TWEN permet la DHT, TWSTA envoie une « condition de départ » vers le bas le fil qui est la chute d’impulsions pendant un SCL haut du cycle que nous avons discuté plus tôt et écriture TWINT = 1 pour le contrôle de Registre désactive l’indicateur d’interruption (c.-à-d. les résultats en TWINT = 0) et démarre la transmission d’un paquet de données.
rcall tw_wait
Il s’agit d’une sous-routine nous a écrit et qui se trouve juste là à attendre pour l’interface de TWI terminer notre commande.
lds temp,TWSR<br>andi temp,0b11111000<br>cpi temp,0x08<br>brne ERROR
Tout cela n’est vérifier le registre d’État pour voir ce qui est là. Chaque fois que la DHT fait quelque chose, il charge l’état actuel des lignes dans ce registre. Vous pouvez vérifier et s’assurer que la commande que vous avez émis en fait fait à la ligne et a été reconnue par l’esclave. La deuxième ligne définit notre diviseur bits à zéro (n’oubliez pas que nous les avons mis à 1 pour obtenir notre fréquence SCL à 490Hz). Il doit mettre à zéro afin que nous pouvons comparer le registre d’État avec les codes donnés dans le tableau 22-2. Notez que le code d’État 0 x 08 signifie la condition de départ a été envoyée et reconnue. Eh bien, ce qui est 0 x 08 en binaire ? C’est 0b00001000. Donc vous voyez que si nous avions oublié de masquer les trois premiers bits, notre TWSR contiendrait 0b00001011 = 0x0b et la comparsion échouerait. Si vous ne définissez les bits de diviseur comme nous avons fait et juste laissés par des zéros, puis vous n’aurais pas besoin de masquer ces bits. Le plus haut se termine par une pause à un gestionnaire d’erreurs qu’il faut écrire ce qui arriverait si nous n’avons pas le code d’état correct. Maintenant nous allons singulariser quel esclave nous voulons parler à :
ldi temp,0b10100000<br>sts TWDR,temp<br>ldi temp,(1--TWINT)|(1--TWEN)<br>sts TWCR,temp
Tout d’abord, nous remplissons le registre de données, TWDR, avec l’adresse de l’esclave et le peu de lecture/écriture. L’esclave 7 bits adresse que nous avons choisi au hasard (éviter ceux que la feuille de données nous a dit ne pas se servir) est 0b1010000 et nous virer un 0 sur la fin pour signifier que nous voulons « Écrire » à l’esclave. Si nous avions ajouté un 1 sur la fin cela voudrait dire que nous voulons « Lecture » de l’esclave. Et nous remettre les lignes de TWI en écrivant TWINT = 1 dans le registre de contrôle pour effacer l’interruption. Le TWEN = 1 est juste là pour qu’il reste 1 et la DHT reste « validée ». Ceci enverra les 8 bits de données sur toute la ligne SDA à l’esclave et l’esclave apportera la ligne au sol pour accuser réception. Nous attendons pour la transmission de remplir à l’aide de notre routine de tw_wait (sus-évoqué à la fin) et de vérifier le registre d’État afin de s’assurer qu’il tous obtenu envoyé et a reconnu exactement comme nous l’avons fait précédemment avec le signal de départ :
rcall tw_wait<br>lds temp,TWSR<br>andi temp,0b11111000<br>cpi temp,0x18<br>brne ERROR
Maintenant, nous voulons envoyer nos données. Étant donné que nous avons envoyé l’adresse de l’esclave et le bit de l’écriture, il sera assis là, baver en prévision, pour 32653 cycles d’horloge;) prêts à lire les 8 bits suivant le fil de la SDA au large et envoyez-les directement dans c’est propre registre TWDR. Nous voulons envoyer que le lancer de dés. Alors, voici comment nous procédons :
ldi temp,0<br>sts TWDR,temp<br>ldi temp,(1--TWINT)|(1--TWEN)<br>sts TWCR,temp<br>rcall tw_wait<br>lds temp,TWSR<br>andi temp,0b11111000<br>cpi temp,0x28<br>brne ERROR
Tout d’abord nous charger 0 dans le registre de données, puis nous tourner sur les lignes et envoyez-le. Puis nous attendre de la transmission au complet, et enfin, nous vérifions l’état de s’assurer, elle a été envoyée et a reconnu. Nous avons envoyé un zéro est parce que nous allons envoyer 2 octets. Le premier octet est chargé dans « playercashH » par l’esclave, et le deuxième octet est chargé dans « playercashL » par l’esclave. N’oubliez pas que nous voulons finalement envoyer deux octets, afin que nous puissions remplir vers le haut de l’affichage à 4 chiffres. Nous n’avez pas besoin eux cette fois donc nous envoyer juste un zéro pour le premier. Mais je l’ai mis ici car il montre comment envoyer plus d’un octet de données et également nous emploierons ce chemin la prochaine fois.
sts TWDR,dicetotal<br>ldi temp,(1--TWINT)|(1--TWEN)<br>sts TWCR,temp<br>rcall tw_wait<br>lds temp,TWSR<br>andi temp,0b11111000<br>cpi temp,0x28<br>brne ERROR
Ce qui précède doit être maintenant assez simple à comprendre. Nous avons simplement charger le registre de données à nouveau, cette fois avec le total de rouleau sur les deux dés et envoyez-le partout, vérification de l’état après que les lignes vont morts. L’esclave cela chargera dans playercashL. Nous avons maintenant terminé. Donc, nous sautons à notre sortie de commandes :
rjmp tw_return
Voici notre gestionnaire d’erreur. Je suppose que cela ne va jamais exécuté donc il n’est d’envoyer un signal d’arrêt à la ligne puis revenir au tout début et recommencez tout cela.
ERROR:<br>ldi temp,(1--TWINT)|(1--TWSTO)|(1--TWEN)<br>sts TWCR,temp<br>rjmp tw_transmit
Enfin, le nettoyage et la sortie :
tw_return:<br>ldi temp,(1--TWINT)|(1--TWSTO)|(1--TWEN)<br>sts TWCR,temp<br>ret
Ceci juste envoie un signal d’arrêt vers le bas de la ligne (puisque nous avons tourné le commutateur à bascule arrêt TWSTO), arrière s’allume interruptions globales et revient au « main ». Pour finir la discussion sur le Master code, voici la routine tw_wait :
tw_wait:<br>lds temp,TWCR<br>sbrs temp,TWINT<br>rjmp tw_wait<br>ret
Maintenant regardons le code Slave.