Ceci est un extrait électronique d'une publication de Diamond Editions : http://www.ed-diamond.com Ce fichier ne peut être distribué que sur le CDROM offert accompagnant le numéro 100 de GNU/Linux Magazine France. La reproduction totale ou partielle des articles publiés dans Linux Magazine France et présents sur ce CDROM est interdite sans accord écrit de la société Diamond Editions. Retrouvez sur le site tous les anciens numéros en vente par correspondance ainsi que les tarifs d'abonnement. Pour vous tenir au courant de l'actualité du magazine, visitez : http://www.gnulinuxmag.com Ainsi que : http://www.linux-pratique.com et http://www.miscmag.com hacks/codes microcontrôleurs Coder pour Atmel ATtiny Denis Bodor EN DEUX MOTS Dans un précédent hors-série (23), nous avons découvert la famille de microcontrôleurs Atmel AVR avec GCC et l’ATmega16. Nous allons aujourd’hui descendre dans la gamme et toucher l’ATtiny via un développement en assembleur AVR. 1. Ode à l’AVR our les lecteurs ayant raté le horssérie 23, voici un petit résumé de ce qu’est un microcontrôleur AVR. Un microcontrôleur est un processeur couplé à de la mémoire (Flash de préférence) et à un ensemble de fonctionnalités intégrées (convertisseurs, timers, sources d’interruption interne et externes, etc.). Pour utiliser le microcontrôleur, il suffit de créer un code et de le télécharger dans le composant. Dès la mise sous tension (ou après un reset), le microcontrôleur exécute le code embarqué. Il existe des centaines de microcontrôleurs produits par différents fabricants parmi lesquels Microchip, SGS Thomson, Intel ou encore Atmel. Ce dernier propose une vaste gamme appelée AVR qui est directement concurrente de la gamme proposée par Microchip sous le nom de PIC. AVR et PIC sont souvent mis dans le même panier, car ils font l’objet d’une attention toute particulière de la presse et des sites spécialisés en électronique. En effet, AVR comme PIC disposent d’une large logithèque, sont peu onéreux et relativement faciles à programmer, par rapport, par exemple, aux dérivés de 68HC11/12. La popularité des deux gammes, PIC et AVR, permet à l’utilisateur GNU/Linux de disposer d’un certain nombre d’outils de développement, contrairement aux autres microcontrôleurs du marché, pour lesquels il n’existe souvent que des solutions Windows. Les différents modèles d’une gamme se distinguent en fonction de plusieurs caractéristiques : La taille de mémoire Flash utilisable allant 90 du simple ko à 256 ko. Il faut préciser ici que cette valeur est relative, car certains microcontrôleurs se programment en mots de 16 bits et d’autres de 12 bits. Le nombre d’instructions téléchargeables dans la mémoire est donc variable selon le modèle et le fabricant. L e nombre d’entrées/sorties, de 3 à près d’une centaine. L a puissance en fréquence d’horloge ou en MIPS. L e nombre de convertisseurs analogique/digital. Le nombre de registres de travail et/ou le volume de mémoire vive (RAM). L es fonctionnalités courantes (timer, watchdog, PWM, etc.). Les fonctionnalités spécifiques (USB, USB On-The-Go (OTG), wireless, i2c, etc.). L e format (PDIP, SOIC, TQFP, PLCC, etc.). L e prix. C’est un avis tout personnel, mais l’AVR semble se distinguer très clairement des PIC et autres concurrents : U ne partie de la gamme AVR accepte du code développé avec GCC (ATmega par exemple) en raison de l’important volume de mémoire Flash. Comme l’article du hors-série le présentait, il est parfaitement possible d’écrire du code C efficace pour un microcontrôleur AVR et profiter d’une bibliothèque C spécialisée. Les petits modèles d’AVR se programmeront en assembleur. C’est l’objet du présent article. La programmation du microcontrôleur AVR est dite « ICSP » ou « in situ ». Le microcontrôleur est connecté classiquement, comme pour sa mise en œuvre définitive et on greffe une connectique spécifique pour le programmer sans avoir recours à un montage spécial (un programmeur). La liaison AVR/PC se fera généralement via un port parallèle (il existe également des adaptateurs série). Les PIC nécessitent souvent un programmeur comme le montage JDM (voir GLMF 73, juin 2005) via un port série RS232 en voie de disparition sur les configurations actuelles et posant un certain nombre de problèmes d’alimentation. Dans les deux cas, AVR comme PIC, les logiciels permettant le chargement du code dans la mémoire du microcontrôleur existent sous GNU/Linux. L ’assembleur utilisé pour les AVR est plus abordable pour le débutant. Certes, ce langage reste ce qu’il est, mais les PIC ajoutent à la complexité en travaillant avec deux banques (16F628 par exemple) avec lesquelles il faut jongler. Le jeu d’instructions de l’AVR est plus riche et, même si cela ne semble pas être un élément important pour les spécialistes, on dispose d’une plus grande liberté dans le développement. Arrêtons là le comparatif qui reste finalement très subjectif. PIC et AVR, autrement dit, Microchip et Atmel, sont en guerre sur ce secteur de marché et cela ne date pas d’hier. En 1997, GNU Linux Magazine France Microchip réglait déjà des comptes avec Atmel via un document intitulé « La vérité sur l’AVR » (« The Truth About AVR ») comparant leur produit avec ceux du concurrent. Le document est encore intéressant et amusant à lire aujourd’hui même si les griefs contre l’AT90S2313 et AT90S1200 ne sont plus d’actualité. Il est des domaines où la concurrence semble bien plus violente que dans le monde des systèmes d’exploitation pour PC et Mac. Fig. 1 : Schémas de connexion de l’adaptateur ICSP sur port parallèle. Ce montage est sans doute le plus simple qui soit, mais n’offre aucune protection. 2. ATtiny15L L’ATtiny15L est au cœur du présent article. Pour le décrire, commençons par l’aspect le plus bassement matérialiste : le prix. Un ATtiny15L, acheté auprès d’un détaillant électronique (GoTronic, Selectronic, Conrad, etc.), vous coûtera un peu plus de 3 euros. En prenant en compte les composants nécessaires à la fabrication de l’adaptateur ICSP et quelques composants de base pour l’expérimentation (résistances, LED, condensateurs, etc.), vous pouvez compter un budget entre 15 et 30 euros pour des heures de plaisir. Notez également que des kits de développement et des programmeurs Atmel existent sous les désignations STK200, STK300 ou STK500. Ces kits sont compatibles avec l’application de programmation pour GNU/Linux décrite ci-après. Si le prix d’un achat neuf calme vos ardeurs (environs 150 euros) peut-être aurez-vous la chance d’en trouver d’occasion sur les sites d’enchères en ligne. Néanmoins, la solution consistant à fabriquer son propre adaptateur ICSP est bien plus économique (quelques euros). Numéro 84 / Juin 2006 Venons-en aux caractéristiques de l’ATtiny15L dont le seul point faible, à mon goût, est le manque d’entrées/sorties, ce qui est normal vue sa taille. Ceci est toutefois largement compensé par la richesse des fonctionnalités : 1 ko de mémoire Flash. Voilà qui est largement suffisant pour les applications envisageables avec ce type de composant. Notez que la prochaine génération d’ATtiny disposera de bien plus de mémoire Flash pour un format (PDIP 8) identique. O scillateur interne de 1.6 Mhz. Il y a quelques années, il était nécessaire d’utiliser un quartz ou un circuit RC en guise d’horloge pour le microcontrôleur. L’ATtiny15L comme bien d’autres est en mesure de se passer de ce type de chose en utilisant son propre oscillateur interne calibré. Plus simplement, cela signifie l’économie de deux broches sur le composant et une mise en œuvre bien plus simple. 32 registres de 8 bits. Il s’agit, grossièrement, de la mémoire vive du système ou, si vous voulez, de vos variables. 6 4 octets d’EEPROM. Contrairement aux registres qui sont dans un état indéterminé après la mise sous tension, l’EEPROM conserve les données stockées lorsque le composant n’est plus sous tension. Nous avons donc la mémoire Flash pour le programme et les données statiques, les registres pour les variables et l’EEPROM pour le stockage. Une partie de la configuration du microcontrôleur est également stockée dans l’EEPROM. 6 entrées/sorties utilisables selon configuration. Il faut pondérer cette caractéristique, car sur les 6 E/S disponibles, une est utilisée, par défaut, par le reset externe. Il est possible de « récupérer » cette sortie, mais la programmation ICSP basse tension n’est alors plus possible. Sur les 5 E/S restantes, il faut également prendre en considération les multiples fonctions de chaque broche. Ainsi, par exemple, la broche 7, nommée PB2, est une E/S binaire, mais peut également être configurée comme source d’interruption externe ou entrée analogique. Notez également que 4 des 6 E/S sont utilisées pour la programmation ICSP. C’est à ce prix qu’il est possible de « bourrer » tant de fonctionnalités dans un composant de 8 broches. 2 timers. Un timer peut être vu comme une tâche de fond (attention, c’est une 91 hacks/codes microcontrôleurs simple illustration, un AVR n’est pas un système multitâche). Une fois configuré dans ce sens, un timer va déclencher périodiquement une interruption. Une interruption, comme son nom l’indique, est un évènement qui va interrompre le fonctionnement du programme. Le programmeur aura pris soin de créer un morceau de code spécifique qui sera alors exécuté. Ceci fait, le fonctionnement normal du code reprendra. Notez au passage que le microcontrôleur ne peut pas ne rien faire. Tout comme avec une application graphique, il faut une boucle principale. Un convertisseur analogique/digital (ADC) multiplexé en 4 canaux. Le monde ne se compose pas de 0 et de 1. Pour que le microcontrôleur puisse travailler avec des données analogiques, il faut les convertir en valeurs numériques. L’ATtiny15L intègre un convertisseur 10-bit utilisable de différentes manières (relative ou absolue). U ne sortie PWM rapide (Pulse Width Modulation ou modulation de largeur d’impulsion) à 150 kHz. Nous y reviendrons plus en détail dans un prochain article. D ifférentes fonctionnalités intéressantes, comme la mise en sommeil (sleep mode) avec un réveil sur changement d’état d’une des broches, le contrôle de la qualité d’alimentation (Brown-out Detection Circuit), le chien de garde (Watchdog) programmable pour assurer la disponibilité du système et le reset automatique en cas de problème, etc. 3. Programmation Au risque de me paraphraser (article dans le HS23), voici de brèves explications sur la méthode de programmation des composants AVR et l’ICSP. Le schéma page 91 présente la connexion et la composition de l’adaptateur ICSP sur port parallèle d’un PC. Comme vous pouvez le constater, il est très simple, mais des adaptateurs plus complexes reposant par exemple sur le driver de ligne 74HC244 sont documentés sur le Web et sont également supportés par les logiciels de programmation AVR existant sous GNU/ Linux. L’adaptateur décrit ici présente l’avantage de « tenir » dans un le cache plastique d’un connecteur parallèle, mais n’offre pas toutes les protections peut-être souhaitées (inversion de connecteurs, court-circuit, etc.). 92 L’ATtiny15L en situation. Notez le fil vert reliant le reset avec Vcc. Dans sa configuration par défaut, la broche 1 (PB5) n’est pas utilisable et doit être reliée au Vcc ou à un circuit avec un bouton poussoir et une résistance de rappel au Vcc. En mettant la broche 1 à la masse, on fait alors un reset du microcontrôleur. Remarquez que les adaptateurs ICSP, quels qu’ils soient, sont utilisables avec toute la gamme AVR 8-bit d’Atmel. Il faudra simplement prendre garde à bien repérer les broches MOSI (Master Out Slave In), MISO (Master In Slave Out), RST (reset) et SCK (Serial ClocK) pour chaque microcontrôleur de la gamme. Côté logiciel, j’ai opté pour uisp, un programme d’Uros Platise maintenu actuellement par Marek Michalkiewicz (http://www.nongnu.org/uisp/index.html). Ce logiciel en ligne de commande supporte bon nombre d’adaptateurs, dont celui décrit dans cet article (sous la désignation dapa pour « Direct AVR Parallel Access »). La programmation, une fois l’adaptateur connecté à l’AVR, se fera très simplement, en trois étapes.Tout d’abord, il convient d’effacer la mémoire Flash du microcontrôleur : uisp -dlpt=/dev/parport0 --erase -dprog=dapa On charge ensuite le programme : uisp -dlpt=/dev/parport0 --upload if=prog.hex \ -dprog=dapa -dno-poll -v Enfin, l’étape qui n’est pas strictement nécessaire mais fortement recommandée, la vérification : uisp -dlpt=/dev/parport0 --verify if=prog.hex \ -dprog=dapa -dno-poll -v Bien entendu, l’utilisateur doit avoir les permissions adéquates (rw) sur l’entrée dans /dev/parpot0 et le pilote ppdev doit être chargé dans le noyau. Le fichier prog.hex contient, au format hex Intel, le code issu de l’assemblage. Comme précisé en début d’article, les petits AVR se programment en assembleur (bien qu’il existe une technique permettant d’utiliser GCC pour ensuite bidouiller le code généré). Trois assembleurs destinés aux AVR se distinguent : GNU Linux Magazine France Coder pour Atmel ATtiny a vr-as : C’est l’assembleur GNU livré avec avr-gcc. Je ne recommanderai pas cette solution sauf si vous avez l’habitude de l’utiliser sur une autre plate-forme. La syntaxe de l’assembleur n’est pas la même que la solution mise à disposition par Atmel (AVR Studio) et l’adaptation de code trouvé sur le Web sera difficile. a vra : Voici l’une des solutions packagées dans Debian. L’assembleur est mature, mais nécessitera l’utilisation de fichiers d’en-tête personnalisés ou repris du kit de développement Atmel. Ceci n’est pas un point critique, car ces fichiers se limitent à décrire une correspondance entre des adresses et des mots clefs qu’on trouvera dans le datasheet (documentation) du composant. g avrasm : Un autre assembleur très performant et également compatible avec la syntaxe de l’assembleur Atmel. gavrasm séduit par le fait qu’il apporte des informations complémentaires lors de l’assemblage du code comme celles qu’on a l’habitude de trouver avec un compilateur C (avertissement des variables/registres définis mais non utilisés, etc.). On notera toutefois que gavrasm intègre « en dur » les correspondances habituellement déclarées dans les fichiers d’en-tête. Ceci peut sembler très pratique, mais souvent déroutant et surtout très inhabituel. 4. Et si on codait ? L’assembleur donne souvent une double image à la fois attirante et rebutante.Assembleur est souvent synonyme de performances, mais également de complexité. Ce n’est qu’en passant au-delà des préjugés qu’on se rend finalement compte qu’il n’en est rien. Il vous faudra simplement oublier vos habitudes de développeur C, Perl ou Python et les avantages mis à disposition par ces langages de haut niveau. Nous allons commencer par un classique du genre, j’ai nommé l’équivalent du « hello world », la fameuse LED qui clignote : .device attiny15 ; pour avra uniquement .include «attiny15IO.asm» .org 0x0000 rjmp RESET .org 0x0009 RESET: sbi DDRB,PB4 LOOP: sbi cbi rjmp PORTB,PB4 PORTB,PB4 LOOP Le fichier attiny15IO.asm contiendra alors simplement ceci : .equ .equ .equ .equ .equ .equ .equ PORTB DDRB PB4 PB3 PB2 PB1 PB0 = = = = = = = 0x18 0x17 4 3 2 1 0 Numéro 84 / Juin 2006 Avant toutes choses, précisons différents points : L’assembleur n’est pas sensible à la casse. Néanmoins, il est courant de laisser les instructions en minuscule et les constantes en majuscule. Les directives débutant par un point sont destinées à l’assembleur lui-même. Elles permettent de préciser des éléments importants pour l’assemblage comme, par exemple, le microcontrôleur cible (.device). L es commentaires sont précédés d’un point-virgule. L’assembleur ignorera tout ce qui se trouve entre ce symbole et la fin de la ligne. La simplicité de ce premier code n’a d’égal que son mauvais fonctionnement dans la pratique. Il est pourtant parfaitement fonctionnel, nous y reviendrons. Les directives .device et .include parlent d’elles-mêmes. .org permet de préciser une adresse où placer les instructions qui suivent. L’adresse 0x0000 de la Flash est le vecteur utilisé pour un reset. En d’autres termes, c’est l’adresse où se trouve le code à exécuter à la mise sous tension du microcontrôleur. Vous ne devez pas débuter votre code à cette adresse. En effet, les adresses 0x0000 à 0x0008 incluse sont utilisées pour les vecteurs d’interruption. Vous ne pouvez placer ici qu’une seule instruction, un saut relatif (rjmp) vers une adresse désignée par une étiquette, ici RESET:. Notez l’utilisation de .org juste avant. Les étiquettes ne servent que de repère dans le code, l’assembleur calculera le saut à effectuer pour vous. Vous pouvez placer des étiquettes où bon vous semble, si cela vous amuse. Justement nous en arrivons à RESET:. C’est ici que notre programme commence. L’instruction sbi pour Set Bit in I/O Register permet d’activer un bit (à 1) dans un registre d’E/S. Le registre utilisé est DDRB pour Data Direction Register port B. Il permet, pour chaque E/S de définir si elle est utilisée en entrée (0) ou en sortie (1). DDRB n’est qu’une constante représentant le registre à l’adresse 0x17. La correspondance vient directement de notre attiny15IO.asm où la directive .equ donne l’équivalence. Rappelons-le, ceci n’est utile que si vous utilisez avra. Le bit activé est PB4 pour l’E/S 4. C’est le bit 4 (cf. attiny15IO.asm). La suite du code débute à l’étiquette LOOP: avec sbi que nous connaissons déjà mais 93 hacks/codes microcontrôleurs utilisé, cette fois, sur le registre d’E/S PORTB. Celui-ci permet de définir l’état d’une E/S si celle-ci est configurée en sortie. L’instruction suivante, cbi (Clear Bit in I/O Register), procède à l’opération inverse, mettre un bit à 0.Vous l’aurez compris, nous activons la sortie et la désactivons immédiatement. Enfin, nous sautons à l’adresse désignée par LOOP:. Notre code boucle sans fin. Pour tester ce code, il nous suffit de placer une résistance de quelques 470 ohms en sortie de la broche 2 (PB4), puis une LED et de relier sa cathode à la masse. Nous assemblons ensuite notre code avec avra premier.asm ou gavrasm premier.asm (en commentant la ligne .include). Nous obtenons alors un fichier premier.hex qu’il nous suffit d’utiliser avec uisp, comme décrit précédemment. gavrasm créera, par défaut, un autre fichier qu’il est normalement possible d’obtenir avec avra. Malheureusement, avec la version testée (1.0.1 Build 113), une erreur de segmentation est provoquée en utilisant l’option adéquate. Ce fichier se nomme essai.lst, il s’agit d’un résumé de l’assemblage du code sous une forme intelligible par le développeur. On y trouve non seulement le code assembleur, mais également les adresses et le code binaire assemblé au format hexadécimal. On y voit, par exemple, clairement le saut vers RESET: ainsi que celui vers LOOP:. Une fois le code téléchargé dans l’ATtiny15L, un reset est effectué pour sortir du mode de programmation. Dès lors, le code est exécuté. Malheureusement, visuellement rien ne semble clignoter et pour cause. Le microcontrôleur est bien trop rapide et nous ne voyons tout simplement pas la transition. Nous devons donc ralentir la transition ou plutôt marquer une pose entre l’allumage et l’extinction de la LED. 5. Base de programmation ASM A ce stade, je vais considérer que vous avez assimilé les quelques éléments déjà donnés. Nous allons donc accélérer la cadence et prendre quelques raccourcis. Lorsque je parle de pause dans l’exécution du code, il ne s’agit en fait que de l’exécution d’instructions ne servant à rien. Il existe une instruction spécifique permettant d’obtenir ce résultat : nop. Cependant, celle-ci ne prend qu’un seul cycle d’horloge et multiplier les nop ne servirait à rien, si ce n’est remplir la mémoire Flash. 94 Nous allons plutôt créer une sous-routine sous la forme d’une boucle de retardement. Là encore, c’est un classique du genre dans l’apprentissage de l’assembleur pour les microcontrôleurs.Voici notre routine : delai: hop: clr t1 dec brne dec brne ret t1 hop temp hop En tout début de code, nous assignons des noms à certains registres : .def t1 = r1 .def temp = r16 Il ne s’agit pas de constantes définies avec la directive .equ, bien que cela s’en rapproche. Une fois ces deux lignes en place, t1 est le registre r1. Il est utile de procéder de la sorte pour assurer une certaine portabilité au code. L’ATtiny15L dispose de 32 registres, mais tous ne s’utilisent pas de la même manière : r16 à r29 supportent toutes les instructions de manipulation sur les registres. Je vous fais grâce de la liste, mais sachez que ces registres supportent les instructions sbci, subi, cpi, andi, ori et ldi permettant d’utiliser des valeurs immédiates. Une valeur immédiate est explicitement donnée dans le code. Ainsi, ldi temp,0x42 placera la valeur 0x42 dans le registre temp. Ceci ne fonctionnera que si temp est un registre entre r16 et r31. r 1 à r15 s’utilisent comme les registres précédents, mais ne supportent pas les manipulations avec des valeurs immédiates. Si vous voulez placer 0x42 dans le registre r1 par exemple, vous devrez faire ldi temp,0x42, puis mov r1,temp. Ces registres limités seront donc principalement utilisés pour des compteurs et d’autres opérations où le code n’initialise pas directement le contenu des registres. r30 et r31 peuvent être utilisés comme des registres classiques. Ils seront cependant réservés pour un mode d’adressage spécifique. Ces deux registres forment un pointeur de 16 bits (le pointeur Z) qui adresse la mémoire Flash. Une fois ces deux registres initialisés, on utilisera l’instruction lpm (Load Program Memory) qui chargera alors l’octet pointé dans r0. Ce type de manipulations permet de stocker dans la mémoire Flash, non plus des instructions, mais des données via la directive .db de l’assembleur. On placera à cet effet une étiquette permettant de calculer l’adresse à pointer. Revenons à notre sous-routine en l’étudiant pas à pas : d elai: clr t1, nous commençons par mettre le registre t1 à zéro. h op: dec t1, nous décrémentons ensuite le registre de 1. Initialisé précédemment à 0, celui-ci passe à 0xFF. A ce stade, il faut parler du principe des drapeau (flags). Certaines opérations « lèvent » des drapeaux en fonction GNU Linux Magazine France Coder pour Atmel ATtiny de leur résultat. Ici, le drapeau qui nous intéresse est Z pour Zéro. Celui-ci est activé lorsque le résultat d’une opération donne 0. b rne hop est une instruction de branchement conditionnel : Branch if Not Equal. Ce n’est pas très explicite, mais un saut est effectué si le drapeau Z n’est pas levé suite à la dernière opération (Not Equal, car dans une comparaison, lorsqu’il y a égalité, la différence est zéro). Ainsi, après chaque décrémentation, si le registre t1 n’est pas zéro, nous sautons à hop:. C’est une boucle conditionnée. d ec temp, décrémente temp. Si nous arrivons là, c’est que t1 est à zéro. temp sera initialisé dans le code avant l’appel à la sous-routine. brne hop est notre dernier branchement conditionnel qui utilise la précédente opération, celle qui décrémente temp. Cette condition ne sera testée qu’après chaque tour du registre t1. Nous avons deux boucles conditionnées imbriquées. La valeur placée dans temp détermine le nombre de « tours » de boucle utilisant t1. r et est l’instruction de retour permettant de terminer l’appel à la sous-routine. L’adresse de l’appel a été placée sur la pile. Cette pile supporte trois niveaux d’appels aux sous-routines, pas plus. Nous plaçons cette routine juste en dessous de la directive .org 0x0009 et avant RESET:. Ainsi, à moins d’un saut à l’étiquette delai:, ce code ne sera jamais exécuté. Nous pouvons ensuite modifier la boucle principale ainsi : LOOP: 6. Conclusion temporaire Arrêtons là pour cette fois. Il reste beaucoup à dire sur le développement en assembleur sur ATtiny15L et nous y reviendrons dans un prochain article où il sera question d’interruptions, de timer, de PWM et de stockage des données dans la mémoire Flash. En attendant, je vous conseille de vous équiper, de faire ces premiers essais et surtout de parcourir le datasheet téléchargeable sur le site du fabricant (http://www.atmel.com). liens L a page ATtiny15L sur le site Atmel : http://www.atmel.com/dyn/products/product_card. asp?part_id=2033 U n site incontournable par et pour les utilisateurs d’AVR : http://www.avrfreaks.net/ L e programmeur AVR de C. Tavernier : http://www.tavernier-c.com/programmateur_atmel.htm sbi ldi rcall cbi ldi rcall rjmp L a documentation wikibooks sur l’AVR : PORTB,PB4 temp,0x15 delai PORTB,PB4 temp,0x7F delai LOOP http://en.wikibooks.org/wiki/Atmel_AVR L ’article de Guido sur la programmation AVR en C : http://tldp.org/linuxfocus/Francais/November2004/ article352.shtml Dès le chargement du code dans l’AVR, on voit immédiatement le changement. Cette fois, le clignotement de la LED est bien visible (voir photo, non ça ne clignote pas dans le magazine). 2 Ceci nous a permis de faire connaissance avec la notion de sous-routines, de registres et de sauts conditionnels. A ce stade, vous avez une excellente base de travail en assembleur AVR. Denis Bodor, [email protected], [email protected] sites / / incontournables : www.gnulinuxmag.com p t t w H www.ed-diamond.com w Numéro 84 / Juin 2006 Toute l’actualité du magazine sur : Abonnements et anciens numéros en vente sur :