
Description :
CodeVisionAVR est environnement de développement
ou IDE (integrated Development Environment)
pour le développement de programme en C.
Codevision AVR
Tutorial :
1. Prise en main.
a) Création d'un nouveau projet.





b) Source.
c) 1er programme.
d) Programmation.
2. La programmation en C.
2.1 Les commentaires.
//Commentaire /*Commentaire*/ |
Sur plusieurs lignes :>
/*
Commentaire
Commentaire
*/ |
2.2 Syntaxe de base d'un programme.
#include <90s8535.h> /* Rajoute à la compilation le fichier 90s8535.h qui contient les paramètres de l’AT90S8535 */ void main(void) //Indique le début du programme principal dont les instructions sont entre {} { DDRB=0xFF ; //Chaque instruction doit se terminer par un « ; » PORTB=0xFF; } |
2.3 Entrées Sorties
DDRx Impose la direction des ports.
DDRA=0xF0 ; les bits 0 à 3 du portA sont
configurés en entrée et de 4 à 7 en sortie.
PORTx Impose l’état logique des bits
sur le port.
PORTA=0xF0 ; les bits 0 à 3 du portA
passent à l’état bas et de 4 à 7 à l’état haut.
DDRx.y Impose la direction du bit y du
port x.
DDRA.5=0 ; le bit 5 du port A est configuré
en entrée sans affecter les autres pattes.
PORTx.y Impose l’état logique du bit
y sur le port x.
PORTA.0=1 ; le bits 0 du port A passe
à l'état haut.
PINx.y récupère l’état
du bit y du port x.
z=PINA.0 La valeur du bit 0 du port A
est mise dans la variable z.
2.4 Temporisation.
#include <delay.h> doit être rajouté
sous #include <90s8535.h> pour pouvoir
utiliser les fonctions delay
delay_us(X) X détermine le nombre de
microseconde
delay_us(100); tempo de 100us
delay_ms(X) X détermine le nombre de
milliseconde
delay_ms(100); tempo de 100ms
2.5 Les variables
Les variables permettent de stoquer des informations de différents types.
Type |
Taille
en bits |
Valeurs |
bit |
1 |
0 , 1 |
char |
8 |
-128 à 127 |
unsigned char |
8 |
0 à 255 |
signed char |
8 |
-128 à 127 |
int |
16 |
-32768 à 32767 |
short int |
16 |
-32768 à 32767 |
unsigned int |
16 |
0 à 65535 |
signed int |
16 |
-32768 à 32767 |
long int |
32 |
-2147483648 à 2147483647 |
unsigned long int
|
32 |
0 à 4294967295 |
signed long int
|
32 |
-2147483648 à 2147483647 |
float |
32 |
±1.175e-38 à±3.402e38 |
double |
32 |
±1.175e-38 à ±3.402e38 |
La variable bit doit être seulement
déclarée en variable globale
Pour declarer une variable il suffit de précéder
son nom de son type.
Pour l'affecter il suffit de faire une égalité.
Si elle n'est pas initialisée elle sera automatiquement
mise à 0 au démarrage du programme.
int X=45;
Il existe certaines regles à respecter en ce
qui concerne les noms de variables en C. Tout
d'abord, la variable ne doit pas commencer par
un chiffre mais par une châine de caractère.
Il faut aussi toujours définir la variable avant
de l'utiliser.
2.5.1 La portée des variables
Chaque variable a une portée définie par la
façon dont elle est declarée.Si une variable
est decrarée en debut de programme, juste apres
void main par exemple, celle-ci sera utilisable
dans l'integralitée du programme, elle est appellée
variable globale. En revanche, si l'on declare
une variable à l'intérieur d'une procédure ou
fonction, celle-ci ne sera utilisable que dans
cette procédure ou fonction, il s'agit donc
d'une variable locale.
Donc une variable locale cesse d'exister à la
fin de la fonction. C'est pourquoi il existe
des variables static, qui continuent
d'exister apres la fonction.
int alfa(void) { static int n=1; // déclaration et initialisation d'une variable static return n++; } void main(void) { int i; i=alfa(); // i=1 i=alfa(); // i=2 } |
Les variables globales peuvent être stockées à un endroit spécifique de la SRAM avec l’opérateur @
int a @0x80; // la variable "a" sera stockée dans la SRAM à l'adresse 80 |
2.6 Les types de constantes
décimales: pas de préfixe ex: 255
hexadécimales: préfixe 0x ex: 0x0F
binaires: préfixe 0b ex: 0b11111111
octales: préfixe 0 ex: 0377
Entieres non-signées : suffixe U ex:1000U
Entieres longues : suffixe L ex: 99L
Entieres non-signées et longues : suffixe UL ex: 99UL
Réelles : suffixe F ex: 1.234F
Caractères : entre ' ex : 'a'
Chaînes de caratères : entre " ex : "Hello world" Si vous placez une chaîne de caractère entre " comme paramètre d’une fonction, cette chaîne sera considérée comme une constante et sera automatiquement stocké dans la mémoire Flash.
2.7 Les tableaux
Les variables peuvent être stockées sous forme de tableaux qui peuvent avoir jusqu’à 8 dimensions.
Le 1ere élément d’un tableau est toujours dans la case 0.
Exemples:
int tab1[32]; // tableau de 32 éléments non initialisées int tab2[]={1,2,3}; int tab3[4]={1,2,3,4}; char tab4[]=”Ceci est une chaine de caracteres”; int tab5[32]={1,2,3}; // Seulement les 3 premiers éléments sont initialisés le reste est à 0 int multidim_tab[2][3]={{1,2,3},{4,5,6}};// Tableau à plusieurs dimensions |
2.8 Les structures conditionnelles
if - structure si
|
if (expression) { Instruction; } |
Elle évalue d'abord l'expression (la condition) entre parenthèses. Si la condition est vraie, elle exécute l'instruction. Si la condition est fausse l'instruction est ignorée.
if else - structure si sinon
|
if (expression) { Instruction1; } else {instruction2; } |
Elle évalue d'abord l'expression. Si la condition est vraie, elle exécute l'instruction1. Si la condition est fausse l'instruction2 est exécutés.
switch - structure commutateur
|
switch (variable) { case valeur1 : instruction1; break; case valeur2 : instruction2; break; case valeur3 : instruction3; break; . . . default: instruction_default; } |
Si la valeur de la variable est égale à une des valeurs de la liste alors l'instruction associée est exécutée. Si la valeur de la variable ne correspond à aucune des valeurs alors l'instruction_default est exécuté.
2.9 Les boucles
While - structure tant que
|
while (expression) { Instructions; } |
Elle évalue d'abord l'expression (la condition) entre parenthèses. Si la condition est vraie, elle exécute l'instruction. Puis elle teste de nouveau la condition et cela jusqu'à ce que la condition devienne fausse. Alors la boucle se termine et le programme passe à la suite.
Do While - structure faire tant que
|
do { Instructions; } while (expression); |
L'instruction s'exécute, puis l'expression est évaluée. Si elle est vraie, on effectue de nouveau l'instruction, et ainsi de suite.
For - structure pour
|
for (expression 1; expression 2; expression 3) { instructions; } |
Le rôle de l'expression 1 est d'initialiser un paramètre qui contrôle la reprise de la boucle. L'expression 2 est la condition à satisfaire pour continuer l'exécution de la boucle et l'expression 3 sert à modifier la valeur du paramètre initialisé par l'expression 1.
2.10 Les fonctions
Les fonctions sont des parties de code source qui permettent de réaliser le même type de traitement plusieurs fois. Il faut les déclarer avant des les utiliser. En général, on les définit avant le main.
Toute fonction qui n'est pas de type void retourne un résultat. Le type de ce résultat est celui de la fonction. La génération du retour de fonction est provoquée par l'appel de l'instruction return.
#include <90s8535.h> #include <delay.h> int add(int a,int b) /* int correspond au type de la variable de retour de la fonction add. |
#include <90s8535.h> #include <delay.h> clignote() { PORTB.0=1; delay_ms(500); /*Permet de faire clignoter 1 fois une led connectée à la patte 0 du port B*/ PORTB.0=0; delay_ms(500); } main () { DDRB.0=1; clignote(); } |
2.11 Les opérateurs
| Opérateur | Fonction | Exemple |
ARITHMETIQUES |
||
| = | Affectation | i=0x0F |
| + | Addition | i=1+2 |
| - | Soustraction | i=4-2 |
| * | Multiplication | i=2*3 |
| / | Division | i=6/2 |
| % | Modulo/Reste de la divistion | i=6%2 |
| += | i=i+3 | i+=3 |
| -= | i=i-3 | i-=3 |
| *= | i=i*3 | i*=3 |
| /= | i=i/3 | i/=3 |
| %= | i=i%2 | i%=2 |
| ++ | Incrémentation | i++ |
| -- | Décrémentation | i-- |
LOGIQUE
BIT A BIT |
||
| =~ | Inversion niveau bits | i=~0x0F |
| & | ET niveau bits | i=0xF0&0x0F |
| | | OU niveau bits | i=0xF0|0x0F |
| ^ | OU exclusif niveau bits | i=0xF0^0x0F |
| &= | i=i&0x0F | i&=0x0F |
| |= | i=i|0x0F | i|=0x0F |
| ^= | i=i^0x0F | i^=0x0F |
| >>= | Décalage à droite | i>>=2 (2décalages) |
| <<= | Décalage à gauche | i<<=2 |
TEST |
||
| == | Egal | i==2 |
| < | Strictement inférieur | i<2 |
| > | Strictement supérieur | i>2 |
| <= | Inférieur ou égal |
i<=2 |
| >= | Supérieur ou égal |
i>=2 |
| && | ET logique | j >= 12 && j <= 143 |
| || | OU logique | j >= 12 || j <= 143 |
| ! | Inverse du test | !j |
| != | Différent | i != j |
2.12 Stockage dans la mémoire Flash
Les constantes peuvent être misent sous forme de tableaux jusqu'à 8 dimensions.
Pour le stockage, il suffit d’utiliser les mots-clés const ou flash.
Exemples:
flash int constante_entiere=1234+5; flash char constante_caractere=’a’; flash long constante_longue1=99L; flash long constante_longue2=0x10000000; flash int tab_entier1[]={1,2,3}; flash int tab_entier2[10]={1,2}; // les 2 1er élements sont à 1 et à 2 le reste est à 0 flash int mutidim_tab[2,3]={{1,2,3},{4,5,6}}; flash char chaine_caracteres1[]=”Ceci est une chaine de carateres”; const char chaine_caracteret2[]=”A?Ceci est aussi une chaine de caracteres ”; |
Les constantes peuvent être déclarées dans une fonction.
2.13 Allocation des variables aux registres
Pour utiliser toutes les possibilités de l’architecture et le set d’instruction AVR, le compilateur alloue une partie des variables aux registres du microcontrôleur.
Les registres de R2 à R14 peuvent être utilisés pour des variables bit.
Vous pouvez définir le nombre de registres qui
seront alloués aux variables bit dans Project|Configure|C
Compiler|Code Generation|Bit Variables Size
dans la liste déroulante. Cette valeur doit
être la plus basse possible. Si l’option
Project|Configure|C Compiler|Code Generation|Automatic
Register Allocation est cochée ou la directive
#pragma regalloc+ est utilisée,
le reste des registres entre le R2 et R14 ne
seront pas utilisés pour des variables bit mais
pour des variables globales char et int jusqu’au
registre R14.
Si l’allocation automatique est désactivée, vous pouvez utiliser le mot-clé register pour spécifier quelles variables globales seront allouées aux registres.
#pragma regalloc- // désactivation de l'allocation automatique register int alfa; // allocation de la variable alfa à un registre register int beta @10; // allocation de la variable beta sera faite aux registres paires R10,R12 |
Les variables locales char et int sont automatiquement allouées aux registres R16 à R21 dans l'ordre de déclaration.
2.14 Les structures
Dans un tableau, tous les constituants doivent être du même type. Ce n'est pas le cas des structures, qui sont des variables composées de plusieurs variables de types différents. Chaque champ n'est plus désigné par un numéro comme dans un tableau, mais par un identificateur.
Exemples:
/* Structure globale dans la SRAM*/ struct ram_structure { char a,b; int c; char d[30],e[10]; char *pp; } sr; /* Structure globale dans la FLASH */ flash struct flash_structure { int a; char b[30], c[10]; } sf; /* Structure globale dans l' EEPROM */ eeprom struct eeprom_structure { char a; int b; char c[15]; } se; void main(void) { /* Structure locale*/ struct local_structure { char a; int b; long c; } sl; |
Il existe quelques restrictions à utiliser des structures stockées dans la Flash AVRSM32 stocke 1 octet avec .DB dans le flash donc en réalité cela prend 2 octets, le compilateur de CodeVisionAVR remplacera les éléments char par des int. Ce qui augmente la taille d’un caractère.
Les structures peuvent être composées de tableaux unidimensionnels.
Exemple : Comment créer une structure dans l'EEPROM :
/* Structure globale dans l'EEPROM */ eeprom struct eeprom_structure { char a; int b; char c[15]; } se[2]={{'a',25,"Hello"},{'b',50,"world"}}; void main(void) { char k1,k2,k3,k4; int i1, i2; /*Declare un pointeur sur la structure de l’EEPROM*/ struct eeprom_structure eeprom *ep; /* Accès direct aux éléments de la structure */ k1=se[0].a; i1=se[0].b; k2=se[0].c[2]; k3=se[1].a; i2=se[1].b; k4=se[1].c[2]; /* Le même accès à la structure en utilisant un pointeur */ ep=&se; /*Initialise le pointeur avec l’adresse de la structure */ k1=ep->a; i1=ep->b; k2=ep->c[2]; ++ep; /* Incrémente le pointeur */ k3=ep->a; i2=ep->b; k4=ep->c[2]; } |

