ASM fonction sub et logiciel pour programmer en assembleur une UNO?

Bonjour,
je me suis inspiré du code et de la documentation de @J-M-L en asm :
https://forum.arduino.cc/t/asm-fonction-add/1034944/3 et j'ai fait un petit programme qui soustrait deux variables avec quelques commentaires dans le code :

volatile uint8_t value1 asm("v1") __attribute__ ((used)) = 65;
volatile uint8_t value2 asm("v2") __attribute__ ((used)) = 15;


void setup() {
  Serial.begin(115200);
  asm
  (
    "lds r18, v1  \n" // lds : charge un octet de l’espace de données vers un registre
    "lds r19, v2  \n"
    "sub r18, r19 \n" // sub : soustrait deux registres
    "sts v1, r18  \n"// sts : Ecrit le résultat à la même adresse qu’il a été extrait
  );
  Serial.println(value1);
}

void loop() {}

je trouve ça très interessant !
Avec quel logiciel peut-on programmer en assembleur une UNO (hormis l'IDE arduino) ?

Merci par avance.

Avec les outils de ATmel qui doivent être installé avec l'IDE arduino, je crois avr-as.exe.
Il doit être aussi possible avec l'IDE AVR(AVR studio).
Par contre tu devra remettre le bootloader d'Arduino, je pense.

n'importe quel éditeur de texte... il faut ensuite passer de l'assembleur au binaire. le plus simple étant d'utiliser la fonction d'inline assembler de gcc

https://www.nongnu.org/avr-libc/user-manual/inline_asm.html

https://www.nongnu.org/avr-libc/user-manual/assembler.html

mais il y a vraiment peu de raison d'utiliser l'assembleur directement... le compilateur C ou C++ fait relativement bien les choses généralement. Ponctuellement pourquoi pas si on veut gérer le timing à l'instruction près...

Merci @J-M-L

L'interêt pour moi serait de mieux comprendre les mécanismes internes de fonctionnement du microprocesseur ATmega328P. J'en devine les principes mais je n'en connais pas les détails.
Bon faut t'il encore que je sois capable de les comprendre et ce n'est pas certain.
Il faut savoir rester à sa place !
Quand j'en aurai fini avec le C++ j'irai visiter vos liens. A moins que :

soit une bonne solution.

Merci @J-M-L .
Merci @terwal

bien sûr vous pouvez vous y intéresser. c'est formateur de comprendre ce que le compilateur doit faire, mais ne le faites pas sur le coin d'une table, prévoyez quelques semaines/mois de boulot...

Oui et encore si j'en suis capable !
La suggestion de @terwal est intéressante d'après vous ?
Merci.

On peut toujours utiliser leurs outils, oui

Cf AVR Assembler

(Je suis sur Mac donc pas de .exe :wink: )

Merci et merci @terwal

@philippe86220 de rien, c'est toujours intéressant de savoir ce qu'il se passe en bas niveau.
Je ne vois pas pourquoi tu n'aurais pas le niveau, cela peut par exemple bien mettre en pratique les conventions d'appel.
L'assembleur est assez simple finalement, même si ce n'est pas si simple et rapide d'écrire une application :slight_smile:

Merci mais c'est simple d'effectuer une addition ou une soustraction en assembleur. C'est certainement moins évident de mettre en place du code qui par exemple va gérer un gps ! C'est tout simplement au-dessus de mes moyens. :smirk:

non, c'est juste plus laborieux, et il faudra apprendre à gérer le port série, la mémoire etc...

vaut mieux écrire cela en C++ :wink:

C'est vrai @J-M-L, je veux juste apprendre les bases.
Bien connaître l'essentiel concernant le fonctionnement du matériel par le biais de l'assembleur devrait faciliter ma compréhension des langages évolués comme le c++. Voilà je veux juste acquérir les bases.
D'ailleurs je me demande s'il y a des programmeurs qui écrivent des programmes complexes en assembleur ?
En fait je ne pense pas.

Hello Philippe, si cela arrive, lorsque tu as besoin de respecter un timing.
j'en avais fait un pour gérer le temps de prolongation du temps de commande d'ouverture des injecteurs d'un moteur 6 cylindres. (passage au E10 au lieu de l'essence normale.
dans ce cas, il faut aller très vite...
mais l'assembleur est un autre monde. il ne te permettra pas de t'améliorer en programmation en C.
par contre il te forcera à apprendre et comprendre comment le µ est fait et comment il fonctionne.
AVRSTUDIO te permet d'écrire ton prog en assembleur, de le compiler et de le débuger en pas à pas avec visu sur les registres ou zones de mémoire.
je l'ai sur un vieux PC, c'est ce PC qui m'a permit de developper le programme dont je te parle.
j'ai voulu mettre AVRSTUDIO sur un nouveau PC et internet me dirige sur une version payante. ???
si quelqu'un connait une solution à ce prob.......

.include "m328Pdef.inc" 
.list
;PortB pins
.equ Einj_1			=0 ;portB0 pinoche 14 du µ
.equ Einj_2			=1 ;portB1 pinoche 15 du µ
.equ Einj_3			=2 ;portB2 pinoche 16 du µ
.equ Einj_4			=3 ;portB3 pinoche 17 du µ
.equ Einj_5			=4 ;portB4 pinoche 18 du µ
.equ Einj_6			=5 ;portB5 pinoche 19 du µ
;.equ libre         =6 ;portB6 pinoche 09 du µ pas dispo car quartz exterieur
;.equ libre			=7 ;portB7 pinoche 10 du µ pas dispo car quartz exterieur

;PortC pins
.equ codeur_A	    =0 ;portC0 pinoche 23 du µ
.equ codeur_B	    =1 ;portC1 pinoche 24 du µ
.equ codeur_C	    =2 ;portC2 pinoche 25 du µ
.equ codeur_D	    =3 ;portC3 pinoche 26 du µ
.equ led_1S         =4 ;portC4 pinoche 27 du µ led temoin fréquence 1 Seconde
.equ temp_moteur    =5 ;portC5 pinoche 28 du µ
;.equ reset         =6 ;portC6 pinoche  1 du µ  

;PortD pins
;.equ rx			=0 ;portD0 pinoche  2 du µ
;.equ tx			=1 ;portD1 pinoche  3 du µ
.equ Sinj_1			=2 ;portD2 pinoche  4 du µ
.equ Sinj_2			=3 ;portD3 pinoche  5 du µ
.equ Sinj_3			=4 ;portD4 pinoche  6 du µ
.equ Sinj_4			=5 ;portD5 pinoche 11 du µ
.equ Sinj_5			=6 ;portD6 pinoche 12 du µ
.equ Sinj_6			=7 ;portD7 pinoche 13 du µ
;definition des registres
.def precompt	= r15 ;
.def temp1		= r16 ;
.def temp2		= r17 ;
.def temp3		= r18 ;
.def temp4		= r19 ;
.def sub1l		= r20 ;
.def sub1h		= r21 ;
.def sub2l		= r22 ;
.def sub2h		= r23 ;
.def temp_C		= r24 ; pour tempo UART
.def temp_L		= r25 ; pour tempo UART
.def pointeur_correction_L		= r26 ;XL
.def pointeur_correction_H		= r27 ;XH
.def tampon_calcul_injection_L	= r28 ;YL
.def tampon_calcul_injection_H	= r29 ;YH
.def compteur_cycles_L_T_1_2	= r30 ;ZL
.def compteur_cycles_H_T_1_2	= r31 ;ZH
.dseg ;IRAM
.org $100 ;100 début de la SRAM 
micro:					.byte 1 ;variable à renseigner pour regler la cadence du timer 
moteur_H:				.byte 1 ;octet haut contenant la valeur de la sonde moteur après conversion en numérique
moteur_L:				.byte 1 ;octet bas contenant la valeur de la sonde moteur après conversion en numérique
seuil_moteur_H:			.byte 1 ;contient la valeur "seuil" convertie pour 35°
seuil_moteur_L:			.byte 1 ;contiendra donc d630 ou 0x0276
flag_conversion_lambda: .byte 1 ;vaut 1 ou 0, est l'aiguillage vers convertion sonde lambda 
flag_conversion_moteur: .byte 1 ;vaut 1 ou 0, est l'aiguillage vers convertion sonde température moteur
flag_1:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 1
flag_2:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 2
flag_3:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 3
flag_4:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 4
flag_5:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 5
flag_6:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 6
flag_7:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 7
flag_8:					.byte 1 ;témoin de passage dans la routine de calcul ratio temps pour injecteur 8
tempo_inj_1_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 1
tempo_inj_1_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 1
tempo_inj_2_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 2
tempo_inj_2_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 2
tempo_inj_3_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 3
tempo_inj_3_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 3
tempo_inj_4_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 4
tempo_inj_4_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 4
tempo_inj_5_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 5
tempo_inj_5_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 5
tempo_inj_6_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 6
tempo_inj_6_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 6
tempo_inj_7_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 7
tempo_inj_7_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 7
tempo_inj_8_H:			.byte 1 ;octet haut de memorisation du ration d'allongement de la durée d'injection 8
tempo_inj_8_L:			.byte 1 ;octet bas de memorisation du ration d'allongement de la durée d'injection 8
moteur_froid:			.byte 1 ;mémorisation de l'état de l'inverseur type de carburant
derniere_correction:	.byte 1 ;
memo_codeur:	        .byte 1 ;
correction:				.byte 1 ;après lecture en EEprom, mémorisation du % de correction courant
ajout:					.byte 1 ;
memo_ajout:				.byte 1 ;
conv_finie:             .byte 1 ;
minutes:				.byte 1 ;
precompteur_tampon:		.byte 1 ;
precompteur_1:			.byte 1 ;
precompteur_2:			.byte 1 ;
precompteur_3:			.byte 1 ;
precompteur_4:			.byte 1 ;
precompteur_5:			.byte 1 ;
precompteur_6:			.byte 1 ;
precompteur_7:			.byte 1 ;
precompteur_8:			.byte 1 ;
memo_nb_temp_mot:		.byte 1 ;
memo_conversion:		.byte 1 ;
compteur_secondes_Temp: .byte 1 ;
compteur_10_premieres_minutes: .byte 1 ;
.org 0x200 ;0x200 fin zone pointeurs, début zone fichiers 
tableau_corrections:	.byte 50 ;tableau des adresses des scripts préchargés 3E=62
.Cseg
.org 0x00
jmp RESET
.org 0x0002 
;jmp EXT_INT0 ;inter extérieure 0
EXT_INT0:reti
.org 0x0004
;jmp EXT_INT1 ;inter exterieur 1
EXT_INT1:reti
.org 0x0006
;jmp PC_INT0 ;Pin Change d'état
;PC_INT0:reti
.org 0x0008
;jmp PC_INT1 ;Pin Change d'état
PC_INT1:reti
.org 0x000A
;jmp PC_INT2 ;Pin Change d'état
PC_INT2:reti
.org 0x000C 
;jmp WDT ;seuil atteint sur Watchdog 
WDT:reti
.org 0x000E
;jmp TIM2_COMPA ;seuil atteint sur Timer2/comparateurA
TIM2_COMPA:reti
.org 0x00010
;jmp TIM2_COMPB ;seuil atteint sur Timer2/comparateurB
TIM2_COMPB:reti
.org 0x00012
jmp TIM2_OVF ;dépassement du Timer/Counter2 
;TIM2_OVF:reti
.org 0x00014
;jmp TIM1_CAPT ;évenement sur PB0
TIM1_CAPT:reti
.org 0x00016
;jmp TIM1_COMPA ;seuil atteint sur Timer1/comparateurA
TIM1_COMPA:reti
.org 0x00018
;jmp TIM1_COMPB ;seuil atteint sur Timer1/comparateurb 
TIM1_COMPB:reti
.org 0x0001A
;jmp TIM1_OVF ;dépassement du Timer/Counter1
TIM1_OVF:reti
.org 0x0001C
jmp TIM0_COMPA ;seuil atteint sur Timer0/comparateurA
;TIM0_COMPA:reti
.org 0x0001E
;jmp TIM0_COMPB ;seuil atteint sur Timer0/comparateurB
TIM0_COMPB:reti
.org 0x00020
;jmp TIM0_OVF ;dépassement du Timer/Counter0 
TIM0_OVF:reti
.org 0x00022
;jmp SPI_STC ;SPI tampon transfert complet
SPI_STC:reti
.org 0x0024
;jmp USART_RXC ;USART, tampon réception plein
USART_RXC:reti
.org 0x0026 
;jmp USART_TXC ;USART, tampon émission pleinffffff
USART_TXC:reti
.org 0x0028
;jmp USART_UDRE ;UDR est libre d'utilisation
USART_UDRE:reti
.org 0x002A
jmp ADC_COMP ;Conversion terminée
;ADC_COMP:reti
.org 0x002C
;jmp EE_RDY ;EEPROM prete en écriture
EE_RDY:reti
.org 0x002E
;jmp ANA_COMP ;comparaison analogique atteinte
ANA_COMP:reti
.org 0x0030
;jmp TWI ;liaison série 2 fils
TWI:reti
.org 0x0032
;jmp SPM_RDY ;store programm Memory 
SPM_RDY:reti
.org 0X300
RESET:
;à inclure si le micro-controleur utilisé à une RAM interne
init_du_pointeur_de_pile_pointeur_de_pile:
	ldi		temp1	,low(RAMEND)
	out		SPL		,temp1
	ldi		temp1	,high(RAMEND)
	out		SPH		,temp1
;µµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµ
;attention sortie d'usine, les micro 328PU sont programmés 
;avec une division par 8 de la fréquence, il faut voir les fuses
;µµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµ 

init_direction_des_ports:
;config portB (EEEE EEEE) en entrée
		ldi		temp1	,0b00000000		;pb0 a pb5 sont des entrées. pb6 et PB7 sont occupées par le quartz extérieur
		out		DDRB	,temp1			;0=entree 1=sortie
;config portC_pas de bit 0, 1 (EEEE EEEE) en entrée
;ldi temp1,0b100000 ;port C en entrées C0 et C1 sont en analogique C4 led_10S
		ldi		temp1	,0b00010000		;port C en entrées C0 et C1 sont en analogique C4 led_10S
		out		DDRC	,temp1			;0=entree 1=sortie C4 est la led de vie
;config portD (SSSS SSSE) en sortie et 1 entree pour RX
		ldi		temp1	,0b11111110		;pd2 à pd7 sont des sorties
		out		DDRD	,temp1			;0=entree 1=sortie

init_pull_up_des_ports:
;init du portB
	ldi		temp1	,0b00111111
	out		portB	,temp1					;les pull up des entrées du port B sont en service
;init du portC
	ldi		temp1	,0b00000000				;les pull up des entrées du port C ne sont pas en service
	out		portC	,temp1					;des push down seront en hard sur PC0, PC1, PC2, PC3
;init du portD
	ldi		temp1	,0b00000010 
	out		portD	,temp1					;les pull up des entrées du port D ne sont pas en service
	;neutralise les timer 0, 1, 2
	ldi		temp1	,0x00					;
	sts		TIMSK0	,temp1					;
	sts		TIMSK1	,temp1					;
	sts		TIMSK2	,temp1					;
	out		TCCR0B	,temp1					;pas d'horloge sur timer 0
	sts		TCCR1B	,temp1					;pas d'horloge sur timer 1
	sts		TCCR2B	,temp1					;pas d'horloge sur timer 2
	sts		memo_conversion			,temp1	;coefficient correcteur d'injection
	sts		compteur_secondes_Temp	,temp1
	sts		compteur_10_premieres_minutes,temp1
	mov		compteur_cycles_L_T_1_2	,temp1	;compteurL de cycles d'interruptions du timer 0
	mov		compteur_cycles_H_T_1_2	,temp1	;compteurH de cycles d'interruptions du timer 0
	sts     conv_finie,temp1

;Reglage...Reglage...Reglage...Reglage...Reglage...Reglage...Reglage...Reglage...Reglage...Reglage...

initialisations: ;reglage des 32µ secondes ICI
	ldi		temp1	,0x40			;ICI...0x40 donne 1 interruption toutes les 32µ secondes 
	sts		micro	,temp1			;pour faire varier la période de 32µ, c'est ici qu'il faut le faire
	ldi		sub2l	,0x01			;octet bas pour décomptage de 1 période de 32µ de la tempo de maintien
	ldi		sub2h	,0x00			;octet haut pour décomptage de 1 période de 32µ de la tempo de maintien
	rcall	USART_INIT
	;rcall razdetouteleprom



	;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	;l'initialisation des ratios en eeprom n'est à faire que la première fois, ensuite on commente la ligne par un ;
	;on recompile le prg et on le recharge dans le µ. si cette manip n'est pas faite, à chaque mise du contact sur le véhicule
	; on re écrira les rations en eeprom ( attention à la durée de vie de l'eeprom)
	rcall	initialisation_des_ratios
	;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



	rcall	copie_des_ratios_en_ram     ;pour y avoir accès plus rapidement par la suite
init_seuil_moteur:
	ldi		temp1			,0x02		;seuil température moteur
	sts		seuil_moteur_H	,temp1		;pour 35°, le retour est de 
	ldi		temp1			,0xB2		;0x2B2 soit 690 millivolts
	sts		seuil_moteur_L	,temp1

	rcall	ecran_pret							;pour le débugage
	rcall	mess_encodeur						;pour le débugage
	IN		temp1					,PINC		;lecture du codeur sur port C
	andi    temp1,0x0F
	sts     memo_codeur	            ,temp1  ;memorisation de la position du codeur
	rcall	conv_hexa_asc_SEND				;pour le débugage, affiche la position du codeur       

	sei
CONVERSION: 
	ldi		temp1,0x00 ;flag = 0 pour ne pas orienter l'interruption vers les registres lambda
	rcall	CAN_chauffe_moteur

attente_temp_moteur:
	lds		temp1	,conv_finie			;flag de conversion terminée;
	cpi		temp1	,0x00				;si moteur froid, donc coeff à 50% ( 1 sur 2)
	breq	attente_temp_moteur 
	lds temp1,moteur_froid				; si = 0 le moteur est froid		
	cpi temp1,0x00
	breq	moteur_froid_init 

moteur_chaud_init:
	rcall	mess_moteur					;pour debugage
	rcall	mess_chaud					;pour debugage
	jmp		debut_prg

moteur_froid_init:
	rcall	mess_moteur					;pour debugage
	rcall	mess_froid					;pour debugage

debut_prg: 
ldi temp1,0x52							;pour debugage, affiche un R pour Retour de CAN moteur
rcall SEND_CHAR
IN		temp1 ,PINC						;lecture de l'encodeur sur port C
andi    temp1,0x0F						;filtre le nibble bas
sts     memo_codeur ,temp1				;memorisation de la position du codeur
rcall conv_hexa_asc_SEND				;
ldi		temp1,0x43						;pour debugage, affiche un C pour Retour de lecture enCodeur
rcall	SEND_CHAR
lds		temp1,memo_codeur				;mémorise la position de l'encodeur
mov		YL	,temp1
ldi		YH	,0x02
ld		temp1,Y							;lis en RAM la valeur pointée par la position de l'encodeur
sts		correction	,temp1				;initialiser le coefficient de correction
rcall conv_hexa_asc_SEND			    ;affiche la partie "comptage" de la correction 
ldi		temp2,0x10
lds		temp1,memo_codeur				;lis en RAM la valeur "ajout" de la correction pointée par l'encodeur 
clc
adc     temp1,temp2
mov		YL	,temp1
ldi		YH	,0x02
ld		temp1,Y
sts		ajout,temp1						;initialiser le coefficient de correction
sts     memo_ajout,temp1
rcall conv_hexa_asc_SEND				;affiche la partie "ajout" de la correction 
ldi temp1,0x7E;~
rcall SEND_CHAR


	rcall	init_du_timer2				;toutes les 1 Seconde pour led de vie et 3mn pour ctrl température moteur quand celui ci est froid
	rcall	init_du_timer0				;toutes les 32 µsecondes cadenceur injection
	sei
;////////////////////////////////////////////////////////////////////////////////////////////////// 
; les initialisations sont terminées, le programme commence ici
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
forever: 
lecture_codeur:
	IN		temp1,PINC						;lecture de la position de l'encodeur sur port C
	andi    temp1,0x0F                      ;filtre pour ne garder que le nibble bas
	sts     memo_codeur,temp1				;memorisation de la position du codeur
	cpi		temp1,0x00						;l'encodeur est 'il en position zéro
	breq	pas_de_correction				;oui, saut en recopie simple des entrées vers les sorties
E85:										;non, c'est du E85
	lds     temp1,moteur_froid				;le moteur est il froid?
	cpi     temp1,0x00						;oui, le moteur est froid
	breq    starter							;saut en mode starter, on y force l'enrichissement à 50%
E85_le_moteur_est_chaud:					;non, le moteur est chaud
	lds     temp1,memo_codeur				
	mov		YL	,temp1						;on lis la valeur "comptage" de la correction pointée par la position de l'encodeur
	ldi		YH	,0x02
	ld		temp1,Y
	sts		correction,temp1                ; et on l'initialise
	ldi		temp2,0x10
	lds		temp1,memo_codeur				;on ajoute 16 à l'adresse de la partie comptage de la correction
	clc										;pour avoir l'adresse de la partie "ajou" de la correction
	adc     temp1,temp2
	mov		YL	,temp1						;on lis la valeur de la partie "ajout"
	ldi		YH	,0x02
	ld		temp1,Y
	sts		ajout,temp1						;et on l'initialise
	sts     memo_ajout,temp1
	jmp		lecture_codeur					;on boucle en lecture du codeur en attendant l'interruption des 32 µ
E85_le_moteur_est_froid:
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
starter:									;starter, ici on va forcer la correction avec les valeurs 
	ldi		temp1,0x0F						;de "comptage" et d'"ajout" correspondant à la position 15 (0x0F) de l'encodeur
	;pour changer la correction du mode starter, il suffit de modifier la "position" de l'encodeur dans la ligne ci dessus
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	mov		YL	,temp1
	ldi		YH	,0x02
	ld		temp1,Y
	sts		correction,temp1				;ici on initialise la partie "comptage" de la correction
	ldi		temp1,0x18
	mov		YL	,temp1
	ldi		YH	,0x02
	ld		temp1,Y
	sts		ajout,temp1						;ici, on initialise la partie "ajout" de la correction
	sts     memo_ajout,temp1
	
sortie:	
	jmp		lecture_codeur					;on boucle en lecture du codeur en attendant l'interruption des 32 µ
carburant_normal:	  
pas_de_correction:							;c'est du carburant normal, on recopie simplement les entrées en sorties
	IN		temp1,PINB						;saisies des entrées du port B 
	rol		temp1							;décalage à droite pour mettre en accord avec 
	rol		temp1							;les sorties du port D
	out		PORTD,temp1						;on reporte les entrées du portB sur les sorties du portD 
	jmp		lecture_codeur					;on boucle en lecture du codeur en attendant l'interruption des 32 µ

;//////////////////////////////////////////////////////////////////////////////////////////////////
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
TIM0_COMPA:										;interruption timer 0, toutes les 32 secondes
	push	temp2								;on empile les registres
	in		temp2,Sreg
	push	temp2
	push	temp1

injecteur1:
	in		temp2,PINB 
	andi	temp2,0b00000001					;injecteur 1 
	cpi		temp2,0x01							;est il demandé fermé (= à 1) ?
	breq	injecteur1_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_1						;sinon, il est à 0 et on reporte la commande d'ouverture
	rcall	calcul_1
	jmp		injecteur2
injecteur1_tempo:								;on controle si le temps de maintien est terminé
	lds		temp1,tempo_inj_1_L 
	cpi		temp1,0x00
	brne	suite_1
	lds		temp1,tempo_inj_1_H
	cpi		temp1,0x00
	breq	sortie_injecteur1
suite_1:
	lds		sub1l,tempo_inj_1_L					;r18
	lds		sub1h,tempo_inj_1_H					;r19
	cpi		sub1l,0x00
	breq	ctrl_sub1h
	jmp		sub16_1
ctrl_sub1h:
	cpi		sub1h,0x00							;r19	la tempo de maintien l'injecteur 1 est elle terminée?
	breq	sortie_injecteur1					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_1						;non, on maintien la commande de l'injecteur 1 à 0
sub16_1: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_1_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_1_H,sub1h 
	jmp		injecteur2							;on passe à l'injecteur suivant
calcul_1:
calcul_1_1_pourcent:
	lds		temp1,tempo_inj_1_H					;on fait passer les paramètres propres à chaque injection
	mov		tampon_calcul_injection_H,temp1		;r29;pour permettre à la routine appelée de fonctionner sur elle meme
	lds		temp1,tempo_inj_1_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_1					;case memoire précompteur injection_1
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps			;saut en routine de calcul temps avec coeff correction
	mov		temp1,tampon_calcul_injection_H		;r29; on passe les paramètres en sens inverse
	sts		tempo_inj_1_H,temp1					;injection_1 récupère ses paramètres modifiés par la routine
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_1_L,temp1					;d'application du coeff de correction
	lds		temp1,precompteur_tampon
	sts		precompteur_1,temp1
	ret 
sortie_injecteur1:
	ldi		temp1,0x00
	sts		flag_1,temp1						;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_1						;la sortie de la commande de l'injecteur 1 passe à 1
;//////////////////////////////////////////////////////////////////////////////////////////////////
injecteur2:
	in		temp2,PINB 
	andi	temp2,0b00000010					;injecteur 2 
	cpi		temp2,0x02							;est il demandé fermé (= à 1) ?
	breq	injecteur2_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_2						;sinon, il est à 0 et on reporte la commande d'ouverture
	rcall	calcul_2 
	jmp		injecteur3
injecteur2_tempo:
	lds		temp1,tempo_inj_2_L
	cpi		temp1,0x00
	brne	suite_2
	lds		temp1,tempo_inj_2_H
	cpi		temp1,0x00
	breq	sortie_injecteur2
suite_2:
	lds		sub1l,tempo_inj_2_L					;r18
	lds		sub1h,tempo_inj_2_H					;r19
	cpi		sub1l,0x00
	breq	ctrl_sub2h
	jmp		sub16_2
ctrl_sub2h:
	cpi		sub1h,0x00							;r19la tempo de maintien l'injecteur 2 est elle terminée?
	breq	sortie_injecteur2					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_2						;non, on maintien la commande de l'injecteur 1 à 0
sub16_2: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_2_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_2_H,sub1h 
	jmp		injecteur3							;on passe à l'injecteur suivant
calcul_2:
calcul_2_1_pourcent:
	lds		temp1,tempo_inj_2_H
	mov		tampon_calcul_injection_H,temp1		;r29
	lds		temp1,tempo_inj_2_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_2					;case memoire
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps
	mov		temp1,tampon_calcul_injection_H		;r29
	sts		tempo_inj_2_H,temp1
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_2_L,temp1 
	lds		temp1,precompteur_tampon
	sts		precompteur_2,temp1
	ret 
sortie_injecteur2:
	ldi		temp1,0x00
	sts		flag_2,temp1						;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_2						;la sortie de la commande de l'injecteur 2 passe à 1
;//////////////////////////////////////////////////////////////////////////////////////////////////
injecteur3:
	in		temp2,PINB 
	andi	temp2,0b00000100					;injecteur 3 
	cpi		temp2,0x4							;est il demandé fermé (= à 1) ?
	breq	injecteur3_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_3						;sinon, il est à 0 et on reporte la commande d'ouverture
	rcall	calcul_3 
	jmp		injecteur4
injecteur3_tempo:
	lds		temp1,tempo_inj_3_L
	cpi		temp1,0x00
	brne	suite_3
	lds		temp1,tempo_inj_3_H
	cpi		temp1,0x00
	breq	sortie_injecteur3
suite_3:
	lds		sub1l,tempo_inj_3_L					;r20
	lds		sub1h,tempo_inj_3_H					;r21
	cpi		sub1l,0x00
	breq	ctrl_sub3h
	jmp		sub16_3
ctrl_sub3h:
	cpi		sub1h,0x00							;la tempo de maintien l'injecteur 3 est elle terminée?
	breq	sortie_injecteur3					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_3						;non, on maintien la commande de l'injecteur 1 à 0
sub16_3: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_3_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_3_H,sub1h 
	jmp		injecteur4							;on passe à l'injecteur suivant
calcul_3:
calcul_3_1_pourcent:
	lds		temp1,tempo_inj_3_H
	mov		tampon_calcul_injection_H,temp1		;r29
	lds		temp1,tempo_inj_3_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_3					;case memoire
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps
	mov		temp1,tampon_calcul_injection_H		;r29
	sts		tempo_inj_3_H,temp1
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_3_L,temp1 
	lds		temp1,precompteur_tampon
	sts		precompteur_3,temp1
	ret
sortie_injecteur3:
	ldi		temp1, 0x00
	sts		flag_3,temp1						;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_3						;la sortie de la commande de l'injecteur 3 passe à 1
;//////////////////////////////////////////////////////////////////////////////////////////////////
injecteur4:
	in		temp2,PINB 
	andi	temp2,0b00001000					;injecteur 4 
	cpi		temp2,0x8							;est il demandé fermé (= à 1) ?
	breq	injecteur4_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_4						;sinon, il est à 0 et on reporte la commande d'ouverture
	rcall	calcul_4 
	jmp		injecteur5
injecteur4_tempo:
	lds		temp1,tempo_inj_4_L
	cpi		temp1,0x00
	brne	suite_4
	lds		temp1,tempo_inj_4_H
	cpi		temp1,0x00
	breq	sortie_injecteur4
suite_4:
	lds		sub1l,tempo_inj_4_L					;r20
	lds		sub1h,tempo_inj_4_H					;r21
	cpi		sub1l,0x00
	breq	ctrl_sub4h
	jmp		sub16_4
ctrl_sub4h:
	cpi		sub1h,0x00							;la tempo de maintien l'injecteur 4 est elle terminée?
	breq	sortie_injecteur4					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_4						;non, on maintien la commande de l'injecteur 4 à 0
sub16_4: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_4_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_4_H,sub1h 
	jmp		injecteur5							;on passe à l'injecteur suivant
calcul_4:
calcul_4_1_pourcent:
	lds		temp1,tempo_inj_4_H
	mov		tampon_calcul_injection_H,temp1		;r29
	lds		temp1,tempo_inj_4_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_4					;case memoire
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps
	mov		temp1,tampon_calcul_injection_H		;r29
	sts		tempo_inj_4_H,temp1
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_4_L,temp1 
	lds		temp1,precompteur_tampon
	sts		precompteur_4,temp1
	ret
sortie_injecteur4:
	ldi		temp1,0x00
	sts		flag_4,temp1						;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_4						;la sortie de la commande de l'injecteur 4 passe à 1
;//////////////////////////////////////////////////////////////////////////////////////////////////
injecteur5:
	in		temp2,PINB 
	andi	temp2,0b00010000					;injecteur 5 
	cpi		temp2,0x10							;est il demandé fermé (= à 1) ?
	breq	injecteur5_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_5						;sinon, il est à 0 et on reporte la commande d'ouverture 
	rcall	calcul_5 
	jmp		injecteur6
injecteur5_tempo:
	lds		temp1,tempo_inj_5_L
	cpi		temp1,0x00
	brne	suite_5
	lds		temp1,tempo_inj_5_H
	cpi		temp1,0x00
	breq	sortie_injecteur5
suite_5:
	lds		sub1l,tempo_inj_5_L					;r20
	lds		sub1h,tempo_inj_5_H					;r21
	cpi		sub1l,0x00
	breq	ctrl_sub5h
	jmp		sub16_5
ctrl_sub5h:
	cpi		sub1h,0x00							;la tempo de maintien l'injecteur 5 est elle terminée?
	breq	sortie_injecteur5					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_5						;non, on maintien la commande de l'injecteur 5 à 0
sub16_5: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_5_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_5_H,sub1h 
	jmp		injecteur6							;on passe à l'injecteur suivant
calcul_5:
calcul_5_1_pourcent:
	lds		temp1,tempo_inj_5_H
	mov		tampon_calcul_injection_H,temp1		;r29
	lds		temp1,tempo_inj_5_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_5					;case memoire
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps
	mov		temp1,tampon_calcul_injection_H		;r29
	sts		tempo_inj_5_H,temp1
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_5_L,temp1 
	lds		temp1,precompteur_tampon
	sts		precompteur_5,temp1
	ret
sortie_injecteur5:
	sbi		PORTD,Sinj_5						;la sortie de lcommande de l'injecteur 1 passe à 1
	ldi		temp1,0x00
	sts		flag_5,temp1							;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_5						;la sortie de la commande de l'injecteur 5 passe à 1
;//////////////////////////////////////////////////////////////////////////////////////////////////
injecteur6:
	in		temp2,PINB 
	andi	temp2,0b00100000					;injecteur 6 
	cpi		temp2,0x20							;est il demandé fermé (= à 1) ?
	breq	injecteur6_tempo					;si oui, sa tempo est elle terminée?
	cbi		PORTD,Sinj_6						;sinon, il est à 0 et on reporte la commande d'ouverture
	rcall	calcul_6 
	jmp		sortie_timers
injecteur6_tempo:
	lds		temp1,tempo_inj_6_L
	cpi		temp1,0x00
	brne	suite_6
	lds		temp1,tempo_inj_6_H
	cpi		temp1,0x00
	breq	sortie_injecteur6
suite_6:
	lds		sub1l,tempo_inj_6_L					;r20
	lds		sub1h,tempo_inj_6_H					;r21
	cpi		sub1l,0x00
	breq	ctrl_sub6h
	jmp		sub16_6
ctrl_sub6h:
	cpi		sub1h,0x00							;la tempo de maintien l'injecteur 6 est elle terminée?
	breq	sortie_injecteur6					;oui, elle est terminée, on saute en mise à 1 en sortie
	cbi		PORTD,Sinj_6						;non, on maintien la commande de l'injecteur 6 à 0
sub16_6: 
	sub		sub1l,sub2l							;soustraction des bits bas
	sbc		sub1h,sub2h							;soustraction des bits haut avec la retenue 
	sts		tempo_inj_6_L,sub1l					;résultat dans r18L et R19H
	sts		tempo_inj_6_H,sub1h 
	jmp		sortie_timers						;on passe à l'injecteur suivant
calcul_6:
calcul_6_1_pourcent:
	lds		temp1,tempo_inj_6_H
	mov		tampon_calcul_injection_H,temp1		;r29
	lds		temp1,tempo_inj_6_L
	mov		tampon_calcul_injection_L,temp1		;r28
	lds		temp1,precompteur_6					;case memoire
	sts		precompteur_tampon,temp1 
	rcall	calcul_correction_du_temps
	mov		temp1,tampon_calcul_injection_H		;r29
	sts		tempo_inj_6_H,temp1
	mov		temp1,tampon_calcul_injection_L		;r28
	sts		tempo_inj_6_L,temp1 
	lds		temp1,precompteur_tampon
	sts		precompteur_6,temp1
	ret
sortie_injecteur6:
	ldi		temp1,0x00
	sts		flag_6,temp1						;on repasse le flag à zéro pour la prochaine injection 1
	sbi		PORTD,Sinj_6						;la sortie de lcommande de l'injecteur 6 passe à 1
sortie_timers:
sortie_COMPA_T0:
	ldi		temp1, 0x07							;valide les interruptions si sei est valide
	out		TIFR0,temp1							;raz le flag de demande d'interruption
	pop		temp1								;récupère temp1 sur la pile
	pop		temp2								;récupère dans temp2 le registre d'état sur la pile
	out		sreg,temp2							;transfere temps2 dans le registre d'état
	pop		temp2								;récupère temp2 sur la pile
	reti										;fin de l'interruption du timer0 
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
CAN_chauffe_moteur:					; précision sur 10 bits justification à droite. ma tension de ref = 1.0243V soit divisée par 1024 donne un lsb de 0.001000293 Volt
	push	temp1
	push	temp2
	ldi		temp1,0b11000101		;(1<<REFS1)|(1<<REFS0)|(1<<ADLAR);ADLAR = 1 =>justif à gauche, ref interne 1.1V avec condo sur pin AREF et voie entrée ANA 1
	sts		ADMUX,temp1
	lds		temp1,ADCSRA			;validation du convertisseur
	ori		temp1,0b10001100		;ADEN passe à 1
	sts		ADCSRA,temp1
	lds		temp1, ADCSRA
	ori		temp1,0b11000100		;top de conversion passe à 1 et repassera à zéro seul 
	sts		ADCSRA,temp1			;ADSC passe à 1
	pop		temp2
	pop		temp1
	ret
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ADC_COMP:							;analogique digitale conversion complète
attente_fin_de_conversion:
	push	temp3 ;r18
	push	temp2					;r17;on empile les registres
	in		temp2,Sreg
	push	temp2
	push	temp1					;r16
;************************************************************************
	lds		temp1,ADCSRA			;efface le flag de conversion finie
	ori		temp1,0b10010100		;un 1 efface le flag de conversion finie 
	sts		ADCSRA,temp1			;prescaler = 16
	lds		temp2,ADCL				;lecture de la donnée basse
	lds		temp1,ADCH				;lecture de la donnée haut

moteur:
;*********************************************************************************** 
	sts		moteur_L,temp2			;0xE0
	sts		moteur_H,temp1			;0xE0
	lds		temp3,seuil_moteur_L	;temp3=0xB2
	lds		temp4,seuil_moteur_H	;temp4=0x02
	lds		temp1,moteur_L
	lds		temp2,moteur_H 
	cp		temp2,temp4				;si le seuil_bas_H est > on sort
	brpl	moteur_chaud
	breq	test_seuil_bas_L		;si le seuil_bas_H est = on test le seuil bas L
	jmp		Moteur_froid_E85		;sinon, le seuil H est = ou < 
test_seuil_bas_L:
	cp		temp1,temp3 ;
	brpl	moteur_chaud
	jmp		Moteur_froid_E85

moteur_chaud:
	ldi     temp1,0x01
	sts		moteur_froid,temp1		;le moteur n'est pas froid
	jmp		sortie_de_conversion
Moteur_froid_E85:
	ldi     temp1,0x00
    sts		moteur_froid,temp1		;le moteur est  froid

sortie_de_conversion:
;debug
;ldi temp1,0x4D;Moteur
;rcall SEND_CHAR
;lds  temp1,moteur_H
;rcall conv_hexa_asc_SEND
;mov temp1,temp2;
;rcall conv_hexa_asc_SEND
;ldi temp1,0x2A;*
;rcall SEND_CHAR
;ldi temp1,0x20;space
;rcall SEND_CHAR
;ldi temp1,0x2A;*
;rcall SEND_CHAR
;lds  temp1,moteur_froid
;rcall conv_hexa_asc_SEND
;ldi temp1,0x2A;*
;rcall SEND_CHAR

	ldi		temp1,0x01
	sts		conv_finie,temp1

	pop		temp1			;récupère temp1 sur la pile
	pop		temp2			;récupère dans temp2 le registre d'état sur la pile
	out		sreg,temp2		;transfere temps2 dans le registre d'état
	pop		temp2			;récupère temp2 sur la pile
	pop		temp3			;récupère temp3 sur la pile
	reti
;//////////////////////////////////////////////////////////////////////////////////////////////////
TIM2_OVF: ;le préscaler est diviseur par 1024 de la fréquence horloge
;un cycle du timer2 = 16,404 miliseconde
;une seconde=1000/16.404 = 61 cycles pour faire 1 seconde
;une minute =60*61= 3660 cycles
;pour rapidité, 3840 = 0x0F00
;correction pour 10 secondes
;10 secondes = 61 cycles * 10 = 610 cycles en hexa:0x0262
	push	temp3			;r18
	push	temp2			;r17;on empile les registres
	in		temp2,Sreg
	push	temp2
	push	temp1			;r16
;************************************************************************
	mov		temp1,compteur_cycles_L_T_1_2	;on incrémente l'octet bas du compteur d'interruptions
	inc		temp1							;
	mov		compteur_cycles_L_T_1_2,temp1	;
	cpi		temp1,0x61						;y a t'il eu 61 interruptions de 16 ms (1 seconde)?
	brne	sortie_de_timer2_overflow		;non alors on sort 
une_seconde_passee:							;oui, il y a 1 seconde d'écoulée
	ldi		compteur_cycles_L_T_1_2	,0x00	;on raz l'octet bas du compteur d'interruptions
	lds		temp1,compteur_secondes_Temp	;on incrémente le compteur de secondes
	inc		temp1

	sts		compteur_secondes_Temp	,temp1	;le compteur de secondes
	;//////////////////////////////////////////////////////////////////////////////////////////////////////////
	;c'est ici pour modifier la fréquence de la led de vie
	cpi		temp1					,0x01	;est'il arrivé à 1 seconde?
	;cpi		temp1						;0x0A	;est'il arrivé à 10 secondes?
	;//////////////////////////////////////////////////////////////////////////////////////////////////////////
	brsh	flip_flop_C4					;oui, on saute en flip_flop_C4:
	jmp		sortie_de_timer2_overflow		;on sort car il n'y a pas encore 10 secondes comptées

flip_flop_C4: 
	in		temp1,portC						;on lis la sortie 4 du port C
	ldi		temp2,0b00010000				;on isole le bit 4
	and		temp1,temp2
	eor		temp1,temp2						;on inverse le bit 4
	out		portC,temp1						;on le recopie sur le port C
	ldi		temp1,0x00
	mov		compteur_cycles_H_T_1_2,temp1	;on raz tous les paramètres pour compter 
	mov		compteur_cycles_L_T_1_2,temp1	;à nouveau 10 secondes
	sts		compteur_secondes_Temp,temp1

	lds temp1,moteur_froid; si = 0 le moteur est froid		
	cpi temp1,0x00
	brne	sortie_de_timer2_overflow
	
	;ici, si le moteur est froid, on surveille sa température toutes les 2 minutes
	;dès qu'il est chaud, on abandonne le mode starter
comptage_des_minutes:						;les 10 premières minutes sont passées, 
	lds		temp1,minutes	
	inc		temp1
	sts		minutes,temp1
	cpi		temp1,0x78						;est'il arrivé à 120 secondes?
	brlo	sortie_de_timer2_overflow
	ldi		temp1,0x00
	sts		minutes,temp1					;on raze tous les paramètres pour compter 
	rcall	CAN_chauffe_moteur

sortie_de_timer2_overflow:
	pop		temp1			;récupère temp1 sur la pile
	pop		temp2			;récupère dans temp2 le registre d'état sur la pile
	out		sreg,temp2		;transfere temps2 dans le registre d'état
	pop		temp2			;récupère temp2 sur la pile
	pop		temp3			;récupère temp3 sur la pile
	reti
;//////////////////////////////////////////////////////////////////////////////////////////////////
init_CAN: ; précision sur 10 bits justification à droite. ma tension de ref = 1.0243V soit divisée par 1024 donne un lsb de 0.001000293 Volt
	ldi		temp1,0b11000000	;(1<<REFS1)|(1<<REFS0)|(0<<ADLAR) ;ADLAR = 0 =>justif à droite, ref interne 1.1V avec condo sur pin AREF et voie entrée ANA 0
	sts		ADMUX,temp1
	ldi		temp1,0b00000110	;préscaler 128 pour ramener la fréquence de conversion de 16000000à 250000
	sts		ADCSRA,temp1 
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
USART_INIT: ;fonctionne avec le moniteur arduino en 115200 bauds mais ne fonctionne pas avec le terminal AVRSTUDIO
	.equ	quartz		= 16000000 
	.equ	bauderate	= 115200	; sera à 115200 si X2 validé 
	.equ	UBRRVAL		= ((quartz+bauderate*4)/(bauderate*8)-1) ; pour 57600 et 115200 si X2 activé
	ldi		r16,UBRRVAL
	ldi		r17,(UBRRVAL>>8)
	sts		UBRR0H,r17				;baud register high
	sts		UBRR0L,r16				;baud register low 
	ldi		temp1,0x22				;double la vitesse
	sts		UCSR0A,temp1			;si mode assynchro
	ldi		temp1,(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0) ;les bits RXEN0 et TXEN0 passent à 1
	sts		UCSR0B,temp1			;valident la réception et la transmission par l'USART. ;le bit USBS0 reste à 0 pour 1bit de stop
	ldi		temp1,(1<<UCSZ00)|(1<<UCSZ01) ;(1<<USBS0)le double bit UCSZ00 et UCSZ01 passe à 1 pour 8 bits de transmission
	sts		UCSR0C,temp1			;19200,pas de parité,huits bits et 1 bit de stop
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
init_du_timer0:				;est utilisé comme cadenceur pour faire 8 timers
	ldi		temp1,0x00
	out		TCNT0,temp1		;le timer0 comptera jusqu'à OCR0A puis passera en comparaison trouvée
	ldi		temp1,0x02		;valide les interruptions si sei est valide
	out		TCCR0A,temp1	;;mode CTC clear (TCNT0)sur comparaison trouvée
	ldi		temp1,0x02 
	sts		TIMSK0,temp1	;valide l'interruption par comparaison trouvée avec OCR0A
	lds		temp1,micro		;0x 3F = 32µ secondes
	out		OCR0A,temp1		;on initialise la cible du comptage
	ldi		temp1,0x07		;raz une eventuelle demande d'interruption
	out		TIFR0,temp1
	ldi		temp1,0x02		;initialise le préscaler du timer0 à 2 pour une division par64
	out		TCCR0B,temp1	;mise en fonction du Timer 0 en mode comparaison sur OCRA0
	ret						;retour à l'appelant
;//////////////////////////////////////////////////////////////////////////////////////////////////
init_du_timer2:				;est utilisé comme minuterie 10 secondes pour 
	ldi		temp1,0x00		;cadencer la scrutation de la sonde lambda
	sts		TCNT2,temp1		;le timer2 comptera jusqu'à 0x3C puis recommencera à compter à partir de 0
	ldi		temp1,0x00		;valide les interruptions si sei est valide
	sts		TCCR2A,temp1	;mode normal clear (TCNT2)
	ldi		temp1,0x01 
	sts		TIMSK2,temp1	;valide l'interruption sur débordement à 0xFF
	ldi		temp1,0x07		;raz une eventuelle demande d'interruption
	out		TIFR2,temp1
	ldi		temp1,0x07		;initialise le préscaler du timer2 à 7 pour une division par1024
	sts		TCCR2B,temp1	;
	ret						;retour à l'appelant
;//////////////////////////////////////////////////////////////////////////////////////////////////
SEND_CHAR:
	ldi		temp_L,0x06 
	rcall	bcl_tempo_2			;1 mili
	push	temp2				;r17
	lds		temp2,UCSR0A
	sbrs	temp2,UDRE0
	rjmp	SEND_CHAR
pour_debug:
	sts		UDR0,temp1
	pop		temp2
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
delay_court: ;159 microsecondeS
	ldi		temp_C,0xff		;r24
bcl_tempo_1:
	dec		temp_C			;compte de zéro à 255
	brne	bcl_tempo_1
	ret 
;//////////////////////////////////////////////////////////////////////////////////////////////////
delay_long: ;4 milisecondes
	ldi		temp_L,0xff
bcl_tempo_2:
	rcall	delay_court		;appelle 255 fois delay_court
	dec		temp_L			;r25;donc 255*255
	brne	bcl_tempo_2
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
conv_hexa_asc_SEND:
	push temp1				;r16
	push temp2				;r17
	push temp1
	swap temp1 
	andi temp1,0x0f
	ori temp1,0x30
	cpi temp1,0x3A
	brlo send_nibble_H		;vaut de 0 à 9
	ldi temp2,0x07
	add temp1,temp2			;vaut de A à F
send_nibble_H:
	rcall SEND_CHAR			;affiche les unités de 0 à F
	pop temp1
	andi temp1,0x0f
	ori temp1,0x30
	cpi temp1,0x3A
	brlo send_nibble_L		;vaut de 0 à 9
	ldi temp2,0x07
	add temp1,temp2			;vaut de A à F
send_nibble_L:
	rcall SEND_CHAR			;affiche les dizaines de 0 à F
	pop temp2
	pop temp1
	ret
;***************************************************************************
calcul_correction_du_temps:
	lds temp2,correction
	lds precompt,precompteur_tampon
	inc precompt						;r15
	mov temp1,tampon_calcul_injection_L
	mov temp1, precompt					;r16 r24
	cp temp1,temp2						;compare avec le % de correctioon
	breq plus_un
	sts precompteur_tampon,temp1
	ret
plus_un:
	ldi temp2,0x00
	sts precompteur_tampon,temp2		;raz du précompteur
	lds temp3,memo_ajout
decomptage_ajout:
	adiw tampon_calcul_injection_H:tampon_calcul_injection_L,0x01
	dec temp3
	brne decomptage_ajout
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
initialisation_des_ratios:
	;partie "comptage" de correction
	ldi YL,0x00				;(200)
	ldi YH,0x00				;encodeur en position 0
	ldi temp1,0x00			;0x00=pas de correction
	rcall ecriture_EEprom
	ldi YL,0x02				;encodeur en position 1
	ldi YH,0x00				
	ldi temp1,0x0A			;0x0A=10% on comptera 10 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x04				;encodeur en position 2
	ldi YH,0x00
	ldi temp1,0x06			;0x06=15% on comptera 6 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x06				;encodeur en position 3
	ldi YH,0x00
	ldi temp1,0x05			;0x05=20% on comptera 5 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x08				;encodeur en position 4
	ldi YH,0x00
	ldi temp1,0x09			;0x09=22% on comptera 9 et on mémorisera 2
	rcall ecriture_EEprom
	ldi YL,0x0A				;encodeur en position 5
	ldi YH,0x00				
	ldi temp1,0x04			;0x04=25% on comptera 4 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x0C				;encodeur en position 6
	ldi YH,0x00				
	ldi temp1,0x0F			;0x0F=27% on comptera 15 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x00E			;encodeur en position 7
	ldi YH,0x00
	ldi temp1,0x10			;0x10=30% on comptera 10 et on mémorisera 5
	rcall ecriture_EEprom
	ldi YL,0x10				;encodeur en position 8
	ldi YH,0x00
	ldi temp1,0x03			;0x3=33% on comptera 3 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x12				;encodeur en position 9
	ldi YH,0x00
	ldi temp1,0x0E			;0x0E=35% on comptera 14 et on mémorisera 5
	rcall ecriture_EEprom
	ldi YL,0x14				;encodeur en position 10
	ldi YH,0x00
	ldi temp1,0x9			;0x09=36% on comptera 9 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x16				;encodeur en position 11
	ldi YH,0x00
	ldi temp1,0x0C			;0x0C=40% on comptera 12 et on mémorisera 5 
	rcall ecriture_EEprom
	ldi YL,0x18				;encodeur en position 12
	ldi YH,0x00
	ldi temp1,0x07			;0x00=42% on comptera 7 et on mémorisera 3
	rcall ecriture_EEprom
	ldi YL,0x1A				;encodeur en position 13
	ldi YH,0x00
	ldi temp1,0x09			;0x00=45% on comptera 9 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x1C				;encodeur en position 14
	ldi YH,0x00
	ldi temp1,0x0D			;0x0D=48% on comptera 13 et on mémorisera 6
	rcall ecriture_EEprom
	ldi YL,0x1E				;encodeur en position 15
	ldi YH,0x00
	ldi temp1,0x02			;0x00=50% on comptera 2 et on mémorisera 1
	rcall ecriture_EEprom
	
;partie "ajout" de correction
	ldi YL,0x20 
	ldi YH,0x00				;encodeur en position 0
	ldi temp1,0x00			;0x00=pas de correction
	rcall ecriture_EEprom
	ldi YL,0x22				;encodeur en position 1
	ldi YH,0x00				
	ldi temp1,0x01			;0x0A=10% on comptera 10 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x24				;encodeur en position 2
	ldi YH,0x00
	ldi temp1,0x01			;0x06=15% on comptera 6 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x26				;encodeur en position 3
	ldi YH,0x00
	ldi temp1,0x01			;0x05=20% on comptera 5 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x28				;encodeur en position 4
	ldi YH,0x00
	ldi temp1,0x02			;0x09=22% on comptera 9 et on mémorisera 2
	rcall ecriture_EEprom
	ldi YL,0x2A				;encodeur en position 5
	ldi YH,0x00				
	ldi temp1,0x01			;0x04=25% on comptera 4 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x2C			;encodeur en position 6
	ldi YH,0x00				
	ldi temp1,0x04			;0x0F=27% on comptera 15 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x2E			;encodeur en position 7
	ldi YH,0x00
	ldi temp1,0x05			;0x10=30% on comptera 10 et on mémorisera 5
	rcall ecriture_EEprom
	ldi YL,0x30				;encodeur en position 8
	ldi YH,0x00
	ldi temp1,0x01			;0x3=33% on comptera 3 et on mémorisera 1
	rcall ecriture_EEprom
	ldi YL,0x32				;encodeur en position 9
	ldi YH,0x00
	ldi temp1,0x05			;0x0E=35% on comptera 14 et on mémorisera 5
	rcall ecriture_EEprom
	ldi YL,0x34				;encodeur en position 10
	ldi YH,0x00
	ldi temp1,0x04			;0x09=36% on comptera 9 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x36				;encodeur en position 11
	ldi YH,0x00
	ldi temp1,0x05			;0x0C=40% on comptera 12 et on mémorisera 5 
	rcall ecriture_EEprom
	ldi YL,0x38				;encodeur en position 12
	ldi YH,0x00
	ldi temp1,0x03			;0x00=42% on comptera 7 et on mémorisera 3
	rcall ecriture_EEprom
	ldi YL,0x3A				;encodeur en position 13
	ldi YH,0x00
	ldi temp1,0x04			;0x00=45% on comptera 9 et on mémorisera 4
	rcall ecriture_EEprom
	ldi YL,0x3C				;encodeur en position 14
	ldi YH,0x00
	ldi temp1,0x06			;0x0D=48% on comptera 13 et on mémorisera 6
	rcall ecriture_EEprom
	ldi YL,0x3E				;encodeur en position 15
	ldi YH,0x00
	ldi temp1,0x01			;0x00=50% on comptera 2 et on mémorisera 1
	rcall ecriture_EEprom
ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
copie_des_ratios_en_ram:
	;parties "comptage" et "ajout" à suivre
	ldi		pointeur_correction_H	,$02	; on recopie les ratios qui sont en EEprom en RAM
	ldi		pointeur_correction_L	,$00 
	ldi		temp2					,0x00	; les temps d'accès seront plus court et ne pertuberont pas 
copie_en_ram:								;la vitesse du programme d'injection
	mov		YL						,temp2
	ldi		YH						,0x00
	rcall	lecture_EEprom
	st		X+						,temp1
	inc		temp2
	inc		temp2
	cpi		temp2,0x40
	brne	copie_en_ram

	;affichage sur le moniteur pour le debugage
affichage_des_ratios_sur_moniteur:			;pour debug
	ldi		pointeur_correction_H,$02		;on affiche les ratios sur le moniteur 
	ldi		pointeur_correction_L,$00		;pour vérifier la bonne initialisation
affichage_ajoute:
	ld		temp1,X+						;on utilise une simple boucle de 0 à 0x0D
	rcall conv_hexa_asc_SEND				;il y a 0x0C data à recopier sur le moniteur
	ldi temp1,0x3A;:
	rcall SEND_CHAR
	cpi		pointeur_correction_L,0x20
	brne	affichage_ajoute
	ldi temp1,0x40;@
	rcall SEND_CHAR
ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
EEPROM:
ecriture_EEprom:
	rcall	WRITEEE			;routine d'écriture en EEprom
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
lecture_EEprom:
	ldi		temp1,0x00		;vide temp1 qui contiendra la donnée lue au retour
	rcall	READEE			;routine de lecture en EEprom
	ret 
;//////////////////////////////////////////////////////////////////////////////////////////////////
READEE:
	sbic	EECR,EEPE	;EEPROM occupée en écriture ?
	rjmp	ReadEE			;oui, on boucle pour attendre qu'elle soit libre
	out		EEARH,YH		;r29;initialisation de l'adresse haute en EEPROM
	out		EEARL,YL		;r28;initialisation de l'adresse basse en EEPROM
	sbi		EECR,EERE	;le bit de lecture passe à 1
	in		temp1,EEDR	;retour avec le contenu de l'adresse 0 dans temp1 (R16)
	ret
;//////////////////////////////////////////////////////////////////////////////////////////////////
WRITEEE:
	sbic	EECR,EEPE	;l'EEPROM est déjà occupée?
	rjmp	WriteEE			;oui, on attends
	out		EEARH,YH		;r29;init des adresses de destination en EEPROM
	out		EEARL,YL		;r28
	out		EEDR,temp1		;la donnée passe dans le tampon d'écriture en EEPROM
	adiw	Y,1 
	cli						;pas d'interruption pendant l'écriture en EEPROM 
	sbi		EECR,EEMPE	;passe à 1 "en mode écriture"
	sbi		EECR,EEPE	;passe à 1 l'ordre d'écriture
	sei						;les interruptions sont à nouveau autorisées
	ret						;retour à l'appelant
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
razdetouteleprom: ;les 4 pages de l'EEPROM passent à 0x00
razEEprom:
	ldi		temp1,0xFF	;valeur à écrire en EEPROM
	ldi		YH,0		;adresse haute de destination en EEPROM
	ldi		YL,0		;adresse bessa de destination en EEPROM
	ldi		temp2,0x00	;compteur des 255 octets à transférer dans une page
raztouteeprom:
	rcall	WRITEEE					;appel à la routine d'écriture en EEPROM
	adiw	Y,1		;incrémente l'adresse basse de destination en EEPROM
	inc		temp2					;avons nous traité les 255 octets d'une page?
	brne	raztouteeprom			;non, alors on boucle
	cpi		r29,4		;avons nous traité les 4 pages de l'EEPROM
	brne	raztouteeprom			;non, alors on boucle
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RAZ des 4 pages de l'EEPROM
razEEprompage0:
	ldi temp1,0x10
	ldi YH,0
	ldi YL,0
	ldi temp2,0x00
razepromp0:
	rcall WRITEEE
	adiw Y,1
	inc temp2
	brne razepromp0
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
razEEprompage1:
	ldi temp1,0x11
	ldi YH,1
	ldi YL,0
	ldi temp2,0x00
razepromp1:
	rcall WRITEEE
	adiw Y,1
	inc temp2
	brne razepromp1
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
razEEprompage2:
	ldi temp1,0x12
	ldi YH,2
	ldi YL,0
	ldi temp2,0x00
	razepromp2:
	rcall WRITEEE
	adiw Y,1
	inc temp2
	brne razepromp2
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
razEEprompage3:
	ldi temp1,0x13
	ldi YH,3
	ldi YL,0
	ldi temp2,0x00
razepromp3:
	rcall WRITEEE
	adiw Y,1
	inc temp2
	brne razepromp3
	ret
adresse_correction_memorisee:
	ldi		temp1,0x02
	rcall	conv_hexa_asc_SEND
	ldi		YL,0x32 
	ldi		YH,0x00 
	ldi		temp1,0x00				;vide temp1 qui contiendra la donnée lue au retour
	rcall	READEE 
	rcall	conv_hexa_asc_SEND
	sts		derniere_correction,temp1
	ldi		temp1,0x20				;space
	rcall	SEND_CHAR 
	ret
ecran_pret:
	ldi		temp1,0x50	;P affiche "pret" sur le terminal arduino en 115200
	rcall SEND_CHAR
	ldi		temp1,0x52	;R
	rcall SEND_CHAR
	ldi		temp1,0x45	;E
	rcall SEND_CHAR
	ldi		temp1,0x54	;T
	rcall SEND_CHAR
	ldi		temp1,0x20	;affiche un espace sur le terminal arduino
	rcall SEND_CHAR 
	ldi		temp1,0x0A	;nl ;new line feed,new line
	rcall SEND_CHAR 
	ret 
mess_moteur:
	ldi		temp1,0x4D ;m 
	rcall	SEND_CHAR
	ldi		temp1,0x4F ;o
	rcall	SEND_CHAR
	ldi		temp1,0x54 ;t
	rcall	SEND_CHAR
	ldi		temp1,0x45 ;e
	rcall	SEND_CHAR
	ldi		temp1,0x55 ;u 
	rcall	SEND_CHAR
	ldi		temp1,0x52 ;r
	rcall	SEND_CHAR
	ldi		temp1,0x20 ;affiche un espace sur le terminal arduino
	rcall	SEND_CHAR 
	ret
mess_chaud:
	ldi		temp1,0x43 ;c
	rcall	SEND_CHAR
	ldi		temp1,0x48 ;h
	rcall	SEND_CHAR
	ldi		temp1,0x41 ;a 
	rcall	SEND_CHAR
	ldi		temp1,0x55 ;u
	rcall	SEND_CHAR
	ldi		temp1,0x44 ;d
	rcall	SEND_CHAR 
	ldi		temp1,0x20 ;affiche un espace sur le terminal arduino
	rcall	SEND_CHAR 
	ldi		temp1,0x43 ;c
	rcall	SEND_CHAR
	ldi		temp1,0x4F ;o 
	rcall	SEND_CHAR
	ldi		temp1,0x52 ;r
	rcall	SEND_CHAR
	ldi		temp1,0x3D ;=
	rcall	SEND_CHAR
	ret 
mess_froid:
	ldi		temp1,0x46	;f
	rcall	SEND_CHAR
	ldi		temp1,0x52	;r
	rcall	SEND_CHAR
	ldi		temp1,0x4F	;o 
	rcall	SEND_CHAR
	ldi		temp1,0x49	;i
	rcall	SEND_CHAR
	ldi		temp1,0x44	;d
	rcall	SEND_CHAR 
	ldi		temp1,0x20	;affiche un espace sur le terminal arduino
	rcall	SEND_CHAR 
	ldi		temp1,0x43	;c
	rcall	SEND_CHAR
	ldi		temp1,0x4F	;o 
	rcall	SEND_CHAR
	ldi		temp1,0x52	;r
	rcall	SEND_CHAR
	ldi		temp1,0x20	;space
	rcall	SEND_CHAR
	ldi		temp1,0x48	;h
	rcall	SEND_CHAR 
	ldi		temp1,0x45	;e 
	rcall	SEND_CHAR 
	ldi		temp1,0x58	;x 
	rcall	SEND_CHAR
	ldi		temp1,0x41	;a 
	rcall	SEND_CHAR 
	ldi		temp1,0x20	;space
	rcall	SEND_CHAR 
	ldi		temp1,0x3D	;=
	rcall	SEND_CHAR
	ldi		temp1,0x20	;space
	rcall	SEND_CHAR 
	ret 
val_cor:
	rcall	conv_hexa_asc_SEND
	ldi		temp1,0x20 ;space
	rcall	SEND_CHAR 
	ret 
mess_encodeur:
	ldi		temp1,0x45 ;e
	rcall	SEND_CHAR 
	ldi		temp1,0x4E ;n
	rcall	SEND_CHAR 
	ldi		temp1,0x43 ;c
	rcall	SEND_CHAR
	ldi		temp1,0x4F ;o 
	rcall	SEND_CHAR
	ldi		temp1,0x44 ;d
	rcall	SEND_CHAR
	ldi		temp1,0x45 ;e
	rcall	SEND_CHAR
	ldi		temp1,0x55 ;u 
	rcall	SEND_CHAR
	ldi		temp1,0x52 ;r
	rcall	SEND_CHAR
	ldi		temp1,0x20 ;space
	rcall	SEND_CHAR 
	ret 
mess_adresse:
	ldi		temp1,0x41 ;a
	rcall	SEND_CHAR
	ldi		temp1,0x44 ;d
	rcall	SEND_CHAR
	ldi		temp1,0x52 ;r
	rcall	SEND_CHAR
	ldi		temp1,0x45 ;e
	rcall	SEND_CHAR 
	ldi		temp1,0x53 ;s
	rcall	SEND_CHAR 
	ldi		temp1,0x53 ;s
	rcall	SEND_CHAR
	ldi		temp1,0x45 ;e 
	rcall	SEND_CHAR
	ldi		temp1,0x20 ;space
	rcall	SEND_CHAR
	ldi		temp1,0x52 ;r
	rcall	SEND_CHAR
	ldi		temp1,0x41 ;a 
	rcall	SEND_CHAR
	ldi		temp1,0x4D ;m
	rcall	SEND_CHAR
	ldi		temp1,0x20 ;space
	rcall	SEND_CHAR 
	ret 
mess_sauvee_en:
	ldi		temp1,0x53;s 
	rcall SEND_CHAR 
	ldi		temp1,0x41;a 
	rcall SEND_CHAR
	ldi		temp1,0x55;u 
	rcall SEND_CHAR 
	ldi		temp1,0x56;v 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x20;space
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x4E;n 
	rcall SEND_CHAR
	ldi		temp1,0x20;space 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x50;p 
	rcall SEND_CHAR 
	ldi		temp1,0x52;r 
	rcall SEND_CHAR 
	ldi		temp1,0x4F;o 
	rcall SEND_CHAR 
	ldi		temp1,0x4D;m 
	rcall SEND_CHAR 
	ldi		temp1,0x20;space 
	rcall SEND_CHAR
	ret
mess_valeur:
	ldi		temp1,0x20;space 
	rcall SEND_CHAR 
	ldi		temp1,0x56;v 
	rcall SEND_CHAR 
	ldi		temp1,0x41;a 
	rcall SEND_CHAR 
	ldi		temp1,0x4C;l 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x55;u 
	rcall SEND_CHAR 
	ldi		temp1,0x52;r 
	rcall SEND_CHAR
	ldi		temp1,0x20;space 
	rcall SEND_CHAR
	ldi		temp1,0x48;h 
	rcall SEND_CHAR 
	ldi		temp1,0x45;e 
	rcall SEND_CHAR 
	ldi		temp1,0x58;x 
	rcall SEND_CHAR
	ldi		temp1,0x41;a 
	rcall SEND_CHAR 
	ldi		temp1,0x20;space
	rcall SEND_CHAR 
	ret

1 Like

Oupsss bravo @dfgh pour le programme.

C'est noté :wink:
J'ai pas oublié le code que vous m'aviez suggéré pour une calculatrice et celui pour les télécommandes SomfyRTS :wink:

Bonne soirée

comprendre l'architecture d'un micro-contrôleur, ce qu'est le "langage machine" (assembleur) et comment ça s'utilise, comprendre comment on appelle une fonction, la notion de pile de registres, etc est utile. On peut aussi s'essayer à écrire un petit compilateur , c'est marrant puis lire sur la théorie de la compilation

une fois que l'on comprend bien tout cela, on comprend mieux ce qu'il se passe au niveau code dans des langages plus évolués.

Tous les langages de programmation sont structurés en fonction du matériel. Moins le langage est évolué et plus il est nécessaire de connaître son fonctionnement pour pouvoir programmer.
Le langage de plus bas niveau, l'assembleur, nécessite une compréhension très élevée !
Le c et le c++ nécessitent des connaissances au niveau matériel moins poussées mais il en faut quand même, il n'y a qu'à lire le tuto sur les pointeurs de @J-M-L pour le constater.

Visual basic par exemple sur lequel j'ai récemment jeté un œil est très évolué et ne nécessite aucune compréhension du matériel à mon sens :wink:
La connaissance du matériel est donc nécessaire pour les langages qui s'en approchent le plus !

L'assembleur n'a rien à voir avec le c ou c++ au niveau langage mais la connaissance du matériel est leur point commun, chacun à leur niveau.

Voilà ce que je comprends mais il est vrai que je ne suis pas très expérimenté et qu'il se fait tard !

Bon j'arrête de vous embêter avec tout ça.

Bonne soirée à tous.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.