Programmation Arduino

Attention, c'est du lourd, de la programmation assembleur ASM AVR, je suis FAN.

Programmation Arduino


L'Arduino Nano
Micro-contrôleurAtmel ATmega328
Tension de fonctionnement (niveau logique)5 V
Tension d’alimentation (recommandée)7-12 V
Tension d’alimentation (maximum)6-20 V
E/S digitales14 (dont 6 peuvent fournir une sortie PWM, notées par un trait blanc)
E/S analogiques8
Courant disponible par pin E/S40 mA
Mémoire flash32 KB (dont 2KB utilisés par le bootloader)
SRAM2 KB
EEPROM1 KB
Vitesse d’horloge16 MHz
Dimensions44mm x 18mm

Les registres
Regadr.Commentaire Regadr.Commentairedef.Utilisation
r00x00Pas de
valeurs
immédiates
 r160x10Permet les
valeurs
immédiates
A Général
r10x01 r170x11B Général
r20x02 r180x12 
r30x03 r190x13ADR Adresse I²C
r40x04 r200x14DATA Données
r50x05 r210x15 
r60x06 r220x16 
r70x07 r230x17 
r80x08 r240x18 
r90x09 r250x19 
r100x0A r260x1AXLXH:XL
Compteur
r110x0B r270x1BXH 
r120x0C r280x1CYLYH:YLEEPROM
r130x0D r290x1DYH 
r140x0E r300x1EZLZH:ZL 
r150x0F r310x1FXH 

Des registres spécifiques pour l'adressage indirect : X, Y, Z

X=R27:R26, Y=R29:R28 et Z=R31:R30)
3 pointeurs 16 bits X, Y et Z mappés sur les registres 8 bits r26 à r31 (X=r27:r26, Y=r29:r28 et Z=r31:r30)
Les registres d'entrées/sorties
Adr.NomBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
(0xFF)Reserved
(0xFE)Reserved
(0xFD)Reserved
(0xFC)Reserved
(0xFB)Reserved
(0xFA)Reserved
(0xF9)Reserved
(0xF8)Reserved
(0xF7)Reserved
(0xF6)Reserved
(0xF5)Reserved
(0xF4)Reserved
(0xF3)Reserved
(0xF2)Reserved
(0xF1)Reserved
(0xF0)Reserved
(0xEF)Reserved
(0xEE)Reserved
(0xED)Reserved
(0xEC)Reserved
(0xEB)Reserved
(0xEA)Reserved
(0xE9)Reserved
(0xE8)Reserved
(0xE7)Reserved
(0xE6)Reserved
(0xE5)Reserved
(0xE4)Reserved
(0xE3)Reserved
(0xE2)Reserved
(0xE1)Reserved
(0xE0)Reserved
(0xDF)Reserved
(0xDE)Reserved
(0xDD)Reserved
(0xDC)Reserved
(0xDB)Reserved
(0xDA)Reserved
(0xD9)Reserved
(0xD8)Reserved
(0xD7)Reserved
(0xD6)Reserved
(0xD5)Reserved
(0xD4)Reserved
(0xD3)Reserved
(0xD2)Reserved
(0xD1)Reserved
(0xD0)Reserved
(0xCF)Reserved
(0xCE)Reserved
(0xCD)Reserved
(0xCC)Reserved
(0xCB)Reserved
(0xCA)Reserved
(0xC9)Reserved
(0xC8)Reserved
(0xC7)Reserved
(0xC6)UDR0USART I/O Data Register
(0xC5)UBRR0HUSART Baud Rate Register High
(0xC4)UBRR0LUSART Baud Rate Register Low
(0xC3)Reserved
(0xC2)UCSR0CUMSEL01UMSEL00UPM01UPM00USBS0UCSZ01/UDORD0UCSZ00/UCPHA0UCPOL0
(0xC1)UCSR0BRXCIE0TXCIE0UDRIE0RXEN0TXEN0UCSZ02RXB80TXB80
(0xC0)UCSR0ARXC0TXC0UDRE0FE0DOR0UPE0U2X0MPCM0
(0xBF)Reserved
(0xBE)Reserved
(0xBD)TWAMRTWAM6TWAM5TWAM4TWAM3TWAM2TWAM1TWAM0–233
(0xBC)TWCRTWINTTWEATWSTATWSTOTWWCTWENTWIE
(0xBB)TWDR2-wire Serial Interface Data Register
(0xBA)TWARTWA6TWA5TWA4TWA3TWA2TWA1TWA0TWGCE
(0xB9)TWSRTWS7TWS6TWS5TWS4TWS3TWPS1TWPS0
0xB8)TWBR 2-wire Serial Interface Bit Rate Register
(0xB7)Reserved
(0xB6)ASSREXCLKAS2TCN2UBOCR2AUBOCR2BUBTCR2AUBTCR2BUB
(0xB5)Reserved
(0xB4)OCR2BTimer/Counter2 Output Compare Register B
(0xB3)OCR2ATimer/Counter2 Output Compare Register A
(0xB2)TCNT2Timer/Counter2 (8-bit)
(0xB1)TCCR2BFOC2AFOC2BWGM22CS22CS21CS20
(0xB0)TCCR2ACOM2A1COM2A0COM2B1COM2B0WGM21WGM20
(0xAF)Reserved
(0xAE)Reserved
(0xAD)Reserved
(0xAC)Reserved
(0xAB)Reserved
(0xAA)Reserved
(0xA9)Reserved
(0xA8)Reserved
(0xA7)Reserved
(0xA6)Reserved
(0xA5)Reserved
(0xA4)Reserved
(0xA3)Reserved
(0xA2)Reserved
(0xA1)Reserved
(0xA0)Reserved
(0x9F)Reserved
(0x9E)Reserved
(0x9D)Reserved
(0x9C)Reserved
(0x9B)Reserved
(0x9A)Reserved
(0x99)Reserved
(0x98)Reserved
(0x97)Reserved
(0x96)Reserved
(0x95)Reserved
(0x94)Reserved
(0x93)Reserved
(0x92)Reserved
(0x91)Reserved
(0x90)Reserved
(0x8F)Reserved
(0x8E)Reserved
(0x8D)Reserved
(0x8C)Reserved
(0x8B)OCR1BHTimer/Counter1 - Output Compare Register B High Byte
(0x8A)OCR1BLTimer/Counter1 - Output Compare Register B Low Byte
(0x89)OCR1AHTimer/Counter1 - Output Compare Register A High Byte
(0x88)OCR1ALTimer/Counter1 - Output Compare Register A Low Byte
(0x87)ICR1HTimer/Counter1 - Input Capture Register High Byte
(0x86)ICR1LTimer/Counter1 - Input Capture Register Low Byte
(0x85)TCNT1HTimer/Counter1 - Counter Register High Byte
(0x84)TCNT1LTimer/Counter1 - Counter Register Low Byte
(0x83)Reserved
(0x82)TCCR1CFOC1AFOC1B–134
(0x81)TCCR1BICNC1ICES1WGM13WGM12CS12CS11CS10
(0x80)TCCR1ACOM1A1COM1A0COM1B1COM1B0WGM11WGM10
(0x7F)DIDR1AIN1DAIN0D
(0x7E)DIDR0ADC5DADC4DADC3DADC2DADC1DADC0D
(0x7D)Reserved
(0x7C)ADMUXREFS1REFS0ADLARMUX3MUX2MUX1MUX0
(0x7B)ADCSRB–ACMEADTS2ADTS1ADTS0251
(0x7A)ADCSRAADENADSCADATEADIFADIEADPS2ADPS1ADPS0
(0x79)ADCHADC Data Register High byte
(0x78)ADCLADC Data Register Low byte
(0x77)Reserved
(0x76)Reserved
(0x75)Reserved
(0x74)Reserved
(0x73)Reserved
(0x72)Reserved
(0x71)Reserved
(0x70)TIMSK2OCIE2BOCIE2ATOIE2
(0x6F)TIMSK1–ICIE1OCIE1BOCIE1ATOIE1135
(0x6E)TIMSK0OCIE0BOCIE0ATOIE0
(0x6D)PCMSK2PCINT23PCINT22PCINT21PCINT20PCINT19PCINT18PCINT17PCINT16
(0x6C)PCMSK1PCINT14PCINT13PCINT12PCINT11PCINT10PCINT9PCINT8
(0x6B)PCMSK0PCINT7PCINT6PCINT5PCINT4PCINT3PCINT2PCINT1PCINT0
(0x6A)Reserved
(0x69)EICRAISC11ISC10ISC01ISC00
(0x68)PCICRPCIE2PCIE1PCIE0
(0x67)Reserved
(0x66)OSCCALOscillator Calibration Register
(0x65)Reserved
(0x64)PRRPRTWIPRTIM2PRTIM0PRTIM1PRSPIPRUSART0PRADC
(0x63)Reserved
(0x62)Reserved
(0x61)CLKPRCLKPCECLKPS3CLKPS2CLKPS1CLKPS0
(0x60)WDTCSRWDIFWDIEWDP3WDCEWDEWDP2WDP1WDP0
0x3F (0x5F)SREGITHSVNZC
0x3E (0x5E)SPH–(SP10) 5.SP9SP8
0x3D (0x5D)SPLSP7SP6SP5SP4SP3SP2SP1SP0
0x3C (0x5C)Reserved
0x3B (0x5B)Reserved
0x3A (0x5A)Reserved
0x39 (0x59)Reserved
0x38 (0x58)Reserved
0x37 (0x57)SPMCSRSPMIE(RWWSB)SIGRD(RWWSRE)BLBSETPGWRTPGERSSPMEN
0x36 (0x56)Reserved
0x35 (0x55)MCUCR-BODSBODSEPUDIVSELIVCE
0x34 (0x54)MCUSRWDRFBORFEXTRFPORF
0x33 (0x53)SMCRSM2SM1SM0SE
0x32 (0x52)Reserved
0x31 (0x51)Reserved
0x30 (0x50)ACSRACDACBGACOACIACIEACICACIS1ACIS0
0x2F (0x4F)Reserved
0x2E (0x4E)SPDR SPI Data Register
0x2D (0x4D)SPSRSPIFWCOLSPI2X
0x2C (0x4C)SPCRSPIESPEDORDMSTRCPOLCPHASPR1SPR0
0x2B (0x4B)GPIOR2General Purpose I/O Register 2
0x2A (0x4A)GPIOR1General Purpose I/O Register 1
0x29 (0x49)Reserved
0x28 (0x48)OCR0BTimer/Counter0 Output Compare Register B
0x27 (0x47)OCR0ATimer/Counter0 Output Compare Register A
0x26 (0x46)TCNT0Timer/Counter0 (8-bit)
0x25 (0x45)TCCR0BFOC0AFOC0BWGM02CS02CS01CS00
0x24 (0x44)TCCR0ACOM0A1COM0A0COM0B1COM0B0WGM01WGM00
0x23 (0x43)GTCCRTSMPSRASYPSRSYNC
0x22 (0x42)EEARH(EEPROM Address Register High Byte)
0x21 (0x41)EEARLEEPROM Address Register Low Byte
0x20 (0x40)EEDREEPROM Data Register
0x1F (0x3F)EECREEPM1EEPM0EERIEEEMPEEEPEEERE
0x1E (0x3E)GPIOR0General Purpose I/O Register 0
0x1D (0x3D)EIMSKINT1INT0
0x1C (0x3C)EIFRINTF1INTF0
0x1B (0x3B)PCIFRPCIF2PCIF1PCIF0
0x1A (0x3A)Reserved
0x19 (0x39)Reserved
0x18 (0x38)Reserved
0x17 (0x37)TIFR2OCF2BOCF2ATOV2
0x16 (0x36)TIFR1–ICF1OCF1BOCF1ATOV1
0x15 (0x35)TIFR0OCF0BOCF0ATOV0
0x14 (0x34)Reserved
0x13 (0x33)Reserved
0x12 (0x32)Reserved
0x11 (0x31)Reserved
0x10 (0x30)Reserved
0x0F (0x2F)Reserved
0x0E (0x2E)Reserved
0x0D (0x2D)Reserved
0x0C (0x2C)Reserved
0x0B (0x2B)PORTDPORTD7PORTD6PORTD5PORTD4PORTD3PORTD2PORTD1PORTD0
0x0A (0x2A)DDRDDDD7DDD6DDD5DDD4DDD3DDD2DDD1DDD0
0x09 (0x29)PINDPIND7PIND6PIND5PIND4PIND3PIND2PIND1PIND0
0x08 (0x28)PORTCPORTC6PORTC5PORTC4PORTC3PORTC2PORTC1PORTC0
0x07 (0x27)DDRCDDC6DDC5DDC4DDC3DDC2DDC1DDC0
0x06 (0x26)PINCPINC6PINC5PINC4PINC3PINC2PINC1PINC0
0x05 (0x25)PORTBPORTB7PORTB6PORTB5PORTB4PORTB3PORTB2PORTB1PORTB0
0x04 (0x24)DDRBDDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB0
0x03 (0x23)PINBPINB7PINB6PINB5PINB4PINB3PINB2PINB1PINB0
0x02 (0x22)Reserved
0x01 (0x21)Reserved
0x00 (0x20)Reserved


Les ports B/C/D

Port B

MCUCR - Registre de contrôle MCU
bit76543210
0x35 (0x55)-BODSBODSEPUDIVSELIVCE
Read/WriteRR/WR/WR/WRRR/WR/W
Initial Value00000000

Bit 6 - PUD: Désactivation du pull-up
Lorsque ce bit est écrit à un, les "pull-ups" dans les ports d'E / S sont désactivés même si les registres DDxn et PORTxn sont configurés pour activer les "pull-ups" {DDxn, PORTxn} = 0b01.

DDRB : le registre «directions» du port B
Bit76543210
0x04 (0x24)DDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

Chaque broche de port se compose de trois bits de registre: DDxn, PORTxn et PINxn.
L'écriture d'une logique à PINxn bascule la valeur de PORTxn, indépendamment de la valeur de DDRxn.
Notons que l'instruction SBI peut être utilisé pour basculer un seul bit dans un port.

Configuration des ports
DDxnPORTxnPUD
MCUCR
I/OPull-upCommentaire
00XInputNoTri-state (Haute impédance)
010InputYesPxn will source current if ext. pulled low.
011InputNoTri-state (Haute impédance)
10XOutputNoOutput Low (Sink)
11XOutputNoOutput High (Source)

Le registre DDRB indique les directions (entrée ou sortie) de chaque broche.
La valeur 1 correspond donc à une utilisation en sortie et 0 en entrée (Par défaut).
Exemple : La broche 0 du port B en sortie :
DDRB = (1<<DDB0);

PORTB : le registre «sortie» du port B
Bit76543210
0x05(0x25)PORTB5PORTB6PORTB5PORTB4PORTB3PORTB2PORTB1PORTB0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

Attribuer la valeur souhaitée à la broche en utilisant ce registre. Exemple en C:
PORTB |= (1<<PORTB0);

Ou encore en assembleur :
	.equ  	SENSELED=PB1   ;  SENSELED pin (Output on AVR)
	sbi		DDRB,SENSELED	;Pour PB1 en sortie

	sbi   	PORTB,SENSELED	;Allumage LED, set bit 
	
	cbi   	PORTB,SENSELED	;Extinction LED, clear bit
Lire la valeur du port B
bool a;
a= (1<<PINB1);
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<<PB4)|(1<<PB1)|(1<<PB0)
ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0)
out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB

Port C

PINC : le registre «entrée» du port C
Bit76543210
0x06 (0x26)-PINC6PINC5PINC4PINC3PINC2PINC1PINC0
Read/WriteRR/WR/WR/WR/WR/WR/WR/W
Initial Value0N/AN/AN/AN/AN/AN/AN/A


DDRC : le registre «directions» du port C
Bit76543210
0x07 (0x27)-DDC6DDC5DDC4DDC3DDC2DDC1DDC0
Read/WriteRR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

PORTC : le registre «sortie» du port C
Bit76543210
0x08(0x28)-PORTC6PORTC5PORTC4PORTC3PORTC2PORTC1PORTC0
Read/WriteRR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

Port D

PIND : le registre «entrée» du port D
Bit76543210
0x06 (0x26)PIND7PIND6PIND5PIND4PIND3PIND2PIND1PIND0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial ValueN/AN/AN/AN/AN/AN/AN/AN/A


DDRD : le registre «directions» du port D
Bit76543210
0x07 (0x27)DDD7DDD6DDD5DDD4DDD3DDD2DDD1DDD0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

PORTD : le registre «sortie» du port D
Bit76543210
0x08(0x28)PORTD5PORTD6PORTD5PORTD4PORTD3PORTD2PORTD1PORTD0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

Les ports ADC L'ATtiny 25/45/85 dispose d'un convertisseur analogique-numérique (ADC) d'approximation successive de 10 bits.

Utilisation

La valeur minimale représente GND et la valeur maximale représente la tension sur VCC, la tension sur la broche AREF ou une référence de tension interne de 1,1V / 2,56V.
La référence de tension pour le CAN peut être sélectionnée en écrivant dans les bits REFS [2: 0] dans ADMUX.
L'alimentation VCC, la broche AREF ou une référence de tension interne de 1,1 V / 2,56V peuvent être sélectionnées comme référence de tension ADC.
En option, la référence de tension interne 2,56V peut être découplée par un condensateur externe sur la broche AREF pour améliorer l'immunité au bruit.

Le canal d'entrée analogique et le gain différentiel sont sélectionnés en écriture sur les bits MUX [3: 0] dans ADMUX.
L'une des quatre broches d'entrée ADC ADC [3: 0] peut être sélectionnée en tant qu'entrée unique à l'ADC.
ADC2 ou ADC0 peut être sélectionné comme entrée positive et ADC0, ADC1, ADC2 ou ADC3 peuvent être sélectionnés comme entrée négative à l'amplificateur à gain différentiel.

Si des canaux différentiels sont sélectionnés, l'étage de gain différentiel amplifie la différence de tension entre la paire d'entrée sélectionnée par le facteur de gain choisi, 1x ou 20x, en fonction du réglage des bits MUX [3: 0] dans ADMUX.
Cette valeur amplifiée devient alors l'entrée analogique de l'ADC. Si des canaux à une extrémité sont utilisés, l'amplificateur de gain est entièrement contourné.

Si ADC0 ou ADC2 est sélectionné à la fois comme entrée positive et négative pour l'amplificateur de gain différentiel (ADC0-ADC0 ou ADC2-ADC2), le décalage restant dans l'étage de gain et le circuit de conversion peuvent être mesurés directement à la suite de la conversion.
Ce chiffre peut être soustrait des conversions ultérieures avec le même gain pour réduire l'erreur de décalage en dessous de 1 LSW.
Le capteur de température sur puce est sélectionné en écrivant le code "1111" sur les bits MUX [3: 0] dans le registre ADMUX lorsque le canal ADC4 est utilisé comme entrée ADC.

L'ADC est activé en réglant le bit ADC Enable, ADEN dans ADCSRA.
La sélection de la référence de tension et des canaux d'entrée n'entrera en vigueur qu'après avoir réglé ADEN.

L'ADC ne consomme pas de courant lorsque ADEN est effacé, il est donc conseillé d'éteindre l'ADC avant d'entrer en mode d'économie d'énergie.

L'ADC génère un résultat de 10 bits qui est présenté dans les registres de données ADC, ADCH et ADCL.
Par défaut, le résultat est présenté à droite ajusté, mais peut éventuellement être présenté à gauche ajusté en réglant le bit ADLAR dans ADMUX.
Si le résultat est ajusté à la gauche et que la précision n'est pas supérieure à 8 bits, il suffit de lire ADCH.
Sinon, ADCL doit être lu en premier, puis ADCH, pour s'assurer que le contenu des registres de données appartient à la même conversion.
Une fois que ADCL est lu, l'accès ADC aux registres de données est bloqué.
Cela signifie que si ADCL a été lu et une conversion est terminée avant que ADCH est lu, aucun registre n'est mis à jour et le résultat de la conversion est perdu.
Lorsque ADCH est lu, l'accès ADC aux Registres ADCH et ADCL est réactivé.
L'ADC a sa propre interruption qui peut être déclenchée quand une conversion est terminée.
Lorsque l'accès ADC aux registres de données est interdit entre la lecture de ADCH et ADCL, l'interruption se déclenchera même si le résultat est perdu.


Démarrer une conversion

Une seule conversion est lancée en écrivant une commande logique dans le bit de conversion ADC Start, ADSC.
Ce bit reste élevé tant que la conversion est en cours et sera effacé par le matériel lorsque la conversion est terminée.
Si un canal de données différent est sélectionné pendant qu'une conversion est en cours, l'ADC terminera la conversion en cours avant d'effectuer le changement de canal.

Alternativement, une conversion peut être déclenchée automatiquement par diverses sources.
Le déclenchement automatique est activé en réglant le bit d'activation du déclenchement automatique ADC, ADATE dans ADCSRA.
La source de déclenchement est sélectionnée en réglant les bits de sélection de déclenchement ADC, ADTS dans ADCSRB (voir la description des bits ADTS pour une liste des sources de déclenchement).
Lorsqu'un bord positif se produit sur le signal de déclenchement sélectionné, le prédéterminateur ADC est réinitialisé et une conversion est lancée.
Cela fournit une méthode de démarrage de conversions à intervalles fixes.
Si le signal de déclenchement est toujours défini lorsque la conversion est terminée, une nouvelle conversion ne sera pas lancée.
Si un autre front positif se produit sur le signal de déclenchement pendant la conversion, le bord sera ignoré.
Notez qu'un drapeau d'interruption sera défini même si l'interruption spécifique est désactivée ou si l'interruption global bit d'activation dans SREG est effacé.
Une conversion peut donc être déclenchée sans provoquer une interruption.
Toutefois, le drapeau d'interruption doit être effacé afin de déclencher une nouvelle conversion à l'événement d'interruption suivant.
L'utilisation du drapeau d'interruption ADC comme source de déclenchement permet au ADC de démarrer une nouvelle conversion dès que la conversion est terminée.
L'ADC fonctionne ensuite en mode Free Running, échantillonnage et mise à jour en permanence du registre de données ADC.
La première conversion doit être démarrée en écrivant un bit logique dans le bit ADSC dans ADCSRA.
Dans ce mode, l'ADC exécutera des conversions successives indépendamment du fait que le ADC Interrupt Flag, ADIF soit effacé ou non.

Si Déclenchement automatique est activé, les conversions simples peuvent être démarrées en écrivant ADSC dans ADCSRA à un.
ADSC peut également être utilisé pour déterminer si une conversion est en cours.
Le bit ADSC sera lu en tant qu'un lors d'une conversion, indépendamment de la façon dont la conversion a été lancée.

Prescaling and Conversion Timing

Par défaut, les circuits d'approximation successifs nécessitent une fréquence d'horloge d'entrée comprise entre 50 kHz et 200 kHz pour obtenir une résolution maximale.
Si une résolution inférieure à 10 bits est nécessaire, la fréquence d'horloge d'entrée à l'ADC peut être supérieure à 200 kHz pour obtenir une fréquence d'échantillonnage plus élevée.
Il n'est pas recommandé d'utiliser une fréquence d'horloge d'entrée supérieure à 1 MHz.
Le module ADC contient un prescaler, qui génère une fréquence d'horloge ADC acceptable à partir de n'importe quelle fréquence CPU supérieure à 100 kHz.
Le préréglage est réglé par les bits ADPS dans ADCSRA. Le prescaler commence à compter à partir du moment où l'ADC est activé en réglant le bit ADEN dans ADCSRA.
Le prescaler continue à fonctionner tant que le bit ADEN est réglé et est constamment réinitialisé lorsque ADEN est faible.
Lors de l'initialisation d'une conversion à une seule extrémité en réglant le bit ADSC dans ADCSRA, la conversion commence au niveau du front montant suivant du cycle d'horloge ADC.


Une conversion normale prend 13 cycles d'horloge ADC. La première conversion après l'enclenchement du ADC (ADEN dans ADCSRA est réglé) prend 25 cycles d'horloge ADC pour initialiser le circuit analogique.

ADC First Conversion (Single Conversion Mode)

L'échantillonnage et la saisie réels ont lieu pendant 1,5 cycles d'horloge ADC après le début d'une conversion normale et 13,5 cycles d'horloge ADC après le début d'une première conversion.
Lorsqu'une conversion est terminée, le résultat est écrit dans les registres de données ADC et ADIF est défini.
En mode Conversion simple, ADSC est effacé simultanément. Le logiciel peut alors rétablir ADSC et une nouvelle conversion sera déclenchée sur le premier front montant de l'horloge ADC.


ADC Single Conversion

Lorsque le déclenchement automatique est utilisé, le prescaler est réinitialisé lorsque l'événement déclencheur se produit.
Cela garantit un délai fixe de l'événement déclencheur au début de la conversion.
Dans ce mode, l'échantillonnage et le maintien effectuent deux cycles d'horloge ADC après le front montant sur le signal de source de déclenchement.
Trois cycles d 'horloge CPU supplémentaires sont utilisés pour la logique de synchronisation.

ADC Auto Triggered Conversion

En mode exécution libre, une nouvelle conversion sera lancée immédiatement après la conversion, tandis que ADSC reste élevé.

Temps de conversion ADC
ConditionÉchantillon et maintien
(Cycles à partir du début de la conversion)
Temps total de conversion (Cycles)
Première conversion13,525
Conversions normales1,513
Conversions déclenchées automatiquement213,5

Registre ADC


ADCSRA – ADC Control and Status Register A
Bit76543210
0x06ADENADSCADATEADIFADIEADPS2ADPS1ADPS0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000


ADCSRB – ADC Control and Status Register B
Bit76543210
0x03BINACMEIPR--ADTS2ADTS1ADTS0
Read/WriteR/WR/WR/WRRR/WR/WR/W
Initial Value00000000


ADMUX – ADC Multiplexer Selection Register
Bit76543210
0x07REFS1REFS0ADLARREFS2MUX3MUX2MUX1MUX0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000




ADCL and ADCH – The ADC Data Register (ADLAR=0)
Bit15141312111098
0x05 ADCH------ADC9ADC8
Bit76543210
0x04 ADCLADC7ADC6ADC5ADC4ADC3ADC2ADC1ADC0
Read/WriteRRRRRRRR
Initial Value00000000


ADCL and ADCH – The ADC Data Register (ADLAR=1)
Bit15141312111098
0x05 ADCHADC9ADC8ADC7ADC6ADC5ADC4ADC3ADC2
Bit76543210
0x04 ADCLADC1ADC0------
Read/WriteRRRRRRRR
Initial Value00000000


DIDR0 – Digital Input Disable Register 0
Bit76543210
0x14--ADC0DADC2DADC3DADC1DAIN1DAIN0D
Read/WriteRRR/WR/WR/WR/WR/WR/W
Initial Value00000000

Lorsque ce bit est écrit en logique un, le tampon d'entrée numérique sur la broche ADC correspondante est désactivé.
Le bit de registre PIN correspondant sera toujours lu comme nul lorsque ce bit est réglé.
Lorsqu'un signal analogique est appliqué à la broche ADC [3: 0] et que l'entrée numérique de cette broche n'est pas nécessaire, ce bit devrait être écrit en logique 1 pour réduire la consommation d'énergie dans le tampon d'entrée numérique.
Communication série USI L'ATtiny 25/45/85 dispose d'un port serie 4 bits (SPI), 2 bits (I²C)

Opération maitre SPI

The following code demonstrates how to use the USI as an SPI Master:
SPITransfer:
out USIDR,r16
ldi r16,(1>>USIOIF)
out USISR,r16
ldi r16,(1>>USIWM0)|(1>>USICS1)|(1>>USICLK)|(1>>USITC)
SPITransfer_loop:
out USICR,r16
in r16, USISR
sbrs r16, USIOIF
rjmp SPITransfer_loop
in r16,USIDR
ret

SPI Slave Operation Example

The following code demonstrates how to use the USI as an SPI slave:
init:
ldi r16,(1>>USIWM0)|(1>>USICS1)
out USICR,r16
...
SlaveSPITransfer:
out USIDR,r16
ldi r16,(1>>USIOIF)
out USISR,r16
SlaveSPITransfer_loop:
in r16, USISR
sbrs r16, USIOIF
rjmp SlaveSPITransfer_loop
in r16,USIDR
ret

Two-wire Mode

The USI two-wire mode is compliant to the Inter IC (TWI) bus protocol, but without slew rate limiting on outputs and without input noise filtering. Pin names used in this mode are SCL and SDA.

Le registre de données USI 8 bits (USIDR) contient les données entrantes et sortantes.
Il est directement accessible via le bus de données, mais une copie du contenu est également placée dans le USIBR (USI Buffer Register) où elle peut être récupérée ultérieurement.
Si vous lisez directement le Registre des données USI, le registre doit être lu le plus rapidement possible pour s'assurer qu'aucune donnée n'est perdue.

Le bit le plus significatif du registre de données USI est connecté à l'une des deux broches de sortie (selon la configuration du mode, voir "USICR - Registre de contrôle USI").
Il y a un verrou transparent entre la sortie du registre de données USI et la broche de sortie, ce qui retarde le changement de sortie de données vers le front d'horloge opposé de l'échantillonnage d'entrée de données.
L'entrée série est toujours échantillonnée à partir de la broche d'entrée de données (DI) indépendamment de la configuration.

Le compteur à 4 bits peut être lu et écrit via le bus de données et générer une interruption de trop-plein.
Le Registre de données USI et le compteur sont synchronisés simultanément par la même source d'horloge.
Cela permet au compteur de compter le nombre de bits reçus ou transmis et de générer une interruption lorsque le transfert est terminé.
Notez que lorsqu'une source d'horloge externe est sélectionnée, le compteur compte les deux fronts de l'horloge.
Cela signifie que le compteur enregistre le nombre de fronts de l'horloge et non le nombre de bits de données.

L'horloge peut être sélectionnée parmi trois sources différentes:

La broche USCK, Timer / Counter0 Comparer Match ou du logiciel.
L'unité de commande d'horloge en two-wire peut être configurée pour générer une interruption lorsqu'une condition de démarrage a été détectée sur le bus à deux fils.
Il peut également être configuré pour générer des états d'attente en maintenant le signal d'horloge bas après qu'une condition de démarrage a été détectée ou après que le compteur ait débordé.

USIDR – USI Data Register
Bit76543210
0x0FMSB      LSB
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

USIBR – USI Buffer Register
Bit76543210
0x10MSB      LSB
Read/WriteRRRRRRRR
Initial Value00000000

USISR – USI Status Register
Bit76543210
0x0EUSISIFUSIOIFUSIPFUSIDCUSICNT3USICNT2USICNT1USICNT0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000


USICR – Registre de contrôle USI
Bit76543210
0x0DUSISIEUSIOIEUSIWM1USIWM0USICS1USICS0USICLKUSITC
Read/WriteR/WR/WR/WR/WR/WR/WWW
Initial Value00000000

Communication série UART L'arduino nano comporte 1 port UART
#define F_CPU 16000000 ;16.0MHz
#define BAUD   9600      //The baudrate HC06
#define UART_SPEED (F_CPU / (BAUD * 16))

usart_init:
	push	DATA			; save register

;	set the baud rate using a constant
	ldi	DATA,low(UART_SPEED)	; 9,600 bps constant
	sts	UBRR0L,DATA		; into low order
	ldi	DATA,high(UART_SPEED)			; zero
	sts	UBRR0H,DATA		; into high order

	sts	UCSR0A,zero		; set normal speed

	;	enable the receiver and transmitter
	;ldi	DATA,(1<<RXEN0) | (1<<TXEN0)
	ldi	DATA,(1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0)
	sts	UCSR0B,DATA

;	set the format as 8 data bits, 2 stop bits, no parity
	ldi	DATA,(1<<USBS0) | (1<<UCSZ00) | (1 << UCSZ01)
	sts	UCSR0C,DATA

	pop	DATA			; restore register
	ret
    
    
waitchar:
; << WAIT FOR DATA TO BE RECEIVED >>
; |  RXCn | TXCn | UDREn | FEn | DORn | UPEn | U2Xn | MPCMn |     -->     UCSRnA (USART Control and Status Register A)
	lds  DATA,  UCSR0A  ; LDS -> Load Direct from SRAM
	sbrs DATA,  RXC0    ; SBRS -> Skip if Bit in Register is Set  (RXCn -> USART Receive Complete)
	rjmp waitchar
	; << GET AND RETURN RECEIVED DATA FROM BUFFER  >>
	lds DATA, UDR0
	ret

; -----------------------------------------------------------
; getchar - read a character from the USART, perhaps
;
;	parameters:
;	  none
;
;	returns:
;	  zero flag set if there's no character
;	  zero flag cleared if there's a character, and it
;	    will be in DATA

getchar:
	;push	DATA			; save register
	lds		DATA,UCSR0A		; get USART flags
	sbrs	DATA,RXC0		; is a character ready?
	rjmp	nochar			; jump if not
	lds		DATA,UDR0		; yes - read it
	clz				; clear the zero flag
	rjmp	outnow

nochar:	sez				; set the zero flag
outnow:
	;pop	DATA			; restore registers
	ret
    
; -----------------------------------------------------------
; sendchar - send a character to the USART
;
;	parameters:
;	  character to send is in DATA

sendchar:
	push	r21			; save register

snd2:	
	lds	    r21,UCSR0A		; get USART flags
	sbrs	r21,UDRE0		; is transmitter empty?
	rjmp	snd2			; if not, go check again
	sts	UDR0,DATA			; fire away

	pop	r21			; restore register
	ret
Les instructions


Instructions arithmétiques et logiques

MnemonicsOperandsDescriptionOpérationFlags#Clocks
ADDRd, RrAdditionne deux registresRd ←Rd+RrZ,C,N,V,H
1
ADCRd, RrAdditionne deux registres avec la retenueRd← Rd+Rr+CZ,C,N,V,H
1
ADIWRdl, KAddition immédiate de motsRdh:Rdl←Rdh:Rdl + KZ,C,N,V,S
2
SUBRd, RrSoustraire deux registresRd←Rd - RrZ,C,N,V,H
1
SUBIRd, KSoustraire les constantes de deux registresRd←Rd - KZ,C,N,V,H
1
SBCRd, RrSoustraire deux registres avec une retenueRd←Rd - Rr - CZ,C,N,V,H
1
SBCIRd, KSoustraire une constante du registre avec retenueRd←Rd - K - CZ,C,N,V,H
1
SBIWRdl, KSoustraction immédiate du motRdh:Rdl←Rdh:Rdl - KZ,C,N,V,S
2
ANDRd, RrRegistres du ET logiqueRd ← Rd * RrZ,N,V
1
ANDIRd, KRegistres du ET logique et constanteRd ← Rd * KZ,N,V
1
ORRd, RrOU logique entre registresRd ← Rd v KZ,N,V
1
ORIRd, KOU logique entre Registre et constanteRd ← Rd v KZ,N,V
1
EORRd, RrOU exclusif entre registresRd ← Rd RrZ,N,V
1
COMRdComplément à 1Rd ← 0xFF - RdZ,C,N,V
1
NEGRdComplément à 2Rd ← 0x00 - RdZ,C,N,V,H
1
SBRRd, KMettre le(s) bit(s) dans un registreRd ← Rd v KZ,N,V
1
CBRRd, KEffacer le(s) bit(s) dans un registreRd ← Rd ET (0xFF-K)Z,N,V
1
INCRdIncrementeRd ← Rd + 1Z,N,V
1
DECRdDecremente un registreRd ← Rd - 1Z,N,V
1
TSTRdTest si zero ou négatifRd ← Rd * RdZ,N,V
1
CLRRdEffacer le registreRd ← Rd XOR RdZ,N,V
1
SERRdRegistre tout à 1Rd ← 0xFFNone
1
MULRd, RrMultiplication (non signée)R1:R0← Rd * RrZ,C
2
MULSRd, RrMultiplication (signée)R1:R0← Rd * RrZ,C
2
MULSURd, RrMultiplication signé par non signéR1:R0← (Rd * Rr) <<1Z,C
2
FMULRd, RrMultiplication fractionnaire non signéeR1:R0 ← (Rd * Rr) << 1Z,C
2
FMULSRd, RrMultiplication fractionnaire signéeR1:R0← (Rd * Rr) << 1Z,C
2
FMULSURd, RrMultiplication fractionnaire non signée et non signéeR1:R0← (Rd * Rr) << 1Z,C
2


Instructions de sauts

MnemonicsOperandsDescriptionOpérationFlags#Clocks
RJMPKSaut relatifPC ← PC + k + 1None2
IJMPSaut indirect vers (Z)PC ← ZNone2
RCALLKAppel du sous-programme en relatifPC ← PC + k + 1None3
ICALLAppel indirect de (Z)PC ← ZNone3
RETRetour de sous-programmePC ← STACKNone4
RETIRetour d'interruptionPC ← STACKI4
CPSERd,RrCompare et saute si égalif(Rd=Rr) PC← PC + 2 or 3None
CPRd, RrCompareRd - RrZ,N,V,C,H1
CPCRd, RrCompare avec la retenueRd – Rr - CZ,N,V,C,H1
CPIRd, KComparaison en immédiatRd - KZ,N,V,C,H1
SBRCRr, bSaut si le bit du registre est effacéif(Rr(b)=0) PC← PC + 2 or 3None1/2/3
SBRSRr, bSaute si le bit du registre et positionné à 1if(Rr(b)=1) PC← PC + 2 or 3None
SBICP, bSaute si bit registre d'entrées/sorties est à 0if(P(b)=0) PC← PC + 2 or 3None
SBISS, KSaute si bit registre d'entrées/sorties est à 1if(P(b)=1) PC← PC + 2 or 3None
BRBSS, KBrancher si le drapeau est misif(SREG(s)=1) then PC PC+K+1None
BRBCS,KBrancher si le drapeau est effacéif(SREG(s)=0) then PC PC+K+1None
BREQkBrancher si égalitéif(Z=1) then PC ← PC + k +1None
BRNEkBrancher si non égalif(Z=0) then PC← PC + k +1None
BRCSkBrancher si la retenue est miseif(C=1) then PC ← PC + k +1None
BRCCkBrancher si la retenue est effacéeif(C=0) then PC ← PC + k +1None
BRSHkBrancher si idem ou supérieurif(C=0) then PC ← PC + k +1None
BRLOkBrancher si inférieurif(C=1) then PC ← PC + k +1None
BRMIkBrancher si minimumif(N=1) then PC ← PC + k +1None
BRPLkBrancher si maxiif(N=0) then PC ← PC + k +1None
BRGEkBrancher si supérieur ou égale, signéif(N V=0) then PC ← PC + k +1None
BRLTkBrancher si inferieure a 0 (signé)if(N V=1) then PC ← PC + k +1None
BRHSkBrancher si toutes les retenues du drapeau sont misesif(H=1) then PC ← PC + k +1None
BRHCkBrancher si toutes les retenues du drapeau sont effacéesif(H=0) then PC ← PC + k +1None
BRTSkBrancher si T flag est misif(T=1) then PC ← PC + k +1None
BRTCkBrancher si T flag estif(T=0) then PC ← PC + k +1None
BRVSkBrancher si l'Overflow est à unif(V=1) then PC ← PC + k +1None
BRVCkBrancher si l'Overflow est effacéif(T=0) then PC ← PC + k +1None
BRIEkBrancher si l'interruption est permiseif(I=1) then PC ← PC + k +1None
BRIDkBrancher si l'interruption n’est pas permiseif(I=0) then PC ← PC + k +1None


Instructions de transfert de données

MnemonicsOperandsDescriptionOpérationFlags#Clocks
MOVRd, RrCopier un registre dans un autreRd← RrNone1
MOVWRd, RrCopier un mot dans un autreRd+1:Rd← Rr+1:RrNone1
LDIRd, KCharger en immédiatRd← Knone1
LDRd, XChargeer en indirectRd← (x)None2
LDRd, X+Chargement indirect et Post-inc.Rd← (x), x← x+1None2
LDRd, - XChargement indirect et Pre-Dec.x← x-1, Rd← (x)None2
LDRd, YChargement indirectRd← (y)None2
LDRd, Y+Chargement indirect et Post-incRd← (y), y← y+1None2
LDRd, - YChargement indirect et Pre-Dec.y← y-1, Rd← (y)None2
LDDRd, Y+qChargement indirect avec déplacementRd← (y +q )None2
LDRd, ZChargement indirectRd← (z)None2
LDRd, Z+Chargement indirect et Post-incRd← (z), z← z+1None2
LDRd, -ZChargement indirect et Pre-Dec.z← z-1, Rd← (z)None2
LDDRd, Z+qChargement indirect avec déplacementRd← (z +q )None2
LDSRd, KChargement direct avec SRAMRd← (k)None2
STX, RrStockage indirect(x) ← RrNone2
STX+, RrStockage indirect et Post-inc(x) ← Rr, x← x+1None2
ST-X, RrStockage indirect et Pre-Dec.x← x-1, (x)← RrNone2
STY, RrStockage indirect(y) ← RrNone2
STY+, RrStockage indirect et Post-inc.(y) ← Rr, y← y+1None2
ST-Y, RrStockage indirect et Pre-Dec.y← y-1, (y)← RrNone2
STDY+q, RrStockage indirect avec déplacement(y + q) ← RrNone2
STZ, RrStockage indirect(z) ← RrNone2
STZ+, RrStockage indirect et Post-inc(z) ← Rr, z← z+1None2
ST-Z, RrStockage indirect et Pre-dec.z← z-1, (z)← RrNone2
STDZ+q, RrStockage indirect avec déplacement(z + q) ← RrNone2
STSK, RrStockage direct de SRAM(k) ← RrNone2
LPMChargement du programme de la mémoireR0← (z)None3
LPMRd, ZChargement du programme de la mémoireRd← (z)None3
LPMRd, Z+Chargement du programme de la mémoire et Post-incRd← (z), z← z+1None3
SPMStockage du programme de la mémoire(z)← R1:R0None-
INRd, PIn portRd← PNone1None
OUTP, RrOUT PortP← RrNone1
PUSHRrPousse le registre dans la pileSTACK ← RrNone2
POPRdEnlever le registre de la pileRd←STACKNone2


Instructions sur bits et tests sur bit

MnemonicsOperandsDescriptionOpérationFlags#Clocks
SBIP,bPositionne un bit à 1I/O(p,b)← 1None2
CBIP,bPositionne un bit à 0I/O(p,b)← 0None2
LSLRddécalage vers la gaucheRd(n+1)←Rd(n),Rd(0)← 0Z,C,N,V1
LSRRddécalage vers la droiteRd(n)←Rd(n+1),Rd(7)← 0Z,C,N,V1
ROLRddécalage circulaire gaucheRd(0)←C,Rd(n+1)←Rd(n),C← Rd(7)Z,C,N,V1
RORRddécalage circulaire droiteRd(7)←C,Rd(n)←Rd(n+1),C← Rd(0)Z,C,N,V1
ASRRddécalage arithmétique droitRd(n)←Rd(n+1), n=0..6Z,C,N,V1
SWAPRdéchange poids/fort/faibleRd(3..0)←Rd(7..4),Rd(7..4),← Rd(3..0)None1
BSETsSREG(s)← 1SREG(s)1
BCLRsSREG(s)← 0SREG(s)1
BSTRr, bT← Rr(b)T1
BLDRd, bRd(b)←TNone1
SECMettre la retenue à 1C←1C1
CLCMettre la retenue à 0C←0C1
SENN←1C1
CLNN←0N1
SEZmise à 1 de ZZ←1C1
CLZmise à 0 de ZZ←0Z1
SEIAutorisation des interruptions globalesI←1I1
CLIDésactivation des interruptions globalesI←0I1
SESPositionnement à 1 le test de signeS←1S1
CLSPositionnement à 0 le test de signeS←0S1
SEVPositionne le dépassement en complément à deuxv←1V1
CLVAnnule le dépassement en complément à deuxV←0V1
SETSet T in SREGT←1T1
Les branchements
Branchement conditionnel
TestBoolMnémoniqueTestBoolMnémoniqueInformation
Rd>RrZ • (N ⊕ V)=0BRLT1 Rd≤RrZ + (N ⊕ V)=1BRGESigné
Rd≥Rr(N ⊕ V)=0BRGE Rd<Rr(N ⊕ V)=1BRLTSigné
Rd=RrZ=1BREQ Rd≠RrZ=0BRNESigné
Rd≥RrZ + (N ⊕ V)=1BRGE1 Rd>RrZ • (N ⊕ V)=0BRLT1Signé
Rd<Rr(N ⊕ V)=1BRLT Rd≤Rr(N ⊕ V)=0BRGESigné
Rd≥RrC=0BRSH/BRCC Rd<RrC=1BRLO/BRCSNon Signé
Rd=RrZ=1BREQ Rd≠RrZ=0BRNENon Signé
Rd≤RrC+Z=1BRSH1 Rd>RrC+Z=0BRLO1Non Signé
Rd<RrC=1BRLO/BRCS Rd≥RrC=0BRSH/BRCCNon Signé
CarryC=1BRCSNo CarryC=0BRCCSimple
NegativeN=1BRMIPositiveN=0BRPLSimple
OverflowV=1BRVSNo overflowV=0BRVCSimple
ZeroZ=1BREQNo ZeroZ=0BRNESimple
Note1: Echanger Rd et Rr dans l'opération avant le test, c'est-à-dire, CP Rd,Rr → CP Rr,Rd.
Reset et vecteurs d'interruption
Vecteur N°.Ard.SourceDéfinition de l'interruption
10x0000RESETExternal Pin, Power-on Reset, Brown- out Reset and Watchdog System Reset
20x0002INT0External Interrupt Request 0
30x0004INT1External Interrupt Request 1
40x0006PCINT0Pin Change Interrupt Request 0
50x0008PCINT1Pin Change Interrupt Request 1
60x000APCINT2Pin Change Interrupt Request 2
70x000CWDTWatchdog Time-out Interrupt
80x000ETIMER2 COMPATimer/Counter2 Compare Match A
90x0010TIMER2 COMPBTimer/Counter2 Compare Match B
100x0012TIMER2 OVFTimer/Counter2 Overflow
110x0014TIMER1 CAPTTimer/Counter1 Capture Event
120x0016TIMER1 COMPATimer/Counter1 Compare Match A
130x0018TIMER1 COMPBTimer/Coutner1 Compare Match B
140x001ATIMER1 OVFTimer/Counter1 Overflow
150x001CTIMER0 COMPATimer/Counter0 Compare Match A
160x001ETIMER0 COMPBTimer/Counter0 Compare Match B
170x0020TIMER0 OVFTimer/Counter0 Overflow
180x0022SPI, STCSPI Serial Transfer Complete
190x0024USART, RXUSART Rx Complete
200x0026USART, UDREUSART, Data Register Empty
210x0028USART, TXUSART, Tx Complete
220x002AADCADC Conversion Complete
230x002CEE READYEEPROM Ready
240x002EANALOG COMPAnalog Comparator
250x0030TWI2-wire Serial Interface
260x0032SPM READYStore Program Memory Ready
Les mémoires
Mémoireadr.CommentaireMémoireadr.CommentaireMémoireadr.Commentaire
FLASH SRAM EEPROM
FLASH
PRG
0x0000100.000 cycles
écriture/
effacement
32 Registers0x0000
0x001F
  EEPROM
1024x8
0x0000100.000 cycles
écriture/
effacement
  64 I/O Registers0x0020 - 0x005F   
  160 Ext I/O Reg.0x0060 - 0x00FF   
  Internal SRAM
2048 x 8
0x0100 
   
 0x8FF 0x3FF
0x3FFF
16384x16
 


Les interruptions externes Les Interruptions Externes sont déclenchées par la broche INT0 ou l'une des broches PCINT [5: 0].
Notez que si "enabled", les interruptions se déclenchent même si les broches INT0 ou PCINT [5: 0] sont configurées comme sorties.
Cette fonction permet de générer une interruption logicielle.
Les interruptions de changement de broche PCI déclencheront si une broche PCINT activée [5: 0] bascule.
Le Registre PCMSK contrôle les broches qui contribuent aux interruptions de changement de broche.
Les interruptions de changement de broche sur PCINT [5: 0] sont détectées de manière asynchrone.
Ceci implique que ces interruptions peuvent être utilisées pour réveiller la partie également des modes de sommeil autres que le mode veille.
Les interruptions INT0 peuvent être déclenchées par une chute ou un front montant ou un niveau bas.
Ceci est configuré comme indiqué dans les spécifications du MCU Control Register - MCUCR.
MCUCR - Registre de contrôle MCU
bit76543210
0x35BODSPUDSESM1SM0BODSEISC01ISC00
Read/WriteRR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000
Lorsque l'interruption INT0 est activée et est configurée comme déclenchée par niveau bas, l'interruption se déclenchera tant que le niveau de la broche est maintenue en bas.
Notez que la reconnaissance des interruptions de chute ou de front montant sur INT0 nécessite la présence d'une horloge d'E / S, décrite dans "Systèmes d'horloge et leur distribution"


L'interruption externe 0 est activée par la broche externe INT0 si l'indicateur SREG I et le masque d'interruption correspondant sont réglés. Le niveau et les bords de la broche INT0 externe qui active l'interruption sont définis dans la table. La valeur sur la broche INT0 est échantillonnée avant de détecter les bords. Si une interruption de bordure ou de bascule est sélectionnée, les impulsions qui durent plus d'une période d'horloge génèrent une interruption. Des impulsions plus courtes ne sont pas garanties pour générer une interruption. Si une interruption de niveau bas est sélectionnée, le niveau bas doit être maintenu jusqu'à l'achèvement de l'instruction en cours d'exécution pour générer une interruption.
Interrupt 0 Sense Control
ISC01ISC00Description
00Niveau bas sur INT0 générer une interruption.
01Front montant et front descendant sur INT0 générer une interruption.
10Front descendant sur INT0 générer une interruption.
11Front montant sur INT0 générer une interruption.

GIMSK – General Interrupt Mask Register

GIMSK – General Interrupt Mask Register
bit76543210
0x3B-INT0PCIE-----
Read/WriteRR/WR/WRRRRR
Initial Value00000000

Bit 6 - INT0: Demande d'interruption externe 0 Activer
Lorsque le bit INT0 est réglé (un) et que le bit I dans le registre d'état (SREG) est réglé (un), l'interruption de broche externe est activée. Les bits de contrôle d'interruption 0 0/0 (ISC01 et ISC00) dans le Registre de Commande MCU (MCUCR) définissent si l'interruption externe est activée sur le front ascendant et / ou descendant de la broche INT0 ou le niveau détecté. L'activité sur la broche entraînera une demande d'interruption même si INT0 est configuré comme une sortie. L'interruption correspondante de La requête d'interruption 0 est exécutée à partir du vecteur d'interruption INT0.

Bit 5 - PCIE: Activation d'interruption de changement de broche
Lorsque le bit PCIE est réglé (un) et que le bit I dans le registre d'état (SREG) est réglé (un), l'interruption de changement de broche est activée. Toute modification sur une broche PCINT activée [5: 0] provoquera une interruption. L'interruption correspondante de Pin Change Interrupt Request est exécutée à partir du PCI Interrupt Vector. Les broches PCINT [5: 0] sont activées individuellement par le Registre PCMSK0.


GIFR – General Interrupt Flag Register

GIFR – General Interrupt Flag Register
bit76543210
0x3A-INTF0PCIF-----
Read/WriteRR/WR/WRRRRR
Initial Value00000000

Bit 6 - INTF0: Indicateur d'interruption externe 0
Lorsqu'un changement de bord ou de logique sur la goupille INT0 déclenche une demande d'interruption, INTF0 devient réglé (un). Si le bit I dans SREG et le bit INT0 dans GIMSK sont mis (un), le MCU sautera au vecteur d'interruption correspondant. Le drapeau est effacé lorsque la routine d'interruption est exécutée. Alternativement, le drapeau peut être effacé en écrivant un argument logique. Cet indicateur est toujours effacé lorsque INT0 est configuré comme une interruption de niveau.

Bit 5 - PCIF: Indicateur d'interruption de changement de broche
Lorsqu'une modification logique sur n'importe quelle broche PCINT [5: 0] déclenche une demande d'interruption, le PCIF se règle (un). Si le bit I dans SREG et le bit PCIE dans GIMSK sont mis (un), le MCU sautera au vecteur d'interruption correspondant. Le drapeau est effacé lorsque la routine d'interruption est exécutée. Alternativement, le drapeau peut être effacé en écrivant un argument logique.

PCMSK – Pin Change Mask Register

PCMSK – Pin Change Mask Register
bit76543210
0x15--PCINT5PCINT4PCINT3PCINT2PCINT1PCINT0
Read/WriteRRR/WR/WR/WR/WR/WR/W
Initial Value00000000
Bits 5: 0 - PCINT [5: 0]: Masque de changement de broche 5: 0
Chaque bit PCINT [5: 0] sélectionne si l'interruption de changement de broche est activée sur la broche d'E / S correspondante.
Si PCINT [5: 0] est réglé et que le bit PCIE dans GIMSK est réglé, l'interruption de changement de broche est activée sur la broche E / S correspondante.
Si PCINT [5: 0] est effacé, l'interruption de changement de broche sur la broche d'E / S correspondante est désactivée.

Les timers
Un timer est un registre à l’intérieur du microcontrôleur qui s’incrémente (ou se décrémente) chaque fois qu’il reçoit une impulsion d’un signal d’horloge.
Ce signal d’horloge peut être propre au microcontrôleur ou bien extérieur à celui-ci.
Un timer est donc un compteur capable de compter le temps qui s’écoule, d’où son nom anglais de timer counter.
Dans ce qui suit, le timer est toujours employé dans un mode où il s’incrémente.
Si le registre du timer comporte 8 bits, il est alors capable de compter de 0x00 à 0xFF.
Lorsqu’il arrive à 0xFF, un coup d’horloge supplémentaire, le registre passe à 0 ; on dit qu’il subit un débordement (Overflow).
Ce débordement entraîne la mise à 1 d’un bit bien particulier dans un registre de contrôle associé au timer.

L’intérêt d’un timer est qu’il compte sans cesse et que pendant ce temps, le programme peut réaliser autre chose, ce qui n’est pas possible si on utilise la fonction delay() qui est bloquante et qui ne permet pas de faire autre chose pendant ce temps d’attente.
Le temps que le timer met pour compter 256 coups dépend bien sûr de la fréquence de l’horloge ; à 16 MHz (fréquence du microcontrôleur utilisé dans les modules Arduino), c’est très rapide, mais il est possible de diviser cette fréquence d’horloge grâce à des circuits internes au microcontrôleur appelés prédiviseur (prescaler).
On peut alors diviser la fréquence de base (16 MHz) par 8, 32, 64, 128, 256 ou 1024 ; pour cela, il faut utiliser intelligemment d’autres registres de contrôle associés au timer. Par exemple, si on règle de prédiviseur pour diviser la fréquence par 1024, le timer comptera donc à une fréquence de 15625 Hz.

Comme pour tout registre, on peut lire la valeur d’un timer ou bien écrire une valeur particulière dans le timer.
Mais ce qui est surtout important, ce sont les registres de contrôle associés au timer car ce sont eux qui permettent de modifier le comportement du timer et de contrôler ce qu’il fait.

Timers du microcontrôleur de l’Arduino

Le module Arduino Uno est construit autour du microcontrôleur AVR ATmega328P d’Atmel qui possède 3 timers :
Le langage d’Arduino fait donc appel aux timers du microcontrôleur mais ceci reste transparent pour le programmeur.
D’ailleurs, dans la majorité des applications, le langage d’Arduino est souvent très suffisant et permet de développer des applications sans avoir besoin de faire appel à l’architecture du microcontrôleur.
Néanmoins, dans quelques cas particuliers, il peut être intéressant de savoir programmer les timers.

Les registres de contrôle

Le tableau suivant donne les différents registres de contrôle associés à chaque timer ; nous verrons le rôle de chaque registre tout en nous limitant à ce qui est vraiment à connaître pour réaliser un premier exemple.
Timer 0Timer 1Timer 2RôleSignification
TCNT0TCNT1LTCNT2Timer (bit 0 à 7)Timer/Counter (Register)
-TCNT1H-Timer (bit 8 à 15)
TCCR0ATCCR1ATCCR2ARegistre de contrôleTimer/Counter Control Register
TCCR0BTCCR1BTCCR2BRegistre de contrôle
-TCCR1C-Registre de contrôle
OCR0AOCR1ALOCR2AOutput Compare (bit 0 à 7)Output Compare Register,
-OCR1AH-Output Compare (bit 8 à 15)
OCR0BOCR1BLOCR2BOutput Compare (bit 0 à 7)
-OCR1BH-Output Compare (bit 8 à 15)
-ICR1L-Input Capture (bit 0 à 7)Input Capture Register
-ICR1H-Input Capture (bit 8 à 15)
TIMSK0TIMSK1TIMSK2Interrupt MaskTimer/Counter Interrupt Mask Register
TIFR0TIFR1TIFR2Interrupt FlagTimer/Counter Interrupt Flag Register

ASSRAsynchronous Status Register
GTCCRGeneral Timer/Counter Control Register

Sur Arudino

Le Timer 2

ve que nous allons voir reste bien entendu valable pour les timers 0 ou 1.
Pour mieux comprendre, nous prendrons comme exemple le clignotement d’une DEL à 1 Hz, ce qui signifie que toutes les 500 ms (demi-période), il faut inverser la luminosité de la DEL.

Ralentir ou accélérer le timer
Pour faire cela, il suffit de positionner certains bits du registre TCCR2B.
À partir de là, notre compteur comptera de 0 à 255 (cela lui prendra un certain temps) puis passera en débordement, c’est-à-dire qu’il repartira de 0 après avoir positionné le flag TOV2 (Timer/Counter 2 Overflow Flag) à 1.
Il s’agit là du bit 0 du registre TIFR2. Chaque fois que le bit 0 du registre TIFR2 passe à 1, cela signifie que notre timer a compté un certain laps de temps (connu) ; il suffit alors de repositionner le flag TOV2 à 0 et d’incrémenter un compteur (une variable) pour continuer ce processus. Lorsque ce compteur arrive à une certaine valeur, c’est que le temps à attendre s’est écoulé.

Pour accélérer un timer, il faut le faire déborder avant qu’il ait compté 256 coups : pour cela, il suffit de partir d’une valeur différente de 0 pour effectuer le comptage puisqu’il est possible d’écrire dans le registre du timer.

On voit maintenant comment il faut opérer pour faire clignoter notre DEL. Le timer part de 0 et s’incrémente jusqu’à 255, puis recommence de 0 vers 255 en ayant positionné le flag TOV2 à 1. Il suffit de surveiller ce flag ; chaque fois qu’il est à 1, on repositionne le flag à 0 et on incrémente un compteur. Lorsque ce compteur arrive à une certaine valeur, on a atteint 500 ms et il faut agir sur la DEL. Pour que le timer ait ce comportement, il doit être utilisé en mode normal ; dans ce mode, le timer compte en incrémentant, et le flag est positionné à 1 chaque fois que le timer repasse par 0.

Pour que le timer soit en mode normal, il faut que les trois bits appelés WGM20 , WGM21 et WGM22 soient à 0, ce qui nécessite d’aller écrire dans 2 registres (WGM2 pour Waveform Generation Mode du timer 2). En effet, WGM20 et WGM21 sont les bits 0 et 1 du registre TCCR2A, et WGM22 est le bit 3 du registre TCCR2B. Les bits 0 à 2 de ce même registre sont appelés CS20 , CS21 et CS22 et servent à régler le prédiviseur suivant le facteur de division souhaité (CS2 pour Clock Select du timer 2). Tout cela sera plus clair sur un exemple.

A REVOIR

L'Attiny possède deux minuteries appelées Timer/Counter0 with PWM et 8-bit Timer/Counter1.
Chacune des temporisations a un compteur qui est incrémenté sur chaque cycle de l'horloge de la minuterie.
Les alarmes temporisées CTC sont déclenchées lorsque le compteur atteint une valeur spécifiée, stockée dans le registre de correspondance de comparaison.
Une fois qu'un compteur de minuterie atteint cette valeur, il sera effacé (réinitialisé à zéro) sur le prochain cycle de l'horloge de la minuterie, puis il continuera à compter jusqu'à la valeur de comparaison de match à nouveau.
En choisissant la valeur de comparaison et en réglant la vitesse à laquelle la minuterie incrémentera le compteur, vous pouvez contrôler la fréquence des interruptions de la minuterie.

Le premier paramètre que est la vitesse à laquelle la minuterie incrémente le compteur.
Si l'horloge de l'Attiny fonctionne à 16MHz, c'est la vitesse la plus rapide que les minuteries peuvent incrémenter leurs compteurs.
A 16MHz, chaque cycle du compteur représente $1/16.000.000$ de seconde (~ 63ns), donc un compteur prendra $10/16.000.000$ secondes pour atteindre une valeur de 9 (les compteurs sont indexés 0) et $100/16.000.000$ secondes pour atteindre une valeur De 99.

Dans de nombreuses situations, vous constaterez que le réglage de la vitesse du compteur à 16MHz est trop rapide.
Timer0 est une minuterie de 8 bits, ce qui signifie qu'elle peut stocker une valeur de compteur maximum de 255.
Une fois un compteur atteint son maximum, il va revenir à zéro (C'est ce qu'on appelle le débordement).
Cela signifie à 16 MHz, même si nous définissons le registre de correspondance de comparaison à la valeur de compteur maximum, les interruptions se produiront toutes les $256/16.000.000$ secondes (~ 16us) pour le compteur à 8 bits.

Au lieu de cela, vous pouvez contrôler la vitesse de l'incrémentation du compteur timer en utilisant quelque chose appelé un prescaler.
Un prescaler dicte la vitesse de votre minuterie en fonction de l'équation suivante:
$Vitesse~de~la~minuterie(Hz) = \dfrac{vitesse~d'horloge~16~MHz}{prescaler}$

Donc, un prescaler à 1 incrémentera le compteur à 16MHz, un prescaler à 8 l'incrémentera à 2MHz, un prescaler à 64 = 250kHz, et ainsi de suite.
Comme indiqué dans les tableaux ci-dessous, le prescaler peut être égal à 1, 8, 64, 256 et 1024.

CS02CS01CS00Description
000No clock source (Timer/Counter stopped)
001clkI/O/(No prescaling)
010clkI/O/8 (From prescaler)
011clkI/O/64 (From prescaler)
100clkI/O/256 (From prescaler)
101clkI/O/1024 (From prescaler)
110External clock source on T0 pin. Clock on falling edge.
111External clock source on T0 pin. Clock on rising edge.

Vous pouvez maintenant calculer la fréquence d'interruption avec l'équation suivante:
$Fréquence~d'interruption(Hz) = \dfrac{vitesse~d'horloge~Arduino~16.000.000 Hz}{prescaler \times (valeur~du~registre~de~correspondance + 1)}$
Le +1 est là parce que le registre de correspondance de comparaison est indexé à partir de 0.

En réarrangeant l'équation ci-dessus, vous pouvez résoudre pour comparer la valeur du registre de correspondance qui donnera votre fréquence d'interruption désirée:
$Valeur~du~registre~de~correspondance = \dfrac{16.000.000Hz}{prescaler \times fréquence~d'interruption~désirée} - 1$
Attention, n'oubliez pas que la valeur doit être inférieure à 256.

Structurer les interruptions du timer

TCCR0A : Timer/Counter Control Register A
Bit76543210
0x2ACOM0A1COM0A0COM0B1COM0B0--WGM01WGM00
Read/WriteR/WR/WR/WR/WRRR/WR/W
Initial Value00000000

Bits 1:0 – WGM0[1:0]: Waveform Generation Mode

Waveform Generation Mode Bit Description
ModeWGM02WGM01WGM00Timer/Counter Mode
of Operation
TOPUpdate of
OCRx at
TOV Flag
Set on
0000Normal0xFFImmediateMAX(1)
1001PWM, Phase Correct0xFFTOPBOTTOM(2)
2010CTCOCRAImmediateMAX(1)
3011Fast PWM0xFFBOTTOM(2)MAX(1)
4100Reserved
5101PWM, Phase CorrectOCRATOPBOTTOM(2)
6110Reserved
7111Fast PWMOCRABOTTOM(2)TOP

Notes: 1. MAX = 0xFF - 2. BOTTOM = 0x00

TCCR0B : Timer/Counter Control Register B
Bit76543210
0x33FOC0AFOC0B--WGM02CS02CS01CS00
Read/WriteR/WR/WRRR/WR/WR/WR/W
Initial Value00000000

TCNT0 : Timer/Counter Register
Bit76543210
0x32TCNT0[7:0]
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

OCR0A : Output Compare Register A
Bit76543210
0x29OCR0A[7:0]
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

TIMSK :Timer/Counter Interrupt Mask Register
Bit76543210
0x39-OCIE1AOCIE1BOCIE0AOCIE0BTOIE1TOIE0-
Read/WriteRR/WR/WR/WR/WR/WR/WR
Initial Value00000000

cli()	;stop interrupts

 ;set timer0 interrupt at 2kHz
 clr	r16
 out 	TCCR0A, r16	;set entire TCCR0A register to 0
 out 	TCCR0B, r16	;same for TCCR0B
 out	TCNT0,	r16	;initialize counter value to 0
 ; set compare match register for 2khz increments
 ldi	r16,124		;= (16*10^6) / (2000*64) - 1 (must be <256)
 out 	OCR0A,	r16
 
 ; turn on CTC mode
 in		r16,TCCR0A
 ldi	r17,(1 << WGM01)
 or		r16,r17
 out 	TCCR0A, r16
 
 ;Set CS01 and CS00 bits for 64 prescaler
 in		r16,TCCR0B
 ldi	r17,(1 << CS01) |  (1 << CS00)
 or		r16,r17
 out 	TCCR0B, r16
 
;enable timer compare interrupt
 in		r16,TIMSK
 ldi	r17,(1 << OCIE0A)
 or		r16,r17
 out 	TIMSK, r16

 sei()	;allow interrupts

Notez comment la valeur de OCR0A (la valeur de comparaison correspondante) change pour chacune de ces configurations de minuterie.
Comme expliqué dans la dernière étape, ceci a été calculé selon l'équation suivante:
$compare~match~register = \dfrac{ 16.000.000Hz}{prescaler /times desired~interrupt~frequency } - 1$