Cette article présente une suite de petits programmes qui m’ont permis de découvrir la carte PICDEM.net 2 et le compilateur C C18. Je n’aborde pas ici la pile TCP/IP mais des concepts beaucoup plus basiques tel que:
- la commande de DELs
- l’utilisation des boutons poussoirs
- la lecture du potentiomètre et du capteur de température : utilisation du convertisseur analogique numérique (CAN)
- la commande de l’afficheur LCD
- l’utilisation de la voie série
- l’utilisation de l’EEPROM externe en mode SPI
- les interruptions (Timer, USART, PortB, …)
Remarquez que ces programmes ne sont en rien « spécifique » à cette carte et au PIC18F97J60 mais sont utilisables sur une carte de test classique équipée d’un PIC18F2520 par exemple.
Imprimer cet article
Le schéma de la carte PICDEM.net 2 est donné dans la documentation de cette carte par MicroChip. Je suppose que l’environnement de développement MPLAB et le compilateur C18 sont installés. Comme je débute avec C18, j’utilise l’assistant de création de projet : menu Project->Project Wizard. J’utilise aussi comme base de départ le document de présentation du compilateur C18 de l’académie d’Aix-Marseille et le document « MPLAB C18 C Compiler : Getting Started ».
Présentation de la carte
- PIC18f97j60 : PIC avec contrôleur ethernet embarqué
- ENC28J60 : contrôleur ethernet externe
- 25LC256 : Mémoire EEPROM SPI
- Afficheur LC 2×16 caractères compatible HD44780
- Connecteur pour afficheur LCD externe optionnel
- Capteur de température TC1047
- Huit dels connectées au port J du PIC
- Quatre boutons poussoirs connectés au port B du PIC (portB<3:0>)
- Potentiomètre de 10K relié entre la masse et le +3,3V relié à l’entrée analogique AN2
- Bouton de Reset du PIC
- Connecteur RJ45 pour ethernet 10base-T (1 pour connexion directe au PIC, 1 pour connexion au ENC28J60)
- Connecteur RJ12 pour programmation in-situ du PIC (compatible avec le programmateur PicKit2)
- Connecteur DB9 pour port série à la norme RS232 (liaison PC). J’ai rajouté un connecteur HE10-10 pour avoir une connexion série à la norme TTL.
- Port d’extension compatible PICTail
- Zone de prototypage
- Connecteur d’alimentation : continu de 7V à 15V
- Del de précense d’alimentation
- Sous la carte, deux autocollants avec les adresses MAC pour chacun des connecteurs ethernet
Projet1 : allumer des diodes !
Le premier projet MPLAB aura donc comme nom « DELs ». Je rajoute un fichier source avec le nom « dels.c ». Le contenu de ce fichier est le suivant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <18F97J60> // PIC utilisé sur PICDEM.net 2 #include // Fonctions de delai void main(void) // Prog principal { TRISJ=0x00; // Les dels sont reliés au port J // du PIC. On positionne tout le // port J en sortie while (1) // Boucle infinie { PORTJ=0xFF; // Tout le port J à 1 (dels allumées) Delay10KTCYx(100); // Attente de 10 000*100 cycles PORTJ=0x00; // Tout le port J à 0 (dels éteintes) Delay10KTCYx(200); // Attente de 10 000*200 cycles } // Fin boucle infinie } // Fin prog principal |
Les fusibles de programmation seront réglés par le menu Configure->Configuration Bits… comme dans la capture ci-dessous. Vous pouvez configurer les fusibles directement dans le code, là c’est juste la flemme 🙂
Si lors de la compilation le linker ne trouve pas le fichier « c018i.o », c’est que les chemins de recherche sont mal définis. J’ai résolu le problème par le menu Project->Build Options…->Project puis dans l’onglet Directories j’ai cliquez sur le bouton Suite Defaults. Si le linker échoue toujours, il faut regarder si les chemins sont configurés correctement dans Project->Set Language Tools Locations->Microchip C18->Default Search Path et positionnez correctement toutes les entrées.
La programmation s’effectue avec un PICkit2 par le menu Programmer->Select Programmer->PICkit2 puis par Programmer->Program. Pensez à relâcher le RESET par Programmer->Release from Reset. Les 8 dels doivent clignoter.
Projet2 : Tester les boutons poussoirs
Création d’un nouveau projet « bp ». Ajout d’un fichier « bp.c ». Le code source de ce fichier est visible ci-dessous:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include // PIC utilisé sur PICDEM.net 2 #include // Fonctions de delai void main(void) // Prog principal { TRISJ=0x00; // port J en sortie (dels) TRISB=0x0F; // BP en entrée (RB0, RB1, RB2 et RB3) // Resistances de rappel au +VCC cablées while (1) // Boucle infinie { PORTJ=~PORTB&0x0F; // Lecture du port B et inversion puis // masquage des 4 bits de poids faible // puis recopie dans le port J Delay10KTCYx(100); // Attente de 10 000*100 cycles } // Fin boucle infinie } |
Lors de l’appui d’un bouton, la del correspondante s’allume.
Remarque: je trouvais lourd d’avoir à programmer le PIC puis à relâcher la ligne de RESET. Or dans le menu Programmer->Settings (si vous avez choisi un programmateur), vous pouvez choisir différentes options pour votre programmateur. J’ai donc choisi de relâcher la ligne de RESET après une programmation réussie (Run after a successful program) et de lancer une programmation automatique après chaque compilation réussie (Program after a successful build).
Projet3 : Utilisation du CAN (lecture potentiomètre et capteur de température)
Création d’un projet « CAN-Pot » et d’un fichier source en C « can-pot.c ». Pour ce premier test du CAN, je vais utiliser la doc et les registres internes du PIC. Je vais donc être au plus prêt du matériel mais la lisibilité du code s’en ressent :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include // PIC utilisé sur PICDEM.net 2 #include // Fonctions de delai void main(void) // Prog principal { TRISJ=0x00; // port J en sortie (dels) TRISA=0x06; // Potentiometre sur AN2 // Capteur de Temperature sur AN3 // Ces deux broches doivent être en entrée ADCON1=0b00001011; // B7 et B6 : non utilisé // B5 : 0 -> Vref-=GND // B4 : 0 -> Vref+=+Vcc // B3 à B0 : entrée AN0 à AN3 en mode Analogique // le reste en mode digital ADCON0=0b00001000; // B7 : 0 -> Pas de calibration du CAN // B6 : non utilisé // B5 à B2 : choix du canal à numériser : ici 2 // B1 et B0 : CAN non activé ADCON2=0b00111110; // B7 : 0 -> Alignement à gauche : resultat sur 8 bits dans ADRESH // B6 : non utilisé // B5 à B3 : Horloge Tad : ici à 20 // B2 à B0 : Horloge CAN : ici à Fosc/64 ADCON0|=0x01; // Alimentation du CAN while (1) // Boucle infinie { ADCON0|=0x02; // Lancement d'une conversion while ((ADCON0 & 0x02)==2); // Attente fin de conversion PORTJ=ADRESH; // Resultat de la conversion sur les dels Delay10KTCYx(1); // Attente de 10 000*1 cycles } // Fin boucle infinie } |
Après compilation et programmation, tout fonctionne comme attendu. Les 8 bits de poids fort du résultat de la conversion s’affiche sur les dels.
Je « recode » le même programme en utilisant les bibliothèques de fonctions standards fourni par MicroChip. Pour cela il faut utiliser le document MPLAB-C18-Libraries. Ci-dessous le code source :
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2
#include <delays.h> // Fonctions de delai
#include <adc.h> // Fonctions pour le CANvoid main(void) // Prog principal
{
volatile unsigned int resultat_CAN; // Variable pour stocker le résultat du CANTRISJ=0x00; // port J en sortie (dels)
TRISA=0x0C; // Potentiometre sur AN2
// Capteur de Temperature sur AN3
// Ces deux broches doivent être en entréeOpenADC( ADC_FOSC_64 &
ADC_LEFT_JUST & // Alignement à gauche dans la variable resultat_CAN
ADC_20_TAD,
ADC_CH2 & // Choix du canal à numériser
ADC_INT_OFF & // Pas d’interruption
ADC_REF_VDD_VSS, // Vref+=Vdd=3,3V Vref-=VSS=0V
11 ); // Masque pour indiquer les entrées A et NDelay10TCYx( 5 ); // Delai de 10*5 cycles
while (1) // Boucle infinie
{
ConvertADC(); // Lance la conversion
while( BusyADC() ); // Attend que la conversion soit finie
resultat_CAN = ReadADC(); // Stocker le résultat dans un entier non signé 16bits
PORTJ = resultat_CAN>>8; // PortJ est un port 8 bits, on récupère les 8 bits
// de poids fort de resultat_CAN
Delay10KTCYx(1); // Attente de 10 000*1 cycles
} // Fin boucle infinie
}
J’ai eu beaucoup plus de mal à faire fonctionner ce petit programme car la doc n’est pas très explicite sur comment utiliser les tensions de référence du CAN. En essayant ADC_REF_VDD_VSS, c’est à dire Vref+=VDD et Vref-=GND, le programme fonctionne. Par contre il faut reconnaitre que c’est plus lisible.
Je passe maintenant au test du capteur de température. Celui-ci est un TC1047 de chez MicroChip. Ce capteur peut mesurer des températures de -40°C à +125°C. Il est donné pour fournir 500mV à 0°C et a une sensibilité de +10mV/°C. La seule ligne a changé dans le code précédent est le choix du canal à numériser dans la ligne OpenADC : ADC_CH2 par ADC_CH3. Après recompilation et programmation, les dels affichent effectivement la « température » et celle-ci varie lorsque je pose mon doigt sur le capteur. Faisons un calcul pour vérifier la conversion, notez que celle-ci est loin d’être optimale puisque on numérise entre 0V et 5V. Or le capteur fournit une tension comprise entre 0,1V (-40°C) et 1,75V (+125°C). De plus je n’utilise que les 8 bits de poids forts d’où le quantum vaut (3,3V-0V)/255 = 12,94mV. En lisant les dels j’obtient le chiffre 58 soit une tension numérisée de 58*12,94mV = 0,75V soit une température de T=(0,75-0,5)/10mV soit T=25°C. La température est correcte !
Projet4 : Utilisation de la voie série
Maintenant que l’on sait lire la température, il serait intéressant de l’envoyer vers un PC par le biais d’une voie série RS232. La carte PICDEM.net 2 est équipée d’un connecteur DB9 et d’un convertisseur de tension type MAX232 pour mettre les bons niveaux de tensions. Dans ce programme, je vais utiliser la bibliothèque de fonctions fourni par MicroChip. Le PIC18F97J60 possède deux USART indépendantes. Celle qui est câblée sur la carte est la première. J’ouvre donc un nouveau projet dans MPLAB avec le nom « uart » ainsi qu’un nouveau code « uart.c ». Le code est donné ci-dessous:
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2
#include <delays.h> // Fonctions de delai
#include <adc.h> // Bibliothèque de fonctions pour le CAN
#include <usart.h> // Bibliothèque de fonctions pour l’USARTvoid initialisation(void)
{
TRISJ=0x00; // port J en sortie (dels)
TRISA=0x0C; // Potentiometre sur AN2
// Capteur de Temperature sur AN3
// Ces deux broches doivent être en entréeOpenADC( ADC_FOSC_64 &
ADC_LEFT_JUST & // Alignement à gauche dans la variable resultat_CAN
ADC_20_TAD,
ADC_CH3 &
ADC_INT_OFF &
ADC_REF_VDD_VSS,
11 );Open1USART( USART_TX_INT_OFF & // Initialisation voie série
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
80 ); // Vitesse 19200 voir tableau dans doc officiel du 18F97J60
}void main(void) // Prog principal
{
volatile unsigned int resultat_CAN;initialisation(); // Appel de la fonction d’initialisation
while (1) // Boucle infinie
{
ConvertADC(); // Lance la conversion
while( BusyADC() ); // Attend que la conversion soit finie
resultat_CAN = ReadADC(); // Stocker le résultat dans un entier non signé 16bits
PORTJ = resultat_CAN>>8; // PortJ est un port 8 bits, on récupère les 8 bits
// de poids fort de resultat_CAN
Write1USART( resultat_CAN>>8 ); // Ecriture sur la voie série 1 du résultat du CAN
Delay10KTCYx(1); // Attente de 10 000*1 cycles
} // Fin boucle infinie
}
C’est assez lisible comme code à condition de lire la documentation des bibliothèques. Comme je n’ai plus de port série DB9 sur mon portable, je jette un coup d’œil sur la ligne TX avec un oscilloscope et je retrouve bien la donnée affichée par les dels. La transmission s’effectue bien à 19200 bauds/s en 8N1.
Projet5: Mise en œuvre de l’afficheur LCD
Comme je ne peux pas connecter la voie série, je vais afficher la température sur l’afficheur LCD de la carte. MicroChip fournit une bibliothèque de fonctions pour gérer un afficheur compatible HD44780 du nom de XLCD. Je vais donc tester cette bibliothèque. Et c’est avec beaucoup de mal que j’obtient enfin un résultat. Il faut tout d’abord modifier le fichier « xlcd.h » disponible dans les fichiers include du compilateur C18 pour adapter le cablage de l’afficheur LCD à la carte PICDEM.net 2. J’obtient donc le fichier suivant:
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
// Afficheur LCD sur carte PICDEM.net 2
#define BIT8/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
/* #define UPPER *//* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTE
#define TRIS_DATA_PORT TRISE/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTHbits.RH1 /* PORT for RW */
#define TRIS_RW TRISHbits.TRISH1 /* TRIS for RW */#define RS_PIN PORTHbits.RH2 /* PORT for RS */
#define TRIS_RS TRISHbits.TRISH2 /* TRIS for RS */#define E_PIN PORTHbits.RH0 /* PORT for E */
#define TRIS_E TRISHbits.TRISH0 /* TRIS for E */
Lors de la compilation, le LCD restait désespérément muet ! J’ai donc cherché une solution sur différents forums. Il existe deux solutions à ce problème. La solution la plus simple est de mon point de vue de faire recompiler toute la partie gestion du LCD en insérant les fichiers source dans le projet MPLAB (voir capture d’écran ci-dessous) et PAS de créer une nouvelle librairie (la seconde solution, beaucoup trop lourde).
Faire bien attention à l’initialisation du LCD sinon seul le premier caractère s’affiche. Il manque aussi quelques fonctions de bases à XLCD comme un « gotoxy » ou un « clearscreen ». Une fois le problème du LCD résolu, un autre problème apparait. Comment transformer un nombre flottant en chaine de caractères. La fonction « ftoa » n’existe pas dans la librairie standard de MicroChip. Cependant, ce problème a été traité de nombreuses fois (faire une recherche avec ftoa dans les forums de MicroChip) et il existe plusieurs solutions. Pour ma part, j’ai choisi une solution relativement simple avec la fonction « sprintf » (consultez le code !). Enfin tout fonctionne maintenant, j’affiche sur la première ligne du LCD le résultat brut de la conversion du capteur de température en sortie du CAN et sur la deuxième ligne la température en degré. Le code est présenté ci-dessous :
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2
#include <stdio.h> // Bibliothèque d’entrées/sorties standard (ici pour sprintf)
#include <delays.h> // Fonctions de delai
#include <adc.h> // Bibliothèque de fonctions pour le CAN
#include <usart.h> // Bibliothèque de fonctions pour l’USART
#include <xlcd.h> // Bibliothèque de fonctions pour LCD
// Cela permet de définir les broches connectées
// au LCD// Les trois fonctions suivantes sont nécessaires pour XLCD
void DelayFor18TCY(void) // un delay de 18 cycles mini
{
Delay10TCYx(2);
}void DelayPORXLCD(void) // un delai de 15ms
{ // cycles = (delai * Fosc) / 4
Delay1KTCYx(94); // cycles = (15ms * 25Mhz) / 4 = 93750
}void DelayXLCD(void) // un delai de 5ms
{
Delay1KTCYx(32); // cycles = (5ms * 25MHz ) / 4 = 31250
}void initialisation(void)
{
TRISJ=0x00; // port J en sortie (dels)
TRISA=0x0C; // Potentiometre sur AN2
// Capteur de Temperature sur AN3
// Ces deux broches doivent être en entréeOpenADC( ADC_FOSC_64 &
ADC_LEFT_JUST & // Alignement à gauche dans la variable resultat_CAN
ADC_20_TAD,
ADC_CH3 &
ADC_INT_OFF &
ADC_REF_VDD_VSS,
11 );Open1USART( USART_TX_INT_OFF & // Initialisation voie série
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
80 ); // Vitesse 19200 voir tableau dans doc officielle du PIC18F97J60OpenXLCD( EIGHT_BIT & LINES_5X7 ); // Initialisation du LCD en mode 8 bits, 2 lignes, caractères 5×7
WriteCmdXLCD( CURSOR_OFF & BLINK_OFF); // Effacement du curseur
WriteCmdXLCD( SHIFT_DISP_LEFT ); // Déplacement du curseur aprés chaque caractère
}void main(void) // Prog principal
{
volatile unsigned int resultat_CAN; // variable contenant le résulat sur 10 bits de la conversion
char buffer[20]; // un tableau de caractères qui contiendra la coversion flottant vers asciiinitialisation(); // Appel de la fonction d’initialisation
while (1) // Boucle infinie
{
ConvertADC(); // Lance la conversion
while( BusyADC() ); // Attend que la conversion soit finie
resultat_CAN = ReadADC(); // Stocker le résultat dans un entier non signé 16bits
PORTJ = resultat_CAN>>8; // PortJ est un port 8 bits, on récupère les 8 bits
// de poids fort de resultat_CAN
Write1USART( resultat_CAN>>8 ); // Ecriture sur la voie serie du résultat de conversion
SetDDRamAddr(0); // On se positionne au début de la première ligne du LCD
putrsXLCD( « Temp. CAN: » ); // On affiche une chaine située en flash (put’r’s) sur le LCD
sprintf (buffer, « %u », resultat_CAN>>8); // On ecrit dans buffer la conversion en chaine
// de caractères des 8 bits de poids fort de resultat_CAN
putsXLCD( buffer ); // On affiche ‘buffer’ sur le LCD
SetDDRamAddr(0x40); // On passe à la deuxième ligne du LCD
putrsXLCD( « Temp. DEG: « ); // On affiche la chaine situé en flash
sprintf (buffer, »%d », (int)((((resultat_CAN>>8)*0.0129)-0.5)*100)); // on ecrit dans buffer la
// chaine de cractère qui correspond à la conversion en °C
// de la tension issu du capteur de température. Ici ce sera
// un nombre entier
putsXLCD( buffer ); // On l’affiche sur le LCDDelay10KTCYx(1); // Attente de 10 000*1 cycles
} // Fin boucle infinie
}
On peut améliorer le code en faisant par exemple 128 mesures de la température et faire une moyenne, afficher la température avec deux chiffres avant la virgule et un après (chiffre non significatif ici) ou encore rajouter quelques fonctions de gestion du LCD. Un exemple avec ces améliorations est donné ci-dessous:
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2
#include <stdio.h> // Bibliothèque d’entrées/sorties standard (ici pour sprintf)
#include <delays.h> // Fonctions de delai
#include <adc.h> // Bibliothèque de fonctions pour le CAN
#include <xlcd.h> // Bibliothèque de fonctions pour LCD
// Cela permet de définir les broches connectées
// au LCD// Les trois fonctions suivantes sont nécessaires pour XLCD
void DelayFor18TCY(void) // un delay de 18 cycles mini
{
Delay10TCYx(2);
}void DelayPORXLCD(void) // un delai de 15ms
{ // cycles = (delai * Fosc) / 4
Delay1KTCYx(94); // cycles = (15ms * 25Mhz) / 4 = 93750
}void DelayXLCD(void) // un delai de 5ms
{
Delay1KTCYx(32); // cycles = (5ms * 25MHz ) / 4 = 31250
}// Fonctions supplémentaires pour le LCD, libellé des fonctions en anglais
void GotoxyXLCD(unsigned char x, unsigned char y) // Déplacement du curseur en Y (0 ou 1) et X (0 à 15)
{
if (y<2 && x<16)
{
if (y) SetDDRamAddr(0x40+x);
else SetDDRamAddr(x);
}
}void ClearScreenXLCD(void)
{
static rom const unsigned char vide[]= » « ; // chaine d’espace pour effacer le LCD (16 caractères)GotoxyXLCD(0,0);
putrsXLCD(vide);
GotoxyXLCD(0,1);
putrsXLCD(vide);
}void initialisation(void)
{
TRISJ=0x00; // port J en sortie (dels)
TRISA=0x0C; // Potentiometre sur AN2
// Capteur de Temperature sur AN3
// Ces deux broches doivent être en entréeOpenADC( ADC_FOSC_64 &
ADC_LEFT_JUST & // Alignement à gauche dans la variable resultat_CAN
ADC_20_TAD,
ADC_CH3 &
ADC_INT_OFF &
ADC_REF_VDD_VSS,
11 );OpenXLCD( EIGHT_BIT & LINES_5X7 ); // Initialisation du LCD en mode 8 bits, 2 lignes, caractères 5×7
WriteCmdXLCD( CURSOR_OFF & BLINK_OFF); // Effacement du curseur
WriteCmdXLCD( SHIFT_DISP_LEFT ); // Déplacement du curseur aprés chaque caractèreGotoxyXLCD(0,0); // Message de bienvenue
putrsXLCD( « Capteur Temp » );
GotoxyXLCD(0,1);
putrsXLCD( « O. Dartois » );
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
Delay10KTCYx(255);
ClearScreenXLCD();
}void main(void) // Prog principal
{
unsigned char i; // variable sur 8 bit pour une boucle
volatile unsigned int resultat_CAN; // variable contenant le résulat sur 10 bits de la conversion
char buffer[20]; // un tableau de caractères qui contiendra la conversion flottant vers ascii
float temperature; // la variable qui accueille le calcul de température
int temp_entiere, temp_virgule; // deux variables entières pour réaliser la conversion flottant vers asciiinitialisation(); // Appel de la fonction d’initialisation
while (1) // Boucle infinie
{
resultat_CAN = 0; // remise à zero de la variable
for (i=0;i<128;i++) { // On fait 128 acquisition pour augmenter artificiellement la résolution (surechantillonage)
Delay1KTCYx(32); // On attends 5ms -> cycles = (5ms * 25MHz ) / 4 = 31250, Fosc=25MHz
ConvertADC(); // Lance la conversion
while( BusyADC() ); // Attend que la conversion soit finie
resultat_CAN += ADRESH; // Stocker les 8 bits de poids fort issu du CAN dans un entier non signé 16bits
}
resultat_CAN >>=7; // Division par 128 pour faire la moyenne
PORTJ = resultat_CAN; // Affichage sur les delstemperature = ((resultat_CAN*0.0129)-0.5)*1000; // Conversion tension vers température *10
// pour recuperer 1 chiffre aprés la virgule (vor ci-dessous)
temp_virgule = (int)(temperature) % 10; // Récupération de la partie décimale
temp_entiere = (int)(temperature / 10); // Récupération de la partie entière
GotoxyXLCD( 0,0 ); // On se positionne au début de la première ligne du LCD
putrsXLCD( « Temp. CAN: » ); // On affiche une chaine située en flash (put’r’s) sur le LCD
sprintf (buffer, « %4u », resultat_CAN); // On ecrit dans buffer la conversion en chaine
// de caractères des 8 bits de poids fort de resultat_CAN
putsXLCD( buffer ); // On affiche ‘buffer’ sur le LCD
GotoxyXLCD( 0,1 ); // On passe à la deuxième ligne du LCD
putrsXLCD( « Temp. DEG: « ); // On affiche la chaine situé en flash
sprintf (buffer, »%02d.%1d », temp_entiere, temp_virgule ); // on ecrit dans buffer la
// chaine de cractère qui correspond à la conversion en °C
// de la tension issu du capteur de température. Ici ce sera
// un nombre XX.Y où XX et Y sont des nombres entiers signés (%d)
putsXLCD( buffer ); // On l’affiche sur le LCD
} // Fin boucle infinie
}
Projet6: Suite de la mise en oeuvre de l’afficheur LCD : BarGraph
Dans plusieurs exemple de montage sur Internet, il n’est pas rare de trouver un afficheur LCD utilisé en « BarGraph ». C’est à dire une barre qui augmente ou diminue en fonction du phénomène que l’on mesure. Je me suis donné comme but dans ce projet de réaliser un bargraph sur la deuxième ligne de l’afficheur LCD qui réagisse à la tension donnée par le potentiomètre. Pour que le bargrah soit plus joli, il faut redéfinir des caractères de l’afficheur LCD. On dispose de huit caractères personnalisables. La matrice d’un caractère fait 5×8 (5 colonnes sur 8 lignes). Je redéfinis donc un caractère vide, un caractère avec une barre verticale puis deux puis trois puis quatre. Le caractère plein existe déjà dans le jeu de caractère de l’afficheur LCD. La redéfinition des caractères est donnée ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
//----------------------------------------- // Definition des 8 nouveaux caracteres // affichables par le LCD //---------------------------------------- unsigned char rom NewCharXLCD[8][8] = { // Vide { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000 }, // 1 barre verticale { 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000, 0b10000 }, // 2 barres verticales { 0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000, 0b11000 }, // 3 barres verticales { 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100, 0b11100 }, // 4 barres verticales { 0b11110, 0b11110, 0b11110, 0b11110, 0b11110, 0b11110, 0b11110, 0b11110 }, // Coeur gros { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000 }, // Coeur petit { 0b00000, 0b00000, 0b01010, 0b01110, 0b01110, 0b00100, 0b00000, 0b00000 }, //fleche gauche { 0b00000, 0b00001, 0b00011, 0b00111, 0b01111, 0b00111, 0b00011, 0b00001 }, /* // fleche haut { 0b00100, 0b01110, 0b11111, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110 } , // fleche bas { 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b11111, 0b01110, 0b00100 }, // e accent aigu { 0b00010, 0b00100, 0b01110, 0b10001, 0b11111, 0b10000, 0b01110, 0b00000 }, // e accent grave { 0b01000, 0b00100, 0b01110, 0b10001, 0b11111, 0b10000, 0b01110, 0b00000 }, // a accent grave { 0b01000, 0b00100, 0b01110, 0b00001, 0b01111, 0b10001, 0b01111, 0b00000 }, //degree { 0b00010, 0b00101, 0b00010, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000 } */ }; /* quelques caracteres supplementaires pouvant remplacer les precedant // un sourire { 0b01110, 0b11111, 0b01010, 0b00000, 0b10101, 0b10001, 0b01110, 0b00000 }, //rectangle vide { 0b11111, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111 }, //rectangle plein { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 }, */ |
L’exploitation de ces nouveaux caractères avec un « bargraph » est présenté ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#include // PIC utilisé sur PICDEM.net 2 #include // Bibliothèque d'entrées/sorties standard (ici pour sprintf) #include // Fonctions de delai #include // Bibliothèque de fonctions pour le CAN #include // Bibliothèque de fonctions pour LCD // Cela permet de définir les broches connectées // au LCD #include "NewCharXLCD.h" // 8 caractères personnalisables de l'afficheur LCD // Les trois fonctions suivantes sont nécessaires pour XLCD void DelayFor18TCY(void) // un delay de 18 cycles mini { Delay10TCYx(2); } void DelayPORXLCD(void) // un delai de 15ms { // cycles = (delai * Fosc) / 4 Delay1KTCYx(94); // cycles = (15ms * 25Mhz) / 4 = 93750 } void DelayXLCD(void) // un delai de 5ms { Delay1KTCYx(32); // cycles = (5ms * 25MHz ) / 4 = 31250 } // Fonctions supplémentaires pour le LCD, libellé des fonctions en anglais void GotoxyXLCD(unsigned char x, unsigned char y) // Déplacement du curseur en Y (0 ou 1) et X (0 à 15) { if (y<2 && x<16) { if (y) SetDDRamAddr(0x40+x); else SetDDRamAddr(x); } } void ClearScreenXLCD(void) { static rom const unsigned char vide[]=" "; // chaine d'espace pour effacer le LCD (16 caractères) GotoxyXLCD(0,0); putrsXLCD(vide); GotoxyXLCD(0,1); putrsXLCD(vide); } void SendNewCharXLCD(void) { unsigned char index; unsigned char rom * adresse; adresse=&NewCharXLCD[0][0]; SetCGRamAddr(0x40); // adresse du premier caractere personnalise for(index=0;index<65;index++) { putcXLCD(*(adresse++)); } } void initialisation(void) { TRISJ=0x00; // port J en sortie (dels) TRISA=0x0C; // Potentiometre sur AN2 // Capteur de Temperature sur AN3 // Ces deux broches doivent être en entrée OpenADC( ADC_FOSC_64 & ADC_LEFT_JUST & // Alignement à gauche dans la variable resultat_CAN ADC_20_TAD, ADC_CH2 & ADC_INT_OFF & ADC_REF_VDD_VSS, 11 ); OpenXLCD( EIGHT_BIT & LINES_5X7 ); // Initialisation du LCD en mode 8 bits, 2 lignes, caractères 5x7 WriteCmdXLCD( CURSOR_OFF & BLINK_OFF); // Effacement du curseur WriteCmdXLCD( SHIFT_DISP_LEFT ); // Déplacement du curseur aprés chaque caractère SendNewCharXLCD(); ClearScreenXLCD(); GotoxyXLCD(0,0); putcXLCD(0x20); // Affichage des 8 caractères redéfinis putcXLCD(0); putcXLCD(1); putcXLCD(2); putcXLCD(3); putcXLCD(4); putcXLCD(5); putcXLCD(6); putcXLCD(7); putcXLCD(0xFF); Delay10KTCYx(255); Delay10KTCYx(255); Delay10KTCYx(255); Delay10KTCYx(255); } void main(void) // Prog principal { int i,tension_entiere,tension_virgule; volatile unsigned char resultat_CAN; // variable contenant le résulat sur 10 bits de la conversion char buffer[20]; // un tableau de caractères qui contiendra la conversion flottant vers ascii char buff1[16], buff2[16]; float valmax, tension; unsigned char barre; initialisation(); // Appel de la fonction d'initialisation while (1) // Boucle infinie { ConvertADC(); // Lance la conversion while( BusyADC() ); // Attend que la conversion soit finie resultat_CAN = ADRESH; // Stocker les 8 bits de poids fort issu du CAN dans un entier non signé 16bits PORTJ = resultat_CAN; // Affichage sur les dels valmax = ( resultat_CAN/2.55 )/ 6.25; // Calcul de la valeur max pour le bargraph GotoxyXLCD( 0,1 ); // On passe à la deuxième ligne du LCD // La création du bargraph se fait avec les quatres lignes suivantes for (i=0;i<(int)valmax;i++) putcXLCD(0xFF); barre = (char)(( valmax - (int)valmax) / 0.2 ); putcXLCD( barre ); for ( i=0; i< (15-(int)valmax) ; i++) putcXLCD( 0x20 ); GotoxyXLCD( 0,0 ); // On se positionne au début de la première ligne du LCD putrsXLCD( "CAN:" ); // On affiche une chaine située en flash (put'r's) sur le LCD sprintf (buffer, "%03u Tpot:", resultat_CAN); // On ecrit dans buffer la conversion en chaine // de caractères des 8 bits de poids fort de resultat_CAN putsXLCD( buffer ); // On affiche 'buffer' sur le LCD tension = (resultat_CAN*0.0129)*10; // Conversion tension vers température *10 tension_virgule = (int)(tension) % 10; // Récupération de la partie décimale tension_entiere = (int)(tension / 10); // Récupération de la partie entière sprintf (buffer,"%d.%d", tension_entiere, tension_virgule ); putsXLCD( buffer ); // On affiche 'buffer' sur le LCD } // Fin boucle infinie } |
Ce qui donne en vidéo (de mauvaise qualité) ceci:
Projet7: Utilisation des interruptions – Le timer0
Dans un PIC18F, vous avez deux niveaux d’interruptions : haute et basse. Au moment ou vous activez une interruption, vous pouvez la déclarer en haute priorité ou basse priorité. Lorsqu’une interruption se déclenche, le PIC saute alors à deux adresses spéciales:
- l’adresse 0x08 : adresse pour les interruptions hautes priorités
- l’adresse 0x18 : adresse pour les interruptions basses priorités
A partir de là, il faut examiner les drapeaux pour savoir quelle interruption a été levé et rediriger vers la fonction adéquate. Pour déclarer les interruptions en C, il faut utiliser un vocabulaire particulier (se reporter au code ci-dessous) pour déclarer le vecteur d’interruption et les fonctions d’interruptions. Dans l’exmple ci-dessous, on utilise le timer0 en mode 16 bits pour faire clignoter la DEL de poids faible du port J tout en faisant « battre » un coeur sur l’afficheur LCD (imitation d’un signal « heartbeat »). Le code est donné ci-dessous:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2 #include <stdio.h> // Bibliothèque d'entrées/sorties standard (ici pour sprintf) #include <delays.h> // Fonctions de delai #include <timers.h> // Bibliothèque de fonctions pour les Timers #include <xlcd.h> // Bibliothèque de fonctions pour LCD // Cela permet de définir les broches connectées // au LCD #include "NewCharXLCD.h" // 8 caractères personnalisables de l'afficheur LCD void GotoxyXLCD(unsigned char x, unsigned char y); // protoype pour la fonction qui sera appelé lors d'une interruption void timer0_isr(void); // La fonction ci-dessous sera appelé lors de la détection d'une interruption // haute priorité. Cette fonction doit être à l'adresse 0x08 // Dans notre cas, on a activé qu'une seule interruption donc pas de traitement // pour savoir qui a déclenché l'interruption #pragma code high_vector=0x08 // Code positionné à l'adresse 0x08 void interruption_haute(void) { _asm GOTO timer0_isr _endasm // La fonction appellée depuis l'interruption } #pragma code // La fonction qui suit est une fonction d'interruption // elle ne doit pas avoir de paramètres, ni renvoyer de valeur car elle est appellée // en asynchrone. Les variables globales utilisées ici doivent être déclarés "volatile" #pragma interrupt timer0_isr void timer0_isr(void) { INTCONbits.TMR0IF = 0; // Remise à zero du drapeau d'interruption PORTJbits.RJ0^=1; // Inversion de l'état de la DEL (clignotement) GotoxyXLCD(15,0); // Dernier caractère de la première ligne du LCD if (PORTJbits.RJ0) putcXLCD(6); else putcXLCD(5); // Affichage tantot d'un "gros" coeur ou d'un petit "coeur" } // Les trois fonctions suivantes sont nécessaires pour XLCD void DelayFor18TCY(void) // un delay de 18 cycles mini { Delay10TCYx(2); } void DelayPORXLCD(void) // un delai de 15ms { // cycles = (delai * Fosc) / 4 Delay1KTCYx(94); // cycles = (15ms * 25Mhz) / 4 = 93750 } void DelayXLCD(void) // un delai de 5ms { Delay1KTCYx(32); // cycles = (5ms * 25MHz ) / 4 = 31250 } // Fonctions supplémentaires pour le LCD, libellé des fonctions en anglais void GotoxyXLCD(unsigned char x, unsigned char y) // Déplacement du curseur en Y (0 ou 1) et X (0 à 15) { if (y<2 && x<16) { if (y) SetDDRamAddr(0x40+x); else SetDDRamAddr(x); } } void ClearScreenXLCD(void) { static rom const unsigned char vide[]=" "; // chaine d'espace pour effacer le LCD (16 caractères) GotoxyXLCD(0,0); putrsXLCD(vide); GotoxyXLCD(0,1); putrsXLCD(vide); } void SendNewCharXLCD(void) { unsigned char index; unsigned char rom * adresse; adresse=&NewCharXLCD[0][0]; SetCGRamAddr(0x40); // adresse du premier caractere personnalise for(index=0;index<65;index++) { putcXLCD(*(adresse++)); } } void initialisation(void) { TRISJ=0x00; // port J en sortie (dels) PORTJ=0x00; // DELs éteintes OpenXLCD( EIGHT_BIT & LINES_5X7 ); // Initialisation du LCD en mode 8 bits, 2 lignes, caractères 5x7 WriteCmdXLCD( CURSOR_OFF & BLINK_OFF); // Effacement du curseur WriteCmdXLCD( SHIFT_DISP_LEFT ); // Déplacement du curseur aprés chaque caractère SendNewCharXLCD(); ClearScreenXLCD(); GotoxyXLCD(0,0); // Message d'accueil putrsXLCD( "Prog ISR-TIMER0 " ); GotoxyXLCD(0,1); putrsXLCD( "O.Dartois - 2009" ); // Dans la config HS, on obtient Fosc=25MHz // Calcul de la période du timer0: T0 = (1/25MHz)*4*65536*64 = 0,671s OpenTimer0( TIMER_INT_ON & // Activation de l'interruption Timer0 T0_SOURCE_INT & // Source d'interruption Timer0 T0_PS_1_64 & // Pré-diviseur par 64 T0_16BIT ); // Timer0 en mode 16 bits (de 0 à 65535) // Activation des interruptions INTCONbits.GIE = 1; } void main(void) // Prog principal { initialisation(); // Appel de la fonction d'initialisation while (1) // Boucle infinie { // La boucle est vide, tout se fait dans l'interruption } // Fin boucle infinie } |
Projet7: Utilisation des interruptions – Le timer1 – Horloge temps réel
La carte est équipée d’un oscillateur secondaire à 32768Hz connecté aux entrées d’oscillateur du timer1. Cela permet entre autre de réaliser une horloge temps réel (Real Time Clock = RTC) avec ce timer ou encore d’utiliser ce quartz comme source d’horloge basse consommation. Le programme ci-dessous réalise donc une horloge avec affichage sur l’affichage LCD. En laissant tourner le programme, j’ai observé « en gros » une dérive de 3s par jour, ce qui est correcte compte tenu de la qualité du quartz et que je ne compense pas le temps mis pour traiter l’interruption. Pour réaliser une horloge sans trop de dérive avec un timer plusieurs méthodes sont décrites sur le forum du compilateur Hi-Tech C ( lire XX). Le code est présenté ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
#include <p18f97j60.h> // PIC utilisé sur PICDEM.net 2 #include <stdio.h> // Bibliothèque d'entrées/sorties standard (ici pour sprintf) #include <delays.h> // Fonctions de delai #include <timers.h> // Bibliothèque de fonctions pour les Timers #include <xlcd.h> // Bibliothèque de fonctions pour LCD // Cela permet de définir les broches connectées // au LCD #include "NewCharXLCD.h" // 8 caractères personnalisables de l'afficheur LCD volatile unsigned int seconde=0, minute=0, heure=0; void GotoxyXLCD(unsigned char x, unsigned char y); // protoype pour la fonction qui sera appelé lors d'une interruption // Le timer1 est par défaut en interruption haute priorité void timer1_isr(void); #pragma code high_vector=0x08 void interruption_haute(void) { _asm GOTO timer1_isr _endasm } #pragma code #pragma interrupt timer1_isr void timer1_isr(void) { WriteTimer1(0x8000); // On part de 32768 pour aller à 65535 soit 1s avec le quartz à 32K PIR1bits.TMR1IF = 0; // Remise à zero du drapeau d'interruption seconde++; } // Les trois fonctions suivantes sont nécessaires pour XLCD void DelayFor18TCY(void) // un delay de 18 cycles mini { Delay10TCYx(2); } void DelayPORXLCD(void) // un delai de 15ms { // cycles = (delai * Fosc) / 4 Delay1KTCYx(94); // cycles = (15ms * 25Mhz) / 4 = 93750 } void DelayXLCD(void) // un delai de 5ms { Delay1KTCYx(32); // cycles = (5ms * 25MHz ) / 4 = 31250 } // Fonctions supplémentaires pour le LCD, libellé des fonctions en anglais void GotoxyXLCD(unsigned char x, unsigned char y) // Déplacement du curseur en Y (0 ou 1) et X (0 à 15) { if (y<2 && x<16) { if (y) SetDDRamAddr(0x40+x); else SetDDRamAddr(x); } } void ClearScreenXLCD(void) { static rom const unsigned char vide[]=" "; // chaine d'espace pour effacer le LCD (16 caractères) GotoxyXLCD(0,0); putrsXLCD(vide); GotoxyXLCD(0,1); putrsXLCD(vide); } void SendNewCharXLCD(void) { unsigned char index; unsigned char rom * adresse; adresse=&NewCharXLCD[0][0]; SetCGRamAddr(0x40); // adresse du premier caractere personnalise for(index=0;index<65;index++) { putcXLCD(*(adresse++)); } } void initialisation(void) { TRISJ=0x00; // port J en sortie (dels) PORTJ=0x00; // Toutes les sorties du port J à 0 OpenXLCD( EIGHT_BIT & LINES_5X7 ); // Initialisation du LCD en mode 8 bits, 2 lignes, caractères 5x7 WriteCmdXLCD( CURSOR_OFF & BLINK_OFF); // Effacement du curseur WriteCmdXLCD( SHIFT_DISP_LEFT ); // Déplacement du curseur aprés chaque caractère SendNewCharXLCD(); ClearScreenXLCD(); GotoxyXLCD(0,0); putrsXLCD( "Prog ISR-TIMER1 " ); GotoxyXLCD(0,1); putrsXLCD( "O.Dartois - 2009" ); // Dans la config HS, on obtient Fosc=25MHz // Utilisation du TIMER1 en tant que source d'horloge car quartz à 32768Hz // Calcul de la période du timer1: T1 = (1/32768)*(65536-32768) = 1s ! // Ceci afin de réaliser une horloge temps réel (RTC) sans circuit externe OpenTimer1( TIMER_INT_ON & // Activation interruption Timer1 T1_SOURCE_EXT & // Source d'horloge extérieure pour le Timer1 T1_PS_1_1 & // Pas de prédiviseur T1_16BIT_RW & // Ecriture directe en 16bit de TMR1H et TMR1L T1_OSC1EN_ON & // Activation de l'oscillateur basse conso => source extérieur à 32K T1_SYNC_EXT_OFF ); // Pas de synchronisation avec l'horloge principale // Activation des interruptions INTCONbits.GIE = 1; /* Activation globale des interruptions */ INTCONbits.PEIE = 1; /* Activation des interruptions des périphériques */ } void main(void) // Prog principal { unsigned char buffer[16]; initialisation(); // Appel de la fonction d'initialisation ClearScreenXLCD(); GotoxyXLCD(0,0); putrsXLCD( "Horloge RTC T1 " ); WriteTimer1(0x8000); while (1) // Boucle infinie { // Le traitement de l'heure en boucle principale if (seconde>59) { seconde=0; minute++; } if (minute>59) { minute=0; heure++; } if (heure==24) { heure=0; } sprintf( buffer, " %02u:%02u:%02u ", heure, minute, seconde ); GotoxyXLCD(0,1); putsXLCD( buffer ); GotoxyXLCD(15,0); if (seconde%2) putcXLCD(6); else putcXLCD(5); // Signal "heartbeat" } // Fin boucle infinie } |

bonjour j’ai un problème et j’ai besoin de votre aide
j’ai un signal analogique que je doit convertir a l’aide du convertisseur intègre dans le pic 18F252 et afficher ce résultat numérique sur LCD
et mon pic est connecter par voie série (deux broches TX RX) a un module sans fil qui est le xbee.
alors mon problème c’est bien la programmation du pic18F252
esq ce programme que vous avez réalise peu fonctionner dans mon cas si c’est non esq vous pouvez m’aider
merci et j’attend votre réponse je suis prise par le temps je dois en finir le plus vite possible
Vous pouvez utiliser les programmes de l’article, il vous faut juste le compilateur C18 et changer l’include de départ par un
#include p18f252.h
en mettant les signes < et > autour de p18f252.h. Ensuite le reste doit fonctionner…Bon courage
Olivier
merci bcp je fais ésaiyer
merci encor une fois
bonjour je v vous déranger encor un peu avec mes questions de débutante dans le domaine de parogrammation C.
la carte que j’ai réaliser comporte un quartz de 4MHZ et je veux bien programmer ma connexion série avec une vitesse de 9600bauds N-1-8
et la je me suis un petit peu perdue dans ces instructions
mon deuxieme problem c’est la compilation de mon programme avec C18 j’ai suivit toute les étapes pour mais une fois je l’éxcute avec F10 (make) sa m’affiche le message suivant :
Make: The target « C:\Users\nawel\Desktop\mplab\elecronique innovante.o » is out of date.
Executing: « C:\Program Files\MPLAB IDE\MCHIP_Tools\mcc18.exe » -p=18F252 « elecronique innovante.c » -fo= »elecronique innovante.o » -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
Skipping link step. The project contains no linker script.
BUILD FAILED: Mon Aug 02 20:43:29 2010
j’ais ésaiyer en ajoutant aussi le linker o.c dans le nom du fichier sa a marcher au début mé la sa marche plus je sais pas pour quoi?
j’ais encor ésaiyer en ajoutant le 18F252.lkr dans mon projet sa marche toujours pas?
je souhaite bien recevoir votre réponse le plus vite possible puisque comme je vous ais dit avant j’ais pas trop de temps je suis prise par le temps
merci d’avance.
bonjour j’attends toujours votre réponse je travaille dessus depuis plus d’une semaine et j’ai toujours le même problème
s’il vous plais j’ai vraiment besoin de votre aide
merci d’avance
bonjour
j’ai ésaiyé votre programme il marche pas la compilation ne s’affectuer même pas sa m’affiche des fautes
je sais pas quoi faire il me reste 2semaines pour réussir a faire marché ma plaque et la je lé toujours pas fais
svp aidez mois