Langage C et PIC
Download
Report
Transcript Langage C et PIC
Langage C
Développement logiciel sur
micro-contrôleurs PIC en C
D’après Christian Dupaty, Académie d'Aix-Marseille
#include
<stdio.h>
main()
{ puts(" Bonjour
à tous ");
}
Bibliothèques
en C (texte)
*.c
Fichiers
header
*.h
Bibliothèques pré compilées
(fichiers objet)
Editeur de lien
Préprocesseur
Compilateur C
LINKER
Remplace les
#define et effectue
les #include
Transforme le fichier C en un
fichier objet (code machine),
les fonctions pré compilées
sont déclarées dans les fichiers
*.h
Lie (donne des adresses
aux fonctions) tous les
fichiers objets et crée un
fichier exécutable
Fichier
source C
contenant la
fonction
main
FLUX DE DONNEES D’UN
COMPILATEUR C
Fichier de
symboles
pour debug
Programme
exécutable
Syntaxe du C
#include <stdio.h>
#define pi 3.14
float d,c;
Header de la bibliothèque standard
in/out. (pour printf)
Equivalence : Le pré-processeur
remplacera tous les pi par 3.14
Déclaration de deux variables réelles globales
En tête du programme principal
int main()
Début de la fonction main
{
Calculs
d=2.0 ;
c=pi*d ;
Appel de la fonction puts (envoie une chaîne
puts("bonjour à tous\n"); de caractères sur le périphérique de sortie)
printf("la circonférence est %f m\n",c);
appel de la printf (affiche des chaînes
}
formatés, ici c est affiché sous format réel)
Fin de la fonction main
La syntaxe du C – allumer une led
void init_micro();
Librairies : les fichiers « header » *.h contiennent en général des
équivalences ou les prototypes des fonctions pré-complilées ou
non : ici essai.h contient les configurations des fusibles du µC.
void main()
{
Prototype : c’est la déclaration d’une fonction, il indique au
compilateur le type de la fonction et ses paramètres de passage.
#include "essai.h"
init_micro();
output_low(PIN_A0);
}
En tête de la fonction principale (main)
Appel de la fonction init_micro. (pas de paramètre d’entrée)
Appel de la fonction output_low. (permet de mettre un bit à 0,
le paramètre d’entrée est l’adresse du bit)
void init_micro()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(VREF_LOW|-2);
}
[email protected]
Les types de données standard
Type
Longueur
Domaine de valeurs
signed char ou char
8 bits
-128 à 127
unsigned char
8 bits
0 à 255
signed int ou int
16 bits
-32768 à 32767
unsigned int
16 bits
0 à 65535
long int
32 bits
-2 147 483 648 à 2 147 483 647
unsigned long int
32 bits
0 à 4 294 967 295
float
32 bits
±3.4 * (10-38) à ± 3.4 * (10+38)
double
64 bits
± 1.7 * (10-308) à ± 1.7 * (10+308)
void
-
vide
[email protected]
Les types de données propres à
PICC
Par défaut, les types entiers (int, char) de base sont non signés! Ils peuvent
être précédés de signed pour forcer le type signé.
Type
Longueur
Domaine de valeurs
int1 ou short
1 bit
0 ou 1
char
8 bits
0 à 255
int ou int8
8 bits
0 à 255
int16 ou long
16 bits
0 à 65535
int32
32 bits
0 à 4 294 967 295
float
32 bits
± 3.4 * (10-38) à ± 3.4 * (10+38)
void
-
vide
Exemples de déclaration
trois caractères
char tata,blabla,alea ;
tableau de 100 entiers
int table[100] ;
char tableau[ ]={10,0x1c,’A’,55,4}
char *p ;
le symbole * désigne un pointeur sur un type défini
p est un pointeur sur des caractères
Remarque:
un nombre entier en hexadécimal est précédé de 0x ou 0X, (0x1FB9)
un nombre entier en décimal n'a pas besoin de préfixe
un nombre réel se note 13.145 ou 1.3145e+1.
Dans les compilateurs pour µC: notation binaire 0b11010001
Equivalences
directive #define
Les équivalences sont remplacées par leur
valeur par le pré-processeur
#define pi 3.14
#define fruit pomme
Constantes
elles sont rangées dans la ROM et ne sont
donc pas modifiables.
const int i=16569, char c=0x4c ;
const float pi=3.14;
Le mot réservé « const » définit une constante
VARIABLES LOCALES ET GLOBALES
Les variables sont stockées en RAM afin d’être modifiables
au cours du programme. Elles peuvent être à une adresse
fixe (static) ou dans une pile (volatile).
GLOBLALES
LOCALES
Déclarées en dehors d’une fonction
toujours statiques
Déclarées dans une fonction
soit à une adresse fixe (statique)
static char toto;
soit dans une pile LIFO (automatique)
char tata; ou auto char tata;
Branchement : if - else
Condition du test : ==, <,>,<=,>=, !=,&&,|| …
if (A>B)
printf(“ A est supérieur à B”);
else
printf(“A est inférieur ou égal à B”);
…
si (A>B)
alors
afficher(“ A est supérieur à B”)
sinon
afficher(“A est inférieur ou égal à B”)
Boucle WHILE
i=0;
while (i<100)
{
a=a+i;
i++ ;
}
i 0
tant que (i<100)
faire:
a a+i
i i+1
Si la condition de boucle est fausse au départ la
boucle n’est jamais effectuée
Boucle DO WHILE
do
{
a=a+i;
i++ ;
}
while (i<100)
faire:
a a+i
i i+1
tant que (i<100)
Même si la condition de boucle est fausse au départ
la boucle est effectuée au moins une fois
Branchement switch-case
switch (c )
{
case '+' :
resultat=a+b;break;
case '-' :
resultat=a-b;break;
case '*' :
resultat=a*b;break;
case '/' :
resultat=a/b;break;
default : resultat=a+b;
}
suivant la valeur de (c )
début suivant
si '+' :
resultat a+b
si '-' :
resultat a-b
si '*' :
resultat a*b
si '/' :
resultat a/b
par default :
resultat a+b
fin suivant
Cette structure est une extension de la structure alternative
si..alors..sinon et permet une meilleur compacité du code.
Boucle FOR
Action(s) de départ
Condition pour rester dans la boucle
Action(s) à effectuer en dernier dans la boucle
for (i=0 ;i<100 ;i++)
{
a=a+i;
printf("%d\n",a);
}
Action(s) à effectuer dans la boucle
peut se traduire par:
i0
tant que (i<100))
faire a a+i
afficher_valeur(a)
i i+1
Cette structure est une extension de la structure répétitive
tant que … faire et permet une meilleure compacité du code.
Contrôle des boucles
break permet de sortir de la boucle en cours (for, while,
do while, switch)
continue permet de sauter directement à l’itération
suivante d’une boucle
for(i=0 ;i<100 ;i++)
{
if (i<50)
continue
else a=a+i;
}
exit permet de quitter directement le programme (inutile
sur micro contrôleur)
[email protected]
POINTEURS
Ce sont des variables qui contiennent l’adresse d’une autre variable.
Sur micro-contrôleur un pointeur est une valeur sur 16bits.
Un pointeur est déclaré par une * précédée du type de donnée pointée
Le signe & devant une donnée indique l’adresse de celle ci et sa valeur.
char *toto ; déclare un pointeur toto sur un caractère
float *tata ; déclare une pointeur tata sur un réel.
Au sein d'un programme *toto désigne la valeur pointée par toto, alors que
toto désigne l'adresse à laquelle est stockée cette valeur. L'intérêt des
pointeurs est de manipuler des adresses donc des zones entières de
données comme par exemple une chaîne de caractères.
manipulation de pointeurs
On pourra se servir des pointeurs pour accéder
directement à un port du µC:
// Une led est câblée sur PB4, allumée sur un état bas
char
*portB; //portB est un pointeur sur un octet.
portB = 0x06; //on définit l'adresse du pointeur ici le portb à l'adresse $06
while(true)
{
*portB=0b11111111;
//on fait clignoter la led.
delay_ms(300);
*portB=0b11101111;
delay_ms(600);
}
Sous PICC, il existe plusieurs autres possibilités pour accéder aux ports ou aux
registres du µC. Celle-ci est plus générale et plus transposable à d'autres
compilateurs et d'autres marques de µC.
TABLEAUX
Un tableau est un regroupement de variables de même type
C'est une façon plus commode, dans certains cas, d'utiliser les pointeurs.
le tableau est affecté avec les valeurs entre { }
int chiffres[ ]={1,2,4,8,16,32,64};
la taille du tableau est automatiquement
ajustée à 7 entiers.
int TAB[20]={1,12,13,-100};
TAB est un tableau de 20 entiers
dont seuls les 4 premiers sont
affectés
TAB représente l'adresse de début du tableau, pour accéder aux
différentes valeurs du tableau, on utilise un indice qui démarre à 0, ici
TAB[0] vaut 1, TAB[1] vaut 12, TAB[2] vaut 13 etc …
toto est tableau de 10 réels sans affectation.
float toto[10];
char TATA[2][3]={{1,2,3},{4,5,6}}
TATA est un tableau à 2 dimensions, on
utilise 2 indices.
Chaînes de caractères
Ce sont des tableaux de caractères codés en ASCII
finissant par la valeur $00, une chaîne est entourée de "
char message[ ]= "bonjour";
char message[ ]={‘b’,’o’,’n’,’j’,’o’,’u’,’r’,0x00} ;
deux façons différentes de déclarer et
d'affecter une chaîne de caractères
Présentation de PIC C
PIC C :
un environnement de développement en C complet
pour PIC. (éditeur, compilateur, débugger, moniteur
rs232 …)
un nombre assez important de fonctions intégrées et
de bibliothèques.
prise en main rapide
Ses inconvénients:
On notera surtout un non respect de la norme C ANSI
(comme on l'a déjà vu pour les types), des fonctions
parfois mal documentées
L'utilisation de PIC C
PIC C comprend un "wizard" (assistant) qui permet de se passer
de connaître parfaitement les registres et les bits de
configuration.
On choisit:
le µC
les ports de communication (RS232, SPI, I²C)
les timers
les entrées analogiques et le format (8 bits ou 10 bits)
les interruptions utilisées
les composants connectés
Cet assistant crée automatiquement le bout de programme
nécessaire qu'il serait fastidieux d'écrire à la main.
L'utilisation de PIC C (suite)
On se retrouve avec un texte de ce type:
#include "C:\Program Files\PICC\my examples\test.h"
void main()
{
l'assistant a créé un fichier .h dans lequ
se trouve les configurations
setup_adc_ports(NO_ANALOGS);
l'assistant a placé au début du programm
principal toutes les initialisations
setup_adc(ADC_OFF);
nécessaires
setup_psp(PSP_DISABLED);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
}
Pratique de PIC C
TP1
Voir texte du TP et notice de CCS
Entrées/sorties caractères
Les deux fonctions d’E/S sur caractère
Elle sont définies pour le matériel
support des communications
char getchar(void)
Lit un caractère en entrée
(CLAVIER par exemple)
int putchar(char)
Envoie un caractère
(LCD par exemple)
Entrées/sorties Chaînes
A partir de getchar et putchar
affiche une chaîne
de caractères
void
puts(char *chaîne) ;
char
*gets(char *chaîne) ;
saisie une chaîne de caractère finie
par un RC et retourne un pointeur sur
le premier caractère de cette chaîne
PRINTF
printf(format, liste de valeurs)
char a=10 ; float b=3.1412
printf(" décimal %d, hexa %x, reel %f " ,a,a,b) ;
affichera :
décimal 10, hexa A, reel 3,1412
sprintf(chaîne, format, liste de valeurs) écrit dans chaîne
Formats sur printf
%c (char)
%s (chaîne de caractères,
jusqu'au \0)
%d (int)
%u (entier non signé)
%x ou X (entier affiché en
hexadécimal)
%f (réel en virgule fixe)
%p (pointeur)
% (pour afficher le signe %)
[email protected]
\ n nouvelle ligne
\ t tabulation
\ b backspace
\ r retour chariot
\ f form feed
\ ' apostrophe
\ \ antislash
\ " double quote
\ 0 nul
Bibliothèques standards C ANSI
ctype.h trouver les types ex: isdigit (chiffre) ou
islower
limits.h indique les limites des types
string.h traitement sur les chaînes
math.h fonctions mathématiques
stdlib.h conversion de chaines (atoi atof)
génération d’un nombre aléatoire (rand, srand)
allocation dynamique de mémoire (malloc,
calloc), tri (qsort)
time.h fonctions liée à l’heure et à la génération
de nombre aléatoires
[email protected]
Opérateurs unaires
()
[]
!
~
+
++
-&
*
Appel de fonction
Indice de tableau
Négation logique (NOT)
Complément binaire bit à bit
Moins unaire
Plus unaire
Pré ou postincrément
Pré ou postdécrément
Adresse de
Indirection
tableau[3]=5;
b=~a
b=-a;
b=+a;
b=a++;
b=a--;
b=&a;
b=*a;
Opérateurs binaires
*
/
+
<<
>>
&
^
|
Multiplication
Division
Plus binaire
Moins binaire
Décalage à gauche
Décalage à droite
ET entre bits
OU exclusif entre bits
OU entre bits
c=a*b;
c=a/b;
c=a+b;
c=a-b;
c=a<<b;
c=a>>b;
c= a & b;
c= a ^b;
c= a|b;
TESTS
< Strictement inférieur if (a < b)
<= Inférieur ou égal
if (a >= b)
> Strictement supérieur if (a > b)
>= Supérieur ou égal
if (a >= b)
== Egal
if (a ==b)
!= Différent
if (a != b)
&& ET logique
if ((a==5) && (b==2))
|| OU logique
if ((a==5) ||(b==2))
?: Condition z=(a>b)?a:b (Si a>b a z=a sinon z=b)
Affectations et Auto-affectations
=
*=
/=
%=
+=
-=
&=
^=
|=
<<=
>>=
Affectation simple
a=b;
Affectation produit
a*=2 (a=a*2)
Affectation quotient
a/=2 (a= a/2)
Affectation reste
a%=2 (a= le reste de a/2)
Affectation somme
a+=2 (a=a+2)
Affectation différence
a-=2 (a=a-2)
Affectation ET entre bits
a&=5 (a=a&5)
Affectation OU EX entre bits
a^=5 (a=a^5)
Affectation OU entre bits
a|==5 (a=a|=5)
Affectation décalage gauche
a<<=5 (a=a<<5)
Affectation décalage droite
a>>=5 (a=a>>5)
Merci de votre attention
Exercez vous,
un langage s’apprend par la pratique
Compilateur C/C++ gratuits :
DOS : TURBO C/C++ V1.01 www.borland.fr
WINDOWS : DEV-C++ www.bloodshed.net
très performant, orienté C++ mais on peut faire du C, utilisé par
beaucoup de programmeurs chevronnés; certaines fonctions de
TurboC++ ne sont pas supportées
Pour PIC: CC5x http://www.bknd.com/cc5x/
(C'est un bon compilateur limité à 1k de code compilé par module, à
intégrer à MPLAB. Très peu de fonctions intégrées : impossible
de faire tourner des programmes écrits pour PICC avec CC5x, il
faut reécrire ses librairies)