Information sur la mémoire du processeur ATmega328 et ses interruptions.

Pour la liste de tous les registres du processeur ATmega328P, voir :
36. Register Summary, page 621 du fichier : ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
Voir aussi AVR Memories page 26 du même fichier.
Cela donne la structure de la mémoire du programme de 0x0000 à 0x0FFF.
Avec le "Boot manager" en fin de plage mémoire.
On voit aussi en page 28 la structure de la RAM ("Data Memory"), avec les 32 premiers registres d'opérations arithmétique et logique", suivit de 64 I/O registres, dont les 32 premiers sont accessibles par certaines instructions assembleur.
On voit que la mémoire RAM des variables commence à l'adresse 0x0100.

Liste des 32 registres d'opérations arithmétique et logique, r0 à r31  

C.f. : "General Purpose Register File", page 20 du document :
ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
C.f. "General Purpose Register File" depuis les documents du site de Microchip : "ATMEGA328PB"
General Purpose Register File :
r0 ; r1 Ces deux registres sont utilisés implicitement dans certaines, intructions assembleurs, telles que : MUL ; MULS ; MULSU ; FMUL ; FMULS ; FMULSU ; DES ; LPM ; ELPM ; SPM
r2 .. r15 De r0 à r15, les accès "immédiats" ne fonctionnent pas. Exemples :
andi ; cpi ; cbr ; ldi ; lds ; ori ; sbci ; sbr ; ser ; subi ;
r24 ; r26 ; r28 ; r30 Sont les seuls disponibles pour l'instruction : ADIW
r16 .. r31 Presque toutes les instructions assembleurs sont possibles, avec l'exception de ADIW. C.f. commentaire précédent.
r26 ; r27 Correspondent à l'adresse mémoire de X , qui permet des accès indirecte à la mémoire.
C'est très utile pour des tableaux.
LD r16, X
LDD r16, X+1
ST X, r16
STD X+1, r16
r28 ; r29 Correspondent à l'adresse mémoire de Y , qui permet des accès indirecte à la mémoire.
C'est très utile pour des tableaux.
LD r16, Y
LDD r16, Y+1
ST Y, r16
STD Y+1, r16
r30 ; r31 Correspondent à l'adresse mémoire de Z , qui permet des accès indirecte à la mémoire.
C'est très utile pour des tableaux.
Exemples :
IJMP.   "Indirect Jump", saute à l'adresse mémoire stockée dans Z.
ICALL.   "Indirect Call".
LD r16, Z
LDD r16, Z+1
ST Z, r16
STD Z+1, r16

Liste des registres I/O d'Entrée/Sortie de 0x00 à 0x1F  

Ils sont accessibles directement avec les instructions : IN ; OUT ; SBI ; CBI ; SBIS et SBIC, qui prennent 1 cycle chacune.
C'est pratique, car ils correspondent aux registres contrôlant les pins d'Entrée/Sortie.
Il faut ajouter 0x20 à leur adresse si on les accèdes comme des adresses mémoire avec les instructions : LDS et STS.
Cela n'a pas d'intérêts, car ces instructions prennent 2 cycles.
La mémoire RAM commence à l'adresse 0x100.
Les adresses qui précèdent correspondent à des registres du processeur.
C.f. : "14.4 Register Description", page 100 du document :
ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
Voir aussi la page 84 : "I/O-Ports" du même document.
C.f. "General Purpose I/O Registers" depuis les documents du site de Microchip : "ATMEGA328PB"
0x00 Reserved
0x01 Reserved
0x02 Reserved
0x03 PINB, correspond à la lecture des PIN 8 à 13 de l'Arduino.
Bit 0 <-> pin 8 ... Bit 5 <-> pin 13
Bit 6 <-> XTAL1 du quartz ... Bit 7 <-> XTAL2 du quartz. Ils ne peuvent pas être utilisés.
0x04 DDRB, correspond à la direction (lecture ou écriture) des PIN 8 à 13 de l'Arduino.
Comme avant, les bits 6 et 7 ne peuvent pas être utilisés.
0x05 PORTB, correspond à l'écriture sur les PIN 8 à 13 de l'Arduino.
Bit 0 <-> pin 8 ... Bit 5 <-> pin 13
Comme avant, les bits 6 et 7 ne peuvent pas être utilisés.
0x06 PINC, correspond à la lecture des PIN 14 à 19 de l'Arduino.
Bit 0 <-> pin 14 ... Bit 5 <-> pin 19
Bit 6 <-> Reset ... Bit 7 <-> Reserved. Ils ne peuvent pas être utilisés.
0x07 DDRC, correspond à la direction (lecture ou écriture) des PIN 14 à 19 de l'Arduino.
En mode lecture, ils peuvent lire les valeurs analogiques A0 à A5, mais pas simultanément.
Comme avant, les bits 6 et 7 ne peuvent pas être utilisés.
0x08 PORTC, correspond à l'écriture sur les PIN 14 à 19 de l'Arduino.
Mis en mode écriture, ces pins A0 à A5 peuvent être utilisées comme des sorties digitales.
Comme avant, les bits 6 et 7 ne peuvent pas être utilisés.
0x09 PIND, correspond à la lecture des PIN 0 à 7 de l'Arduino.
Bit 0 <-> pin 0 ... Bit 7 <-> pin 7
La pin 0 est utilisée comme bit de reception lors de communication série (RXD).
Elle est donc mise en entrée.
La pin 1 est utilisée comme bit d'émission lors de communication série (TXD).
Elle est donc mise en sortie.
0x0A DDRD, correspond à la direction (lecture ou écriture) des PIN 0 à 7 de l'Arduino.
0x0B PORTD, correspond à l'écriture sur les PIN 8 à 13 de l'Arduino.
Bit 0 <-> pin 0 ... Bit 7 <-> pin 7
0x0C .. 0x14 Reserved
0x15 15.9.7 TIFR0 – Timer/Counter 0 Interrupt Flag Register : page 118
0x16 16.11.9 TIFR1 – Timer/Counter1 Interrupt Flag Register : page 145
0x17 18.11.7 TIFR2 – Timer/Counter2 Interrupt Flag Register : page 167
0x18 .. 0x1A Reserved
0x1B 13.2.5 PCIFR – Pin Change Interrupt Flag Register : page 82
0x1C 13.2.3 EIFR – External Interrupt Flag Register : page 81
0x1D 13.2.2 EIMSK – External Interrupt Mask Register : page 81
0x1E 8.6.6 GPIOR0 – General Purpose I/O Register 0 : page 35 et page 30
C'est un registre que l'on peut utiliser comme une mémoire.
Avec l'avantage que son temps d'accès n'est que de 1 cycle
et ce registre est accessible avec les instructions : IN ; OUT ; SBI ; CBI ; SBIS et SBIC
C'est très utile pour manipuler des bits ou stocker des variables booléennes.
Il existe deux autres "General Purpose I/O Register", le GPIOR1 et le GPIOR2.
Ils sont moins utiles, car leur accès prend 2 cycles et ne peuvent pas être accédé par les instructions mentionnées ci-dessus.
0x1F 8.6.3 EECR – The EEPROM Control Register : page 31

Liste des registres de côntrole I/O de 0x20 à 0x3F  

Ils sont accessibles directement par les instructions assembleur : IN et OUT.
Mais PAS par les instructions assembleur : SBI ; CBI ; SBIS et SBIC
Il sont aussi accessibles par LDS ; STS ; LD ; LDD ; ST et STD. Peut-être aussi par LAS ; LAC et LAT, que je n'ai jamais utilisé.
Mais dans ce cas, il faut ajouter 0x20 à leur adresse.
Les instructions LDS ; STS ; ... prennent 2 cycles chacune ou plus.
Les adresses qui précèdent correspondent à des registres du processeur.
C.f. : "8.5 I/O Memory", page 30 du document :
ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
C.f. "I/O Memory" depuis les documents du site de Microchip : "ATMEGA328PB"
0x20 8.6.2 EEDR – The EEPROM Data Register : page 31
0x21 et 0x22 8.6.1 EEARH and EEARL – The EEPROM Address Register : page 31
0x23 18.11.9 GTCCR – General Timer/Counter Control Register : page 168
0x24 15.9.1 TCCR0A – Timer/Counter Control Register A : page 113
0x25 15.9.2 TCCR0B – Timer/Counter Control Register B : page 116
0x26 15.9.3 TCNT0 – Timer/Counter Register : page 117
0x27 15.9.4 OCR0A – Output Compare Register A : page 117
0x28 15.9.5 OCR0B – Output Compare Register B : page 117
0x29 Reserved
0x2A et 0x2B 8.6.5 GPIOR1 – General Purpose I/O Register 1 et
8.6.4 GPIOR2 – General Purpose I/O Register 2, page 35
Ce sont deux registres qui peuvent être utilisés comme des mémoires, à la place d'utiliser deux cases mémoires de RAM.
0x2C 19.5.1 SPCR – SPI Control Register : page 176
0x2D 19.5.2 SPSR – SPI Status Register : page 177
0x2E 19.5.3 SPDR – SPI Data Register : page 178
0x2F Reserved
0x30 23.3.2 ACSR – Analog Comparator Control and Status Register : page 244
0x31 et 0x32 Reserved
0x33 10.11.1 SMCR – Sleep Mode Control Register : page 53
0x34 11.9.1 MCUSR – MCU Status Register : page 63
Est lié au "11.8 Watchdog Timer", page 60
MCU == "MicroController Unit"
0x35 10.11.2 MCUCR – MCU Control Register : page 54
Est lié au "10. Power Management and Sleep Modes" : page 48
MCU == "MicroController Unit"
0x36 Reserved
0x37 27.9.1 SPMCSR – Store Program Memory Control and Status Register : page 287
0x38 .. 0x3C Reserved
0x3D : 0x3E 7.5.1 SPH and SPL – Stack Pointer High and Stack Pointer Low Register : page 22
C.f. : "7.5 Stack Pointer"
0x3F 7.3.1 SREG – AVR Status Register : page 19
C'est le registre des Flags, I, T, H, S, V, N, Z, C
Ces Flags sont modifiés par la plupart des instructions assembleurs et testables par plusieurs instructions pour faire des sauts conditionnels.

Liste d'adresses des registres de contrôles de 0x60 à 0xFF, non accessibles par OUT et IN  

Les registres qui suivent NE sont PAS accessibles par les instructions assembleur : IN et OUT.
Ils sont accessibles par les instructions : LDS ; STS ; LD ; LDD ; ST et STD. Peut-être aussi par LAS ; LAC et LAT, que je n'ai jamais utilisé.
Donc 0x20 a été additionné à leurs adresses, puisque c'est ce qu'il faut faire lorsqu'on utilise les instructions assembleur ci-dessus.
Ce qui fait qu'on ne liste aucune adresse entre 0x40 et 0x5F, qui correspondent aux adresses 0x20 à 0x3F accédés par les instructions LDS ; STS et suivantes.
C.f. : "8.5 I/O Memory", page 30 du document :
ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
C.f. "I/O Memory" depuis les documents du site de Microchip : "ATMEGA328PB"
0x60 11.9.2 WDTCSR – Watchdog Timer Control Register : page 63
0x61 9.12.2 CLKPR – Clock Prescale Register : page 46
0x62 et 0x63 Reserved
0x64 10.11.3 PRR – Power Reduction Register : page 54
0x67 Reserved
0x66 9.12.1 OSCCAL – Oscillator Calibration Register : page 46
0x67 Reserved
0x68 13.2.4 PCICR – Pin Change Interrupt Control Register : page 82
0x69 13.2.1 EICRA – External Interrupt Control Register A : page 80
0x6A Reserved
0x6B .. 0x6D 13.2.8 PCMSK0 – Pin Change Mask Register 0 : page 83
13.2.7 PCMSK1 – Pin Change Mask Register 1
13.2.6 PCMSK2 – Pin Change Mask Register 2
0x6E 15.9.6 TIMSK0 – Timer/Counter Interrupt Mask Register : page 118
0x6F 16.11.8 TIMSK1 – Timer/Counter1 Interrupt Mask Register : page 144
0x70 18.11.6 TIMSK2 – Timer/Counter2 Interrupt Mask Register : page 166
0x71 .. 0x77 Reserved
0x78 et 0x79 24.9.3 ADCL and ADCH – The ADC Data Register : page 259
0x7A et 0x7B 24.9.2 ADCSRA – ADC Control and Status Register A : page 258
24.9.4 ADCSRB – ADC Control and Status Register B : page 260
0x7C ADMUX
0x7D Reserved
0x7E et 0x7F 24.9.5 DIDR0 – Digital Input Disable Register 0 : page 260
23.3.3 DIDR1 – Digital Input Disable Register 1
0x80 16.11.1 TCCR1A – Timer/Counter1 Control Register A : page 140
0x81 16.11.2 TCCR1B – Timer/Counter1 Control Register B : page 142
0x82 16.11.3 TCCR1C – Timer/Counter1 Control Register C : page 143
0x83 Reserved
0x84 : 0x85 16.11.4 TCNT1L et TCNT1H – Timer/Counter1 : page 143
0x86 : 0x87 16.11.7 ICR1L et ICR1H – Input Capture Register 1 : page 144
0x88 : 0x89 16.11.5 OCR1AL et OCR1AH – Output Compare Register 1 A : page 144
0x8A : 0x8B 16.11.6 OCR1BL et OCR1BH – Output Compare Register 1 B : page 144
0x8C .. 0xAF Reserved
0xB0 18.11.1 TCCR2A – Timer/Counter Control Register A : page 162
0xB1 18.11.2 TCCR2B – Timer/Counter Control Register B : page 165
0xB2 18.11.3 TCNT2 – Timer/Counter Register : page 166
0xB3 18.11.4 OCR2A – Output Compare Register A : page 166
0xB4 18.11.5 OCR2B – Output Compare Register B : page 166
0xB5 Reserved
0xB6 18.11.8 ASSR – Asynchronous Status Register : page 167
0xB7 Reserved
0xB8 .. 0xBD De : 22. 2-wire Serial Interface : page 215
22.9.1 TWBR – TWI Bit Rate Register : 0xB8, page 239
22.9.3 TWSR – TWI Status Register : 0xB9, page 239
22.9.5 TWAR – TWI (Slave) Address Register : 0xBA, page 241
22.9.4 TWDR – TWI Data Register : 0xBB, page 241
22.9.2 TWCR – TWI Control Register : 0xBC, page 239
22.9.6 TWAMR – TWI (Slave) Address Mask Register : 0xBD, page 239
0xBE : 0xBF Reserved
0xC0 .. 0xC2 De : 20. USART0 : page 279
"Universal Synchronous and Asynchronous serial Receiver and Transmitter"
UCSR0A ; UCSR0B ; UCSR0C
0xC3 Reserved
0xC4 : 0xC5 De : 20. USART0 : page 279
"Universal Synchronous and Asynchronous serial Receiver and Transmitter"
UBRR0L et UBRR0H
0xC6 De : 20. USART0 : page 279
"Universal Synchronous and Asynchronous serial Receiver and Transmitter"
UDR0
0xC7 .. 0xFF Reserved



La référence principale que j'ai utilisé : ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
7. AVR CPU Core : page18
7.3 SREG – AVR Status Register : page 20
7.4 AVR CPU General Purpose Working Registers : page 21
7.7.1.Interrupt Response Time" : page 25
Il est indiqué que 4 cycles sont pris pour stocker sur la pile l'adresse de retour d'interruption et entrer dans la routine de gestion d'interruption.
3 cycles supplémentaires sont pris pour exécuter le JMP à l'adresse de la routine d'interruption.
Ce "JMP" se trouve en début des adresses mémoire du programme.
Le premier JMP, à l'adresse 0x0000 est celui du reset.
Il correspond au saut au début du programme.
8. AVR Memories (donne le Program Memory Map") : page 26
8.3 SRAM Data Memory (done la structure de la RAM et des registres) : page 28
9. System Clock and Clock Options : page 36
10. Power Management and Sleep Modes : page 48
11. System Control and Reset : page 56
12.4 Interrupt Vectors in ATmega328 and ATmega328P : page 74
Les "Program Address" doivent être multipliés par 2, pour avoir l'adresse mémoire du programme, car le "Program Counter" est un word de 2 octets.
13. External Interrupts : page 79
14. I/O-Ports : page 84
14.4 Register Description : page 100
15. 8-bit Timer/Counter0 with PWM : page 102
16. 16-bit Timer/Counter1 with PWM : page 120
17. Timer/Counter0 and Timer/Counter1 Prescalers : page 147
18. 8-bit Timer/Counter2 with PWM and Asynchronous Operation : page 150
19. SPI – Serial Peripheral Interface : page 169
20. USART0 : page 179
21. USART in SPI Mode : page 205
22. 2-wire Serial Interface : page 215
23. Analog Comparator : page 243
24. Analog-to-Digital Converter : page 246
27. Boot Loader Support – Read-While-Write Self-Programming : page 272
28. Memory Programming : page 289
"36. Register Summary", page 621 donne la liste de tous les registres du processeur ATmega328P.
"37 : Instruction Set Summary", page 625 donne la liste des instructions assembleurs.
Je lui préfère le document plus complets sur l'assembleur : Atmel AVR 8-bit Instruction Set
Toutes les instructions de l'Assembleur, bien présenté. Document de 152 pages.
Les pages : "Complete Instruction Set Summary" 11 à 14 sont très utiles.

Les instructions OUT et IN peuvent s'utiliser sur des registres de 0x03 à 0x3f
L'avantage de "OUT" et "IN" sur "LDS" et "STS" est qu'ils ne prennent qu'un cycle, contre deux pour "LDS" et "STS".
Il y a équivalence entre les 4 instructions suivantes, mais les deux premières prennent 1 cycle, les deux dernière 2 cycles :
out r16, PINB
out r16, 0x03
lds r16, PINB
lds r16, 0x23

La playlist de vidéos de Anas Kuzechie donne des informations sur la structure de la mémoire et sur la programmation en assembleur.
Elles sont en anglais.
C'est plus joli que ce que je présente, mais a deux "défauts" :
1) Les exemples sont académiques, l'assembleur n'est pas nécessaire pour obtenir les effets obtenus.
2) Sa partie sur les "Timers" est inutile, car ils sont utilisés sans routine de gestions d'interruption.
Malgré cela, on apprends beaucoup de choses en les regardant.

Autres informations en vrac :
Dans la référence :
8-bit AVR Microcontroller with 32K Bytes In-System Programmable Flash
On trouve des informations similaires à celles données dans la référence précédente, qui est plus complète.
Voici quelques pages intéressantes :
"30. Register Summary", page 275
"31. Instruction Set Summary", page 281
Page 49, on a : "Reset and Interrupt Vectors in ATmega328P"

Manipulations de bits :
COM Rd     <=>  Rd = $ff - Rd    One's complement    change tous les bits en leur négation  0 <-> 1
NEG Rd     <=>  Rd = $00 - Rd    Two’s Complement    change entre négatif et positif.
CBI A, b   <=>  Met à 0 le bit  b  du  I/O registre  A. A dans [0 ; 31].   Clear Bit in I/O Register
SBI A, b   <=>  Met à 1 le bit  b  du  I/O registre  A. A dans [0 ; 31].   Set   Bit in I/O Register
SBR Rd, K  <=>  Rd = Rd ou K    Met à 1 des bits du registre Rd.  K=0..0xff   Set Bit(s) in Register
CBR Rd, K  <=>  Rd = Rd et K    Met à 0 des bits du registre Rd.  K=0..0xff   Clear Bit(s) in Register
SBRC Rr, b <=>  Saute l'instruction suivante si le bit  b  du registre  Rr est à 0.   Skip if Bit in Register Cleared
SBRS Rr, b <=>  Saute l'instruction suivante si le bit  b  du registre  Rr est à 1.   Skip if Bit in Register Set
           1 cycle  s'il n'y a pas de saut
           2 cycles s'il y a saut et l'instruction suivante est codée sur un word
           3 cycles s'il y a saut et l'instruction suivante est codée sur deux words

out A, Rr   0 ≤ r ≤ 31  et  0 ≤ A ≤ 63
Stores data from register Rr in the Register File to I/O Space (Ports, Timers, Configuration Registers, etc.).
1 cycles

sts k, Rr    0 ≤ r ≤ 31  et  0 ≤ A ≤ 65535
Stores one byte from a Register to the data space
2 cycles

sts PORTD, r24   est une instruction valide, 
mais elle prend un cycle de plus que l'instruction suivante qui a le même effet
out PORTD, r24


Home arrow arduino_minuteur_assembleur_synchronisation.html arrow memoire_interrupt_info.html
Mise à jour le 19 janvier 2025 par Libre Gisin.