... Blinky

Voici donc notre premier programme, Blinky ...

Comme son nom l'indique, il va nous servir à faire clignoter la Led située sur P0.7 par l'intermédiaire d'une résistance de limitation de 1 Kohms.

Ce premier projet est constitué de deux fichiers principaux, à savoir main.c et crt.s. Main.c contient bien évidement notre programme principal, mais qu'en est-il de crt.s ?

crt.s est en fait un programme assembleur qui sera le premier à être exécuté au reset du microcontrôleur. Il a pour but principal de définir les vecteurs d'interruption, les différentes piles (stacks) du LPC2106, etc...

Dans la foulée, il appellera la fonction main() de notre programme principal.

Pour l'instant, on ne s'attardera pas sur son contenu que l'on pourra détailler plus loin. Il faut simplement savoir qu'il existe et qu'il est très important, mais nous en reparlerons plus tard.

Sans plus attendre, voici notre premier code source:

// ..........................................

//

// Premiers pas dans le monde de l'ARM

//

// Auteur: Fred Microcontrollers and Robotics

// Date : 06 Octobre 2011

//

// Checked : 03 Juillet 2009 15:06

//

// Program_1: Blinky

// ..........................................


#include "lpc210x.h"


#define LED7 (1 << b7)


#define out |


// Le port P0.N est mis en sortie

void Led_Init(int N)

{

IODIR = IODIR out N;

}


// La Led n° N est allumée

void Led_On(int N)

{

IOSET = N;

}


// La Led n° N est éteinte

void Led_Off(int N)

{

IOCLR = N;

}


// Attente d'un certain temps défini par T

void Delai(unsigned long T)

{

while (--T!=0);

}


int main(void)

{

IODIR = 0;

Led_Init(LED7);

while (1)

{

Delai(100000);

Led_On(LED7);

Delai(100000);

Led_Off(LED7);

}

return(0);

}

Le fichier lpc210x.h dont il est question dans les #include contient les déclarations de tous les registres interne du LPC2106.

Les bits b0 à b31 du LPC2106 y sont également définis.

Certains préfèreront déclarer ces bits b0 b31 dans un fichier séparé de lpc210x.h, mais je préfère personnellement faire cette déclaration ici, sachant qu'il s'agit de décrire des bits de registres internes.

On retrouve donc les éléments que nous avons appris récemment au sujet des GPIO, à savoir: mise en entrée de tout le port P0 par IODIR = 0, puis initialisation de la pin P0.7 en sortie. Pour ce faire, plusieurs étapes sont à détailler:

Tout d'abord,

#define LED7 (1 << b7)

permet de définir LED7 comme étant équivalente au bit b7. La définition de b7 se trouve dans le fichier lpc210x.h, et équivaut en fait au chiffre 7. (On va voir dans quelques lignes l'explication détaillée).

#define out |

permet de définir out comme étant un OR.

Nous avions vu précédemment que pour mettre une pin en sortie, il fallait mettre le bit correspondant de IODIR à 1, et ce sans toucher aux autres bits pour ne pas modifier le sens des autres pins. Pour cela, il est possible de faire comme nous l'avions fait plus tôt, c'est à dire:

IODIR = IODIR | 0x00000080

Pour rappel, 0x00000080 traduit en binaire équivaut à

00000000000000000000000010000000

Pour se simplifier le travail, on a vu que l'on a défini ici LED7 (1<<b7), ce qui équivaut donc à dire (0x00000001 << 7).

On va donc effectuer 7 rotations à gauche du bit b0, ce qui positionnera ainsi b7 de LED7 à 1 et le reste à 0. On obtient bien notre masque 0x00000080.

On a bien effectué nos sept rotations ainsi:

00000000000000000000000000000001 ... départ: 0x00000001

00000000000000000000000000000010

00000000000000000000000000000100

00000000000000000000000000001000

00000000000000000000000000010000

00000000000000000000000000100000

00000000000000000000000001000000

00000000000000000000000010000000 ... arrivée: 0x00000080

De plus, le fait de définir out comme étant un OR, l'écriture de

IODIR = IODIR out 0x00000080 sera donc beaucoup plus parlante que

IODIR = IODIR | 0x00000080

La définition de LED7 amènera encore plus de clarté:

IODIR = IODIR out LED7

De même, on pourra définir in comme étant équivalent à ~&, ce qui comme nous l'avions appris à propos des GPIO nous permettra de mettre une pin en entrée de façon beaucoup plus parlante:

IODIR = IODIR in PIN4 par exemple.

En mélangeant les deux , on pourra donc orienter nos I/O sans confusion:

IODIR = IODIR out LED7 out RELAIS in KEYB in CAPTEUR;

Nous allons donc à présent agir sur IOCLR et IOSET pour allumer et éteindre notre Led. Les routines void Led_On(int N) et void Led_Off(int N) vont bien entendu utiliser IOSET et IOCLR avec les masques correspondant au numéro de Led à traiter.

Lorsque notre source semble correct, on va pouvoir le compiler en ouvrant une console Dos ou Linux et en tapant la commande suivante:

make all pour le compiler

et

make prog (ou make wprog sous Windows) pour le télécharger sur la carte, en n'oubliant pas d'appuyer sur le bouton Reset au moment voulu après avoir placé le jumper P0.14 à sa place.

Lorsque le téléchargement est terminé, on retire le jumper P0.14 et on resette à nouveau la carte.

On peut enfin admirer le superbe clignotement de la Led P0.7 !!!

Le rythme de clignotement de la Led est bien entendu géré par la routine Delai(100000).

Mais au fait, sommes nous bien en train de tourner à près de 60MHz ?

Regardons d'un peu plus près.