- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
j'essai depuis plusieurs mois de compiler une programme avec MPLAB X IDE 4.15 et XC8 1.45. Voici les message d’erreurs:
fuses.h:1: error: (0) Cannot use literal values (0x3FFF) with __CONFIG(), use __PROG_CONFIG() instead
(908) status = 1
nbproject/Makefile-default.mk:138: recipe for target 'build/default/production/main.p1' failed
make[2]: *** [build/default/production/main.p1] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory 'K:/E85_16F627/e85.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'K:/E85_16F627/e85.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 2s)
Le code est en plusieurs fichier et n'est pas de moi, j'aimerais pouvoir le compiler pour après le modifier pour qu'il tourne avec une roue codeuse BCD sur un PIC 16F876 .
Je suis débutant en programmation sur PIC, j'ai dèja programmé sur Arduino.
1 main
2 timer.c
3 timer.h
4 ihm.c
5 ihm.h
6 eeprom.c
7 eeprom.h
8 button.c
9 button.h
10 def.h
11 fuses.h
12 main.h
13 Makefile
Code : Tout sélectionner
//
// Avertissement :
//
// - Ce programme n'est pas garanti
// - Si vous utilisez ce programme dans votre véhicule, vous le faites
// à vos risques et périls. Je ne pourrai être tenu pour responsable
// s'il vous arrivait quelque chose (à vous, à un tier, a votre véhicule, etc...)
// - Je vous autorise à exploiter ce programme uniquement dans un but personnel
// et non commercial. Pour une utilisation commerciale, veuillez me contacter
// par l'interface de mon site : http://chaenel.free.fr/cmsimple/?&mailform
//
#include <htc.h>
#include "def.h"
#include "timer.h"
#include "fuses.h"
#include "ihm.h"
#include "button.h"
#include <xc.h>
void lowInit ( void )
{
// Pas de comparateur
CMCON = 0x07;
// Init du port A,
PORTA = 0;
TRISA = 0xFF; // Entrées commandes d'injecteur de RA0 à RA5
// Init du port B
PORTB = 0;
TRISB = BIT6; // Tout en sortie (sortie led et injecteurs) sauf RB6 (entrée bouton poussoir)
}
void main ( void )
{
lowInit();
_ihmInit(); // Init interface homme/machine
_buttonInit(); // Init de la gestion du bouton poussoir
_timerInit(); // Init des interruptions timer et gestion injecteurs
// Tache de fond, aucun processus bloquant (multitache collaboratif)
while( 1 )
{
_ihmRun();
_timerRun();
}
}
Code : Tout sélectionner
#include <htc.h>
#include "def.h"
#include "ihm.h"
#include "button.h"
#include "ihm.h"
//
// Gestion des interruptions timer
// La fonction de gestion des interruptions se trouve ici car on n'utilise
// que l'interruption timer dans ce projet
//
// La gestion des injecteurs se fait directement dans la fonction de gestion
// d'interruption pour perdre le moins de temps possible.
// Car il ne faut en aucun cas pas que cette fonction ne dure plus de 25us.
//
//
// Chronometres pour la mesure des impulsions injecteur venant du calculateur
static WORD chrono0 = 0;
static WORD chrono1 = 0;
static WORD chrono2 = 0;
static WORD chrono3 = 0;
static WORD chrono4 = 0;
static WORD chrono5 = 0;
// Variables pour le calcul de la richesse supplémentaire
static BYTE increment = 0;
static BYTE decrement = 0;
// Variables pour la base de temps 1ms
static BYTE counter1ms = 40;
static BYTE elapsed1ms = 0;
// Définition des constantes increment/decrement correspondantes au pourcentage d'injection
// supplémentaire choisi
typedef struct
{
BYTE increment;
BYTE decrement;
} InjectionParameters;
static const InjectionParameters injectionParameters[11] =
{
{ 0,100 }, // 0/100= 0% de carburant supplémentaire
{ 1, 20 }, // 1/20 = 5% de carburant supplémentaire
{ 1, 10 }, // 1/10 = 10% de carburant supplémentaire
{ 3, 20 }, // 3/20 = 15% de carburant supplémentaire
{ 1, 5 }, // 1/5 = 20% de carburant supplémentaire
{ 1, 4 }, // 1/4 = 25% de carburant supplémentaire
{ 3, 10 }, // 3/10 = 30% de carburant supplémentaire
{ 7, 20 }, // 7/20 = 35% de carburant supplémentaire
{ 4, 10 }, // 4/10 = 40% de carburant supplémentaire
{ 9, 20 }, // 9/20 = 45% de carburant supplémentaire
{ 1, 2 }, // 1/2 = 50% de carburant supplémentaire
};
static void setInjectionParameters ( void )
{
BYTE injectionValue;
// On recupere la valeur supplémentaire d'injection désirée
injectionValue = _ihmInjectionValueGet();
// On limite à 50% par sécurité pour ne pas deborder du tableau de constantes
if ( injectionValue > 10 )
{injectionValue = 10;}
// On regle les variables increment et decrement
increment = injectionParameters[injectionValue].increment;
decrement = injectionParameters[injectionValue].decrement;
}
void interrupt timerInterrupt25us ( void )
{
// Prochaine IT dans 25us (le +11 c'est pour rattraper le temps perdu
// pour venir dans la fonction (sauvegarde des registres, etc...)
TMR0 = -125 + 11;
// Injecteur 1
if (RB0 == 0 )
{ chrono0 += increment; RB0 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono0>>8) || ((BYTE)(chrono0)>=decrement) )
{ chrono0 -= decrement; RB0 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono0 = 0; RB0 = 0;} // 13 cycles : 2.6us
}
// Injecteur 2
if ( RB1 == 0 )
{ chrono1 += increment; RB1 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono1>>8) || ((BYTE)(chrono1)>=decrement) )
{ chrono1 -= decrement; RB1 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono1 = 0; RB1 = 0;} // 13 cycles : 2.6us
}
// Injecteur 3
if ( RB2 == 0 )
{ chrono2 += increment; RB2 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono2>>8) || ((BYTE)(chrono2)>=decrement) )
{ chrono2 -= decrement; RB2 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono2 = 0; RB2 = 0;} // 13 cycles : 2.6us
}
// Injecteur 4
if ( RB3 == 0 )
{ chrono3 += increment; RB3 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono3>>8) || ((BYTE)(chrono3)>=decrement) )
{ chrono3 -= decrement; RB3 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono3 = 0; RB3 = 0;} // 13 cycles : 2.6us
}
// Injecteur 5
if ( RB4 == 0 )
{ chrono4 += increment; RB4 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono4>>8) || ((BYTE)(chrono4)>=decrement) )
{ chrono4 -= decrement; RB4 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono4 = 0; RB4 = 0;} // 13 cycles : 2.6us
}
// Injecteur 6
if ( RB5 == 0 )
{ chrono5 += increment; RB5 = 1; } // 8 cycles : 1.6us
else
{ if ( (BYTE)(chrono5>>8) || ((BYTE)(chrono5)>=decrement) )
{ chrono5 -= decrement; RB5 = 1;} // 13 / 14 cycles : 2.6us / 2.8us
else
{ chrono5 = 0; RB5 = 0;} // 13 cycles : 2.6us
}
//
// Gestionnaire d'interruption (on ne gere que l'interruption du timer 0)
//
// Prochaine IT dans 25us (le +11 c'est pour rattraper le temps perdu
// pour venir dans la fonction (sauvegarde des registres, etc...)
TMR0 = -125 + 11;
// Gestion de la temporisation de 1ms
if ( --counter1ms == 0 )
{ counter1ms = 40;
elapsed1ms++;
}
// On efface le flag d'interruption timer 0
T0IF = 0;
// Pour debug : chronometrage du temps d'execution du gestionnaire d'IT
// PORTB &= ~BIT7;
}
void _timerRun ( void )
{
// On regle les parametres d'injection
setInjectionParameters();
// Si 1ms s'est ecoulée on appelle les gestionnaires
if ( elapsed1ms != 0 )
return;
elapsed1ms--;
_ihm1msInt();
_button1msInt();
}
void _timerInit ( void )
{
// On initialise les variables locales pour la gestion de l'injection
setInjectionParameters();
// On initialise le timer et on lance les interruptions
INTCON = 0b00100000;
OPTION_REG = 0b10001000; //Prescaler du timer 1:4 soit 5MHz avec Quartz 20MHz
GIE = 1;
}
Code : Tout sélectionner
extern void _timerInit ( void );
extern void _timerRun ( void );
Code : Tout sélectionner
#include <htc.h>
#include "def.h"
#include "button.h"
#include "eeprom.h"
//
// Gestion de l'interface homme/machine : gestion de la led, et de la configuration
// de la carburation
//
// Mode actuel de carburation : SP95 ou E85
static BYTE mode;
// Valeur de l'injection supplémentaire du mode E85, par pas de 5%
static BYTE injectionValue;
// Nouvelle valeur d'injection supplémentaire entrée par l'utilisateur, par pas de 5%
static BYTE injectionValueNew;
// Cycle et temporisation pour la gestion du mode de carburation
static WORD modeTmp;
static BYTE modeCyc;
// Au bout d'un certain temps après le demarrage on n'est plus autorisé
// à changer de mode ou changer l'enrichissement
static WORD startupTmp;
// Temporisation pour le starter automatique
static WORD starterTmp;
// Variables pour la gestion de l'affichage du mode en cours
static WORD ledTmp;
static BYTE ledCyc;
static BYTE ledFlashNumber;
// Définitions locales
enum {
MODE_SP95,
MODE_E85
};
#define LED RB7
BYTE _ihmInjectionValueGet ( void )
{
// Retourne le pourcentage d'injection supplémentaire désiré par l'utilisateur
// En mode SP95, pas d'enrichissement
if ( mode == MODE_SP95 )
return 0;
// Dans les 10 premieres secondes après le démrrage de la carte, on
// enrichit à 50% pour faciliter le demarrage du moteur
if ( starterTmp )
return 10;
// Par sécurité, on limite à 50% d'enrichissement maximum
if ( injectionValue > 10 )
injectionValue = 10;
return injectionValue;
}
void _ihmRun ( void )
{
// Procedure qui permet de changer de mode (SP95/E85) et d'entrer le taux d'enrichissement
// en comptabilisant les impulsions du bouton poussoir (lorsqu'on est en mode E85).
// Attention ne fonctionne que si la tempo de startup n'est pas encore ecoulée !
switch( modeCyc )
{ case 0 : // Si la tempo de demarrage est ecoulée, on ne fait rien
if ( startupTmp == 0 )
break;
// On initialise la nouvelle valeur d'enrichissement à 0
injectionValueNew = 0;
// Si le BP n'est pas pressé, on continue le cycle
if ( !_buttonPressed() )
modeCyc++;
break;
case 1 : // On attend un appui sur le BP
if ( _buttonPressed() )
{ modeTmp = 3000; // Permet de detecter un appui long > 3s
modeCyc++;
}
// Si la tempo de démarrage est ecoulée, le cycle est terminé
if ( startupTmp == 0 )
modeCyc = 0;
break;
case 2 : // On attend le relachement de la touche
if ( ! _buttonPressed() )
{ // La touche a été relachée
// Si on n'est pas en mode E85 on ne fait rien, on repart à 0,
// on n'a pas le droit de changer l'enrichissement
if ( mode != MODE_E85 )
{ modeCyc = 0;
break;
}
// Sinon on comptabilise l'appui
injectionValueNew++;
// L'utilisateur a 1s pour faire un autre appui
modeTmp = 1000;
modeCyc++;
}
// Si la touche n'est pas relachée au bout de 3s, on bascule de mode,
// on reinitialise l'affichage, la tempo de startup (pour relancer 10s),
// et on repart en 0
if ( modeTmp == 0 )
{ if ( mode == MODE_E85 )
mode = MODE_SP95;
else
mode = MODE_E85;
_eepromWriteByte( 0, mode );
ledCyc = 0;
startupTmp = 10000;
modeCyc = 0;
}
break;
case 3 : // Si les 1s sont ecoulés, la saisie de l'enrichissement est finie,
// on sauvegarde la nouvelle valeur (limitée à 50%), on reinitialise l'affichage, la tempo
// de startup (pour relancer 10s), et on repart en 0
if ( modeTmp == 0 )
{ injectionValue = injectionValueNew;
if ( injectionValue > 10 ) injectionValue = 10;
_eepromWriteByte( 1, injectionValue );
ledCyc = 0;
startupTmp = 10000;
modeCyc = 0;
break;
}
// Si l'utilisateur a pressé la touche avant la fin de la tempo, on continue a compter
// les impulsions
if ( _buttonPressed() )
modeCyc = 1;
break;
default : // Y'a un bin's !!
modeCyc = 0;
break;
}
// Gestion de l'affichage du mode en cours
switch( ledCyc )
{ case 0 :
if ( mode == MODE_SP95 )
{ // Si en mode SP95, la led est ON en permanence
LED = 1;
}
else
{ // Sinon on est en mode E85, on affiche le taux d'enrichissement
ledCyc = 10;
}
break;
case 10:
// Affichage du taux d'enrichissement E85
ledTmp = 2000; // On commence par une pause de 2s (2000ms) avec la led eteinte
LED = 0;
ledCyc++;
break;
case 11:
if ( ledTmp )
break;
// Pause finie, on flashe la led
ledFlashNumber = injectionValue;
ledCyc++;
break;
case 12:
if ( ledFlashNumber == 0 )
{ // Si plus de flash à faire on a fini
ledCyc = 0;
break;
}
// Sinon on allume la led pour 200ms
ledTmp = 200;
LED = 1;
ledCyc++;
break;
case 13:
if ( ledTmp )
break;
// Pause finie, on coupe la led pour 200ms
ledTmp = 200;
LED = 0;
ledCyc++;
break;
case 14:
if ( ledTmp )
break;
// Pause finie, on decremente le compteur de flash et on repart en 12
ledFlashNumber--;
ledCyc = 12;
break;
default : // Y'a un bin's !!
ledCyc = 0;
break;
}}
void _ihmInit ( void )
{
mode = _eepromReadByte(0); // Récupération du mode de fonctionnement
injectionValue = _eepromReadByte(1); // Récupération du pourcentage d'injection supplémentaire
// On vérifie si les valeurs sont valides
if ( (mode!=MODE_SP95) && (mode!=MODE_E85) )
{ mode = MODE_E85; // Par défaut mode E85, pour etre sur de ne pas rouler pauvre
injectionValue = 6; // 6 x 5% = 30% de carburant en plus
_eepromWriteByte( 0, mode );
_eepromWriteByte( 1, injectionValue );
}
ledCyc = 0;
modeCyc = 0;
startupTmp = 10000; // On a le droit de changer de mode et/ou d'enrichissement pendant 10s
// après la mise du contact
starterTmp = 10000; // 10 secondes de starter à 50% d'enrichissement pour pouvoir démarrer facilement
}
void _ihm1msInt ( void )
{
// Appelé toute les 1ms
if ( modeTmp ) modeTmp--;
if ( ledTmp ) ledTmp--;
if ( startupTmp ) startupTmp--;
if ( starterTmp ) starterTmp--;
}
Code : Tout sélectionner
extern BYTE _ihmInjectionValueGet ( void );
extern void _ihmRun ( void );
extern void _ihmInit ( void );
extern void _ihm1msInt ( void );
Code : Tout sélectionner
#include <htc.h>
#include "def.h"
//
// Gestion de la sauvegarde dans l'eeprom interne du PIC
//
BYTE _eepromReadByte ( BYTE addr )
{
// On recupere un octet en eeprom
EEADR = addr;
RD = 1;
return( EEDATA );
}
void _eepromWriteByte ( BYTE addr, BYTE data )
{
// On écrit un octet en eeprom
EEADR = addr;
EEDATA = data;
EEIF = 0; // flag de fin d'ecriture à 0
WREN = 1; // Autorise l'ecriture en eeprom
GIE = 0; // On desactive les interruptions
EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
GIE = 1; // Reactive les interruptions
while( !EEIF ); // On attend la fin de l'ecriture
WREN = 0; // Interdit l'ecriture en eeprom
}
Code : Tout sélectionner
extern BYTE _eepromReadByte ( BYTE addr );
extern void _eepromWriteByte ( BYTE addr, BYTE data );
Code : Tout sélectionner
#include <htc.h>
#include "def.h"
//
// Gestion du bouton poussoir de configuration, anti rebond soft
//
#define BUTTON_INPUT RB6
#define DEBOUNCE_TMP 40 // 40ms de tempo d'antirebond
static BYTE button; // Etat filtré du bouton
static BYTE buttonDebounceTmp;
BYTE _buttonPressed ( void )
{
return button;
}
Code : Tout sélectionner
extern BYTE _buttonPressed ( void );
extern void _buttonInit ( void );
extern void _button1msInt ( void );
Code : Tout sélectionner
#define PTR char *
#define BYTE unsigned char
#define WORD unsigned short
#define ULONG unsigned long
#define TRUE 1
#define FALSE 0
#ifndef NULL
#define NULL (void *)0
#endif
/* BIT definition */
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x100
#define BIT9 0x200
#define BIT10 0x400
#define BIT11 0x800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define NBIT0 0xFE
#define NBIT1 0xFD
#define NBIT2 0xFB
#define NBIT3 0xF7
#define NBIT4 0xEF
#define NBIT5 0xDF
#define NBIT6 0xBF
#define NBIT7 0x7F
#define NBIT8 0xFEFF
#define NBIT9 0xFDFF
#define NBIT10 0xFBFF
#define NBIT11 0xF7FF
#define NBIT12 0xEFFF
#define NBIT13 0xDFFF
#define NBIT14 0xBFFF
#define NBIT15 0x7FFF
Code : Tout sélectionner
__CONFIG( 0x3FFF &
// Protection of flash memory
//PROTECT &
UNPROTECT &
// Protection of EEPROM data memory
//CPD &
UNPROTECT &
// Low voltage programming enable
//LVPEN &
LVPDIS &
// Brown out detection enable
//BOREN &
BORDIS &
// Master clear reset pin function
//MCLREN &
MCLRDIS &
// Power up timer enable
PWRTEN &
//PWRTDIS &
// Watchdog timer enable
//WDTEN &
WDTDIS &
// Oscillator configurations
//RCCLK
//RCIO
//INTCLK
//INTIO
//EC
HS
//XT
//LP
);
Code : Tout sélectionner
#include <16F627A.h>
#device ICD=TRUE
#use delay(crystal=20000000)
Code : Tout sélectionner
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
RANLIB=ranlib
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
# WARNING: the IDE does not call this target since it takes a long time to
# simply run make. Instead, the IDE removes the configuration directories
# under build and dist directly without calling make.
# This target is left here so people can do a clean when running a clean
# outside the IDE.
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk
Merci de votre aide.
Cordialement.
Marcus.
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
je ne pratique pas MPLABX mais MikroC ..
mais
n'est ce pas un peu trop plein de vide, cette fonction ?
Code : Tout sélectionner
BYTE _buttonPressed ( void )
{
return button;
}
pas d'argument passé, retourne n'import quoi ?
essaie d'abord de faire tourner des morceaux de ton programme , pour voir où cela coince
DIVISER POUR MIEUX REGNER
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Tu dis débuter en programmation sur PIC, et clairement ce programme est plus complexe . Je ne programme pas sur MPLAB mais sur MikroC moi aussi .
Tu devrais mettre tout ton programme zippé sur le forum. Une âme charitable va peut être essayer ! %Mais franchement c'est une usine a gaz surtout avec plusieurs fichiers.
Les PIC c'est pas de l’Arduino, des copier coller ne suffisent pas !
En tout cas bon courage
je poste le ZIP et le schéma pour ceux qui voudrait rouler avec du E85, Je roule depuis 5 ans avec ce montage sur un V6, récemment j'ai eu des plantages du PIC c'est pour cette raison que j'aimerais le modifier, avant il faudrais que j'arrive a compiler l'original.
Cordiaelment.
Marcus
Cela dépends du 16F utilisé, mais pour ton Pic16F627 il y a pas d'interruption prioritaire, l'interruption à lieu à H'04'.
Je pratique que ASM, mais, J'ai regardé le code, et le schéma, je vois qu'on joue sur l'ouverture et fermeture de l'injecteur, avec des temps.
Pas très compliqué à écrire, le plus dur c'est de comprendre comment fonctionne le système, car on ne peut pas écrire un programme
si on ne comprends pas le mécanisme.
Après avec de bonne explication, il y aura peut être un volontaire, mais peut être pas en C++
A+
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 94 invités