L'objectif de cette série d'articles est de présenter le microcontrôleur Propeller 2 de Parallax. Dans celui que vous lisez en ce moment, nous allons élargir les possibilités d'envoyer des chaînes de caractères, comme vous le faites avec la fonction print sur vos systèmes Arduino. Dans cette première tâche, nous allons pouvoir émettre de manière très classique quelques informations de débogage. Pour récapituler où nous en sommes : notre code est capable d'envoyer un caractère unique avec les paramètres suivants : 115200 bauds, 8 bits de données, pas de parité, un bit d'arrêt. Le code complet apparaît dans la figure 1 et il est possible de le télécharger à l'adresse suivante : [1].

Figure 1 : exemple de code pour envoyer un caractère.

Si nous voulons maintenant envoyer la chaîne « Code alive », comme le montre la figure 2, il faut effectuer plusieurs appels à la fonction tx(), un pour chaque caractère. Si nous voyons des lignes de code qui se répètent, il va être intéressant de réfléchir à généraliser la tâche. Copier des parties de fragments de code partout dans le projet n'est jamais une bonne idée, surtout si vous devez ajouter quelque chose ou corriger le code ultérieurement. Nous allons construire une fonction qui prend une chaîne de caractères comme argument, la découpe en caractères uniques et les envoie un par un à notre fonction tx(). Cela semble facile, et si vous avez une certaine expérience du codage, cela devrait théoriquement le rester. Si vous utilisez Spin2 ou Spin pour la première fois, il y aura sans doute un peu plus de lecture et de tâtonnements.
 

Figure 2 : envoi d'un texte, caractère par caractère.

Passage de chaînes de caractères

Comme les chaînes de caractères occupent un espace continu de mémoire contenant tous les caractères consécutifs ainsi qu'une terminaison formée d'un zéro binaire ("\0"), notre action consistera simplement à transmettre l'adresse de départ de cette mémoire à une fonction. Si nous utilisons le langage C/C++, l'opérateur & fera l'affaire, en conjonction avec le premier élément. Avec Spin2, la syntaxe est un peu différente, mais le fonctionnement est pratiquement le même. Ce qui diffère, c'est la façon dont nous déclarons la fonction et l'argument lui-même. Le type de variable passé à notre fonction n'est pas spécifié. Si nous n'indiquons aucun type, le langage Spin2 considèrera qu'il s'agit d'un type long (32 bits). Il est parfois pratique, dans certains cas, d'appliquer cette hypothèse automatique avec Spin2 pour les variables passées à une fonction, mais au prix d'un certain nombre d'effets secondaires indésirables. Dans notre cas, il s'agit de l'adresse mémoire de notre chaîne de caractères et cela conviendra parfaitement à notre objectif. Ce qui va être différent, c'est la manière de déclarer les variables locales. Nous voyons clairement que toutes les variables, ici c, doivent être déclarées en tête de la fonction. Nous utilisons donc un caractère | après le crochet fermant de cette ligne. S'il nous faut plusieurs variables, nous les placerons sur cette ligne en les séparant par des virgules (,). La figure 3 montre à quoi ressemblera la tête de la fonction.

Figure 3 : tête de la fonction.

À l'intérieur de la fonction (voir figure 4), nous devons procéder à une lecture attentive des données, octet par octet. L'instruction c := byte[s++] nécessite quelques mots d'explication. Notre variable c n'a actuellement aucun type, ou plutôt, elle possède un type par défaut. En l'absence de la mention byte[], nous lirions 32 bits (uint32_t variable) en une seule fois ; avec byte[s++], nous allons lire un octet à l'emplacement de 's', à l'adresse mémoire où commence la chaîne. Le s++ ici, en conjonction avec byte[], garantit que l'adresse ne sera incrémentée que d'un octet. Si nous ne le faisons pas, toutes les opérations appliqueront un format 32 bits. Comme nous savons maintenant que nous lisons octet par octet, nous allons examiner l'instruction repeat while. Tant que c n'est pas égal (<>) au zéro binaire, tout ce qui se trouve à l'intérieur de l'instruction repeat while fera partie de la boucle.

Figure 4 : conversion des types.

À l'intérieur de la boucle, illustrée par la figure 5, la fonction tx() émet un octet. Une autre ligne récupère l'octet suivant et le place dans notre variable c. Ensuite, la boucle se poursuit et commence à vérifier si c est encore différent du zéro binaire.
 

Figure 5 : fonction tx() appelée octet par octet .

Notre fonction prints() est donc maintenant en place et nous sommes capables d'envoyer des chaînes de caractères, par le biais d'un UART, à un PC ou à un analyseur logique. La suite consiste à lire l'état des broches d'E/S et à transmettre l'information à l'aide de l'UART. Est-il si difficile de lire l'état d'une broche d'E/S ? Eh bien, en théorie, c'est très facile. Parfois, ce sont les petits extras qui font la différence et qui montrent l'étendue des fonctionnalités qu'offrent les broches intelligentes.


En savoir plus sur le Propeller 2 et les domaines s'y rapportant

Vous souhaitez davantage d'informations sur des sujets comme le microcontrôleur Propeller 2 de Parallax et le langage Spin2 ? Abonnez-vous au magazine Elektor dès aujourd'hui et bénéficiez de tous les articles, projets ou tutoriels publiés.