405 lines
22 KiB
C++
Executable File
405 lines
22 KiB
C++
Executable File
//Aepl-Duino Allumage electronique programmable - Arduino Nano et compatibles
|
|
char ver[] = "Version du 3_5_2016";//Choix entre 3 types de Dwell.
|
|
//En option, connexion d'un potard de 100kohm enter la patte A0 et la masse
|
|
//pour decaler "au vol" la courbe de quelques degrés, voir delAv plus bas
|
|
//T>14ms, correction Christophe.Avance 0°jusqu'a 500t/mn, anti retour de kick
|
|
//Detection et traitement special au demarrage (première etincelle)
|
|
//Multi courbes , 2 courbes supplementaires, b et c, selectionables par D8 ou D
|
|
//La Led L sur tout Arduino suit le courant dans la bobine
|
|
|
|
#include "TimerOne.h" //Génère une interruption toutes les trech ou Dsecu µs
|
|
//#include <LiquidCrystal.h>
|
|
//LiquidCrystal lcd(10, 11, 12, 14, 15, 16);
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// COURBES D'ALLUMAGE ET PARAMETRES
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// A renseigner obligatoirement : Na[],Anga[], Ncyl, AngleCapteur, CaptOn, Dwell
|
|
//Les tableau Na[] et Anga[] doivent obligatoirement débuter puis se terminer par 0 et contenir des valeurs entières >=1
|
|
//Le nombre de points est libre. L'avance est imposée à 0° entre 0 et Nplancher t/mn
|
|
//Le dernier N fixe la ligne rouge, c'est à dire la coupure de l'allumage.
|
|
//Anga [] degrés d'avance vilebrequin correspondant ( peut croitre ou decroitre)
|
|
|
|
int Na[] = {0, 500, 700, 800, 1200, 3000, 5000, 0};
|
|
int Anga[] = {0, 10 , 10, 10, 10, 30, 30, 0};
|
|
int Ncyl = 2; //Nb de cylindres, moteur 4 temps. Multiplier par 2 pour moteur 2 temps
|
|
const int AngleCapteur = 45; //le capteur(Hall ou autre ) est a 45° avant le PMH habituellement
|
|
const int CaptOn = 0; //1 déclenchement sur front montant (par ex. capteur Hall "saturé")
|
|
//0 déclenchement sur front descendant (par ex. capteur Hall "non saturé").
|
|
const int Dwell = 3; //1 pour alimenter la bobine en permanencetre sauf 1ms/cycle.Elle doit pouvoir chauffer sans crainte
|
|
//2 pour alimenter la bobine seulement trech ms par cycle, 3ms par exemple
|
|
//3 pour simuler un allumage à vis platinées: bobine alimentée x% du tps
|
|
|
|
//A la place de la courbe a, on peut selectionner la courbe b (D8 à la masse)ou la c (D9 à la masse)
|
|
//Courbe b
|
|
int Nb[] = {0, 500, 1200, 3000, 6000, 0}; //Connecter D8 à la masse
|
|
int Angb[] = {0, 10 , 10, 30, 30, 0};
|
|
//Courbe c
|
|
int Nc[] = {0, 9900, 0}; //Connecter D9 à la masse
|
|
int Angc[] = {0, 10, 0};
|
|
|
|
const int Nplancher = 450; // vitesse en t/mn jusqu'a laquelle l'avance = 0°
|
|
const int trech = 5300; //temps de recharge bobine, 3ms= 3000µs typique, 7ms certaines motos
|
|
const int unsigned long Dsecu = 600000; //Securite: bobine coupee à l'arret apres Dsecu µs
|
|
int delAv = -3; //delta avance,par ex 2°. Quand Pot avance d'une position, l'avance croit de delAv
|
|
//Uniquement si l'on veut jouer à translater les courbes d'avance en connectant un potard
|
|
//Ceci est une option. Avec un potard de 100kohms entre A0 et la masse, de 0-1V environ, courbe originale
|
|
//de 1 a 2V environ avance augmentée de delAv, au dela de 2V, augmentée de 2*delAv
|
|
//Attention.....Pas de pleine charge avec trop d'avance, danger pour les pistons..
|
|
const int tflash = 150; // Durée flash en µsec
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// CONSTANTES - PINS
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
const int Bob = 3; //Sortie D4 vers bobine.
|
|
const int Cible = 2; //Entrée sur D2 du capteur, R PullUp
|
|
const int Pot = A3; //Entrée analogique sur A0 pour potard de changement de courbes. R PullUp
|
|
const int Led13 = 13; //Temoin sur tout Arduino, suit le courant de bobine
|
|
const int Courbe_b = 8; //Entrée D8 R PullUp. Connecter à la masse pour courbe b
|
|
const int Courbe_c = 9; //Entrée D9 R PullUp. Connecter à la masse pour courbe c
|
|
const int Flash = 10;
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// VARIABLES
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Ici 3 positions:Decalage 0° si <1V, delAV° si 1 à 2 V, 2*delAv° pour > 2V
|
|
int valPot = 0; //0 à 1023 selon la position du potentiomètre en entree
|
|
float modC1 = 0; //Correctif pour C1[], deplace la courbe si potard connecté
|
|
int unsigned long D = 0; //Delai en µs à attendre après la cible pour l'étincelle
|
|
int milli_delay = 0;
|
|
int micro_delay = 0;
|
|
float RDzero = 0; //pour calcul delai avance 0° < Nplancher t/mn
|
|
float Tplancher = 0; //idem//idem
|
|
const int tcor = 140; //correction en µs du temps de calcul pour D
|
|
int unsigned long Davant_rech = 0; //Delai en µs avant la recharge de la bobine.
|
|
int unsigned long prec_H = 0; //Heure du front precedent en µs
|
|
int unsigned long T = 0; //Periode en cours
|
|
int unsigned long Tprec = 0; //Periode precedant la T en cours, pour calcul de Drech
|
|
int N1 = 0; //Couple N,Ang de debut d'un segment
|
|
int Ang1 = 0; //Angle d'avance vilo en degrès
|
|
int N2 = 0; //Couple N,Ang de fin de segment
|
|
int Ang2 = 0;
|
|
int* pN = &Na[0]; //pointeur au tableau des régimes. Na sera la courbe par defaut
|
|
int* pA = &Anga[0]; //pointeur au tableau des avances. Anga sera la courbe par defaut
|
|
float k = 0; //Constante pour calcul de C1 et C2
|
|
float C1[20]; //Tableaux des constantes de calcul de l'avance courante
|
|
float C2[20]; //Tableaux des constantes de calcul de l'avance courante
|
|
float Tc[20]; //Tableau des Ti correspondants au Ni
|
|
//Si necessaire, augmenter ces 3 valeurs:Ex C1[30],C2[30],Tc[30]
|
|
float Tdebug[10];
|
|
int Tlim = 0; //Période minimale, limite, pour la ligne rouge
|
|
int j_lim = 0; //index maxi des N , donc aussi Ang
|
|
int unsigned long NT = 0; //Facteur de conversion entre N et T à Ncyl donné
|
|
int AngleCibles = 0; //Angle entre 2 cibles, 180° pour 4 cyl, 120° pour 6 cyl, par exemple
|
|
int UneEtin = 1; //=1 pour chaque étincelle, testé et remis à zero par isr_GestionIbob()
|
|
int Ndem = 180; //Vitesse estimée du vilo entrainé par le demarreur en t/mn
|
|
int unsigned long Tdem = 0; //Periode correspondante à Ndem,forcée pour le premier tour
|
|
int Mot_OFF = 0; //Sera 1 si moteur detecté arrété par l'isr_GestionIbob()
|
|
//Permet d'icentifier le premier front et forcer T=Tdem, ainsi que Ibob=1, pour demarrer au premier front
|
|
// initialize the library with the numbers of the interface pins
|
|
unsigned long pm = 0;
|
|
boolean flag_lcd = true;
|
|
int i_debug = 0;
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// DEBUG
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
//Macro ps(v) de debug pour imprimer le numero de ligne, le nom d'une variable, sa valeur puis s'arreter definitivement
|
|
#define ps(v) Serial.print("L<igne_") ; Serial.print(__LINE__) ; Serial.print(#v) ; Serial.print(" = ") ;Serial.println((v)) ; Serial.println(" Sketch stop"); while (1);
|
|
//Exemple, à la ligne 140, l'instruction ps(var1);
|
|
//inprimera "Ligne_140var1 = 18 Sketch stop"
|
|
//Macro pc(v)de debug pour imprimer le numero de ligne, le nom d'une variable, sa valeur, puis s'arreter et
|
|
//attendre un clic de souris sur le bouton 'Envoyer'en haut de l'ecran seriel pour continuer.
|
|
#define pc(v) Serial.print("Ligne_") ; Serial.print(__LINE__) ; Serial.print(#v) ;Serial.print(" = ") ; Serial.println((v)) ; Serial.println(" Clic bouton 'Envoyer' pour continuer") ;while (Serial.available()==0);{ int k_ = Serial.parseInt() ;}
|
|
//Exemple, à la ligne 145, l'instruction pc(var2);
|
|
//imprimera "Ligne_145var2 = 25.3 Clic bouton 'Envoyer' pour continuer"
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// CALCUL
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void CalcD ()
|
|
{ // Noter que T1>T2>T3...
|
|
for (int j = 1; j <= j_lim; j++) //On commence par T la plus longue et on remonte
|
|
{
|
|
if (T >= Tc[j])
|
|
{ //on a trouvé le bon segment de la courbe d'avance
|
|
D = float(T * ( C1[j] - modC1 ) + C2[j]); //D en µs, C2 incorpore le temps de calcul tcor
|
|
if ( T > Tplancher)D = T * RDzero; //Imposer 0° d'avance de 0 à 500t/mn
|
|
break; //Sortir, on a D
|
|
}
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// ETINCELLE
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void Etincelle ()
|
|
{
|
|
D = D - tflash;
|
|
if (D < 14000)
|
|
{ // Currently, the largest value that will produce an accurate delay is 16383 µs
|
|
delayMicroseconds(D); //Attendre D
|
|
}
|
|
else
|
|
{
|
|
milli_delay = ((D / 1000) - 2); //Pour ces D longs, delayMicroseconds(D)ne va plus.
|
|
micro_delay = (D - (milli_delay * 1000));
|
|
delay(milli_delay);
|
|
delayMicroseconds(micro_delay);
|
|
}
|
|
digitalWrite (Flash, 1); // Flash de calage
|
|
delayMicroseconds(tflash);
|
|
digitalWrite (Flash, 0);
|
|
digitalWrite(Bob, 0); //Couper le courant, donc étincelle
|
|
digitalWrite(Led13, 0); //Temoin
|
|
//Maintenant que l'étincelle est émise, il faut rétablir Ibob au bon moment
|
|
|
|
switch (Dwell) //Attente courant coupé selon le type de Dwell
|
|
{
|
|
case 1: //Ibob coupe 1ms par cycle seulement, la bobine doit supporter de chauffer
|
|
Davant_rech = 1000; //1ms off par cycle
|
|
break;
|
|
case 2: //Type bobine faible resistance, dite "electronique"
|
|
Davant_rech = 2 * T - Tprec - trech; //On doit enir compte des variations de régime moteur
|
|
Tprec = T; //Maj de la future periode precedente
|
|
break;
|
|
case 3: //Type "vis platinées", Off 1/3, On 2/3
|
|
Davant_rech = T / 2;
|
|
break;
|
|
}
|
|
Timer1.initialize(Davant_rech); //Attendre Drech µs avant de retablire le courant dans la bobine
|
|
Tst_Pot(); //Voir si un potard connecté pour deplacer la courbe ou selectionner une autre courbe
|
|
UneEtin = 1; //Pour signaler que le moteur tourne à l'isr_GestionIbob().
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// INIT
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void Init ()
|
|
//Calcul de 3 tableaux,C1,C2 et Tc qui serviront à calculer D, temps d'attente
|
|
//entre la detection d'une cible par le capteur et la generation de l'etincelle.
|
|
//Le couple C1,C2 est determiné par la periode T entre deux cibles, correspondant au
|
|
//bon segment de la courbe d'avance entrée par l'utilisateur: T est comparée à Tc
|
|
{
|
|
AngleCibles = 720 / Ncyl; //Ex pour 4 cylindres 180°, et 120° pour 6 cylindres
|
|
NT = 120000000 / Ncyl; //Facteur de conversion Nt/mn en Tµs
|
|
//T temps entre 2 étincelle soit 720° mono cylindre 4temps.360°=60/Ns 1°=1/6N
|
|
//720° = 720/6N=120/N Pour un moteur à Ncyl, T=120/Ncyl.N en secondes
|
|
Tdem = NT / Ndem; //Periode imposée à la première étincelle qui n'a pas de valeur prec_H
|
|
Tplancher = 120000000 / Nplancher / Ncyl; //T à vitesse plancher en t/mn: en dessous, avance centrifuge = 0
|
|
RDzero = float(AngleCapteur) / float(AngleCibles);
|
|
Select_Courbe(); //Ajuster éventuellement les pointeurs pN et pA pour la courbe b ou c
|
|
N1 = 0; Ang1 = 0; //Toute courbe part de 0
|
|
int i = 0; //locale mais valable hors du FOR
|
|
pN++; pA++; //sauter le premier element de tableau, toujours =0
|
|
for (i = 1; *pN != 0; i++) //i pour les C1,C2 et Tc.Arret quand regime=0.
|
|
{
|
|
//pN est une adresse (pointeur) qui pointe au tableau N.Le contenu pointé est *pN
|
|
N2 = *pN; Ang2 = *pA; //recopier les valeurs pointées dans N2 et Ang2
|
|
k = float(Ang2 - Ang1) / float(N2 - N1); //pente du segment (1,2)
|
|
C1[i] = float(AngleCapteur - Ang1 + k * N1) / float(AngleCibles);
|
|
C2[i] = - float(NT * k) / float(AngleCibles) - tcor; //Compense la durée de calcul de D
|
|
Tc[i] = float(NT / N2);
|
|
N1 = N2; Ang1 = Ang2; //fin de ce segment, début du suivant
|
|
pN++; pA++; //Pointer à l'element suivant de chaque tableau
|
|
}
|
|
j_lim = i - 1; //Revenir au dernier couple entré
|
|
Tlim = Tc[j_lim]; //Ligne rouge
|
|
|
|
Serial.print("Ligne_"); Serial.println(__LINE__);
|
|
Serial.print("Tc = "); for (i = 1 ; i < 15; i++)Serial.println(Tc[i]);
|
|
Serial.print("Tlim = "); Serial.println(Tlim);
|
|
//Serial.print("C1 = "); for (i = 1 ; i < 15; i++)Serial.println(C1[i]);
|
|
//Serial.print("C2 = "); for (i = 1 ; i < 15; i++)Serial.println(C2[i]);
|
|
|
|
//Timer1 a deux roles:
|
|
//1)couper le courant dans la bobine en l'absence d'etincelle pendant plus de Dsecu µs
|
|
//2)après une étincelle, attendre le delais Drech avant de retablir le courant dans la bobine
|
|
//Ce courant n'est retabli que trech ms avant la prochaine étincelle, condition indispensable
|
|
//pour une bobine à faible resistance, disons inférieure à 3 ohms.Typiquement trech = 3ms à 7ms
|
|
Timer1.attachInterrupt(isr_GestionIbob); //IT d'overflow de Timer1 (16 bits)
|
|
Timer1.initialize(Dsecu); //Le courant dans la bobine sera coupé si aucune etincelle durant Dsecu µs
|
|
Mot_OFF = 1; // Signalera à loop() le premier front
|
|
//lcd.setCursor(5,1);
|
|
//lcd.print(Mot_OFF);
|
|
|
|
digitalWrite(Bob, 0); //par principe, couper la bobine
|
|
digitalWrite(Led13, 0); //Temoin
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// isr GESTION BOBINE
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void isr_GestionIbob()
|
|
{
|
|
Timer1.stop(); //Arreter le decompte du timer
|
|
if (UneEtin == 1)
|
|
{
|
|
digitalWrite(Bob, 1); //Le moteur tourne,retablire le courant dans bobine
|
|
digitalWrite(Led13, 1); //Temoin
|
|
}
|
|
else
|
|
{
|
|
digitalWrite(Bob, 0);
|
|
digitalWrite(Led13, 0); //Moteur arrete, preserver la bobine, couper le courant
|
|
Mot_OFF = 1; //Permettra à loop() de detecter le premier front de capteur
|
|
//lcd.setCursor(5,1);
|
|
//lcd.print(Mot_OFF);
|
|
}
|
|
UneEtin = 0; //Remet le detecteur d'étincelle à 0
|
|
Timer1.initialize(Dsecu); //Au cas où le moteur s'arrete, couper la bobine apres Dsecu µs
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// SELECTION COURBE
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void Select_Courbe()
|
|
{
|
|
//lcd.setCursor(7,1);
|
|
//lcd.print("A");
|
|
//Par défaut, la courbe a est déja selectionnée
|
|
if (digitalRead(Courbe_b) == 0) //D8 à la masse
|
|
{
|
|
pN = &Nb[0]; // pointer à la courbe b
|
|
pA = &Angb[0];
|
|
//lcd.setCursor(7,1);
|
|
//lcd.print("B");
|
|
}
|
|
if (digitalRead(Courbe_c) == 0) //D9 à la masse
|
|
{
|
|
pN = &Nc[0]; // pointer à la courbe c
|
|
pA = &Angc[0];
|
|
//lcd.setCursor(7,1);
|
|
//lcd.print("C");
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// GESTION POTAR
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void Tst_Pot()
|
|
{
|
|
valPot = analogRead(Pot);
|
|
if (valPot < 240 || valPot > 900) modC1 = 0; //0° ou pas de potard connecté (valpot =1023 en théorie)
|
|
else
|
|
{
|
|
if (valPot < 500) modC1 = float (delAv) / float(AngleCibles); //Position 1
|
|
else modC1 = 2 * float (delAv) / float(AngleCibles); //Position 2
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// SETUP
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void setup()
|
|
{
|
|
Serial.begin(9600); //Ligne suivante, 3 Macros du langage C
|
|
Serial.println(__FILE__); Serial.println(__DATE__); Serial.println(__TIME__);
|
|
Serial.println(ver);
|
|
|
|
if (Ncyl < 2)Ncyl = 2; //On assimile le mono cylindre au bi, avec une étincelle perdue
|
|
|
|
pinMode(Cible, INPUT_PULLUP); //Entrée front du capteur sur D2
|
|
pinMode(Bob, OUTPUT); //Sortie sur D4 controle du courant dans la bobine
|
|
pinMode(Pot, INPUT_PULLUP); //Entrée pour potard 100kohms, optionnel
|
|
pinMode(Courbe_b, INPUT_PULLUP); //Entrée à la masse pour selectionner la courbe b
|
|
pinMode(Courbe_c, INPUT_PULLUP); //Entrée à la masse pour selectionner la courbe c
|
|
pinMode(Led13, OUTPUT); //Led d'origine sur tout Arduino, temoin du courant dans la bobine
|
|
pinMode(Flash, OUTPUT);
|
|
|
|
//lcd.begin(8, 2);
|
|
|
|
Init(); //Executée une fois au demarrage et à chaque changement de courbe
|
|
|
|
//lcd.setCursor(4,0);
|
|
//lcd.print(" tpm");
|
|
|
|
//lcd.setCursor(2,0);
|
|
//lcd.print("max. ");
|
|
//lcd.print(NT/Tlim);
|
|
//lcd.print(" tr/min");
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
// LOOP
|
|
//------------------------------------------------------------------------------------------------------------------------
|
|
void loop()
|
|
{
|
|
while (digitalRead(Cible) == !CaptOn); //Attendre front actif de la cible
|
|
T = micros() - prec_H; //front actif arrivé, calculer T
|
|
prec_H = micros(); //heure du front actuel qui deviendra le front precedent
|
|
|
|
if ( Mot_OFF == 1 )
|
|
{ //Demarrage:premier front de capteur
|
|
T = Tdem; //Fournir T = Tdem car prec_H n'existe par pour la première étincelle
|
|
digitalWrite(Bob, 1); //Alimenter la bobine
|
|
digitalWrite(Led13, 1); //Temoin
|
|
Mot_OFF = 0; //Le moteur tourne
|
|
//lcd.setCursor(5,1);
|
|
//lcd.print(Mot_OFF);
|
|
}
|
|
|
|
if (T > Tlim) //Sous la ligne rouge?
|
|
{
|
|
CalcD(); // Top(); //Oui, generer une etincelle
|
|
Etincelle();
|
|
}
|
|
/*
|
|
if (millis() - pm > 500)
|
|
{
|
|
lcd.setCursor(6,1);
|
|
lcd.print(flag_lcd);
|
|
if (flag_lcd)
|
|
{
|
|
lcd.setCursor(0,0);
|
|
if (NT/T<1000) lcd.print(" ");
|
|
lcd.print(NT/T); //régime mot.
|
|
lcd.print(" ");
|
|
lcd.setCursor(0,1);
|
|
}
|
|
if (!flag_lcd)
|
|
{
|
|
float avance = float(AngleCapteur)-(360.0*float(D)/float(T));
|
|
lcd.setCursor(0,1);
|
|
if (avance<10) lcd.print(" "); //angle avance
|
|
lcd.print(avance,1);
|
|
lcd.print(" ");
|
|
}
|
|
pm=millis();
|
|
flag_lcd=!flag_lcd;
|
|
}
|
|
|
|
if (i_debug < 10){
|
|
Tdebug[i_debug] = T;
|
|
i_debug++;
|
|
} else {
|
|
i_debug = 0;
|
|
Serial.print("T = "); for (int i = 1 ; i < 10; i++)Serial.println(Tdebug[i]);
|
|
}
|
|
*/
|
|
while (digitalRead(Cible) == CaptOn); //Attendre si la cible encore active
|
|
|
|
}
|
|
|
|
|
|
/////////////////Exemples de CAPTEURS/////////////////
|
|
//Capteur Honeywell cylindrique 1GT101DC,contient un aimant sur le coté,type non saturé, sortie haute à vide,
|
|
//et basse avec une cible en acier. Il faut CapteurOn = 0, declenchement sur front descendant.
|
|
//Le capteur à fourche SR 17-J6 contient un aimant en face,type saturé, sortie basse à vide,
|
|
//et haute avec une cible en acier. Il faut CapteurOn = 1, declenchement sur front montant.
|
|
////////////////DEBUGGING////////////////////////
|
|
//Voir les macros pc et ps ci dessus
|
|
//float gf = 0;//pour boucle d'attente,gf GLOBALE et FLOAT indispensable
|
|
// gf = 1; while (gf < 2000)gf++;//10= 100µs,100=1.1ms,2000=21.8ms
|
|
//void Top()////////////////////while (1); delay(1000);/////////////////////////////
|
|
//{ digitalWrite(Bob, 1); //Crée un top sur l'oscillo
|
|
// gf = 1; while (gf < 10)gf++;//gf DOIT être Globale et Float 10=100µs,2000=21.8ms, retard/Cible=50µs
|
|
// digitalWrite(Bob, 0); //
|
|
//}
|
|
//void software_Reset() //jamais testé
|
|
// Redémarre le programme depuis le début mais ne
|
|
// réinitialiser pas les périphériques et les registresivre...
|
|
//{
|
|
// asm volatile (" jmp 0");
|
|
//}
|