19
Interfaces analogiques (ADC & DAC) Arduino DUE SÉMINAIRE DESIGN II, Jérôme Genest, 2016

Interfaces analogiques (ADC & DAC) Arduino DUE SÉMINAIRE ...wcours.gel.ulaval.ca/2016/h/GEL2007/default/5notes/seminaire4b_ADC_DAC.pdf · SYNCHRONISATION DU DAC ET DE L’ADC ! On

  • Upload
    others

  • View
    21

  • Download
    0

Embed Size (px)

Citation preview

Interfaces analogiques (ADC & DAC) Arduino DUE SÉMINAIRE DESIGN II, Jérôme Genest, 2016

ARDUINO DUE

¢ Atmel SAM3X8E Arm Cortex M3 �  32 bits �  84 MHz �  3.3 Volts ! Attention !!!

¢  11 Canaux d’ADC : AT06860 �  12 bits, �  Jusqu’à 1MHz (mais 666 kHz à cause du 84 MHz)

¢  84/6 = 14 MHz max clock de l’ADC ¢  14 MHz / 21=666 kHz sampling rate

¢  2 Canaux de DAC �  12 bits �  Jusqu’à 666 kHz

Processeur Cortex M3

Compteurs

ADC

DAC

PDC Peripheral DMA Controller Relié aux DAC & ADC

RAM

UTILISATION SIMPLE

¢ Mavaise idée !! �  Vitesse limitée

¢  ~20kHz

�  Aucune garantie ¢  Fs ne sera pas constant

�  Bloque le flot d’exécution

void setup() { // put your setup code here, to run once: analogWriteResolution(12); analogReadResolution(12); // 10 is default Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: uint16_t i =0; analogWrite(DAC0,i); Serial.print(analogRead(A0)); i++; }

INTERUPTIONS

¢ Signal émis par du HW ou du SW pour signifier qu’un évènement demande de l’attention immédiate �  L’état (registre, stack…) peut être sauvegardé �  Le code est interrompu �  La fonction d’interruption est appelée.

¢ C.f.: Ordinateurs, structures et applications

TIMER INTERUPTS SUR LE DUE

¢ Les compteurs (timer counters) �  On peut leur spécifier une horloge

¢  On peut diviser l’horloge de 84 MHz par: ¢  2, 8, 32, 128

�  On leur spécifie jusqu’à combien compter �  Vont générer une interruption HW lors que le

compteur déborde

¢ Exemple: �  84 MHz / 2 = 42 MHz �  Compter jusqu’à 1000

¢  L’interrupt surviendra à 42 kHz.

LES COMPTEURS

¢  3 Modules de Compteurs �  TC0, TC1, TC2

¢ Chaque compteur a 3 canaux �  0, 1, 2

¢  9 Canaux au total �  Chaque canal est un compteur et chaque a son

interupt et sa fonction de gestion d’interruption

�  Numéro de l’IRQ ¢  3*TC + canal ¢  Exemple TC1, canal 2

¢  IRQ 3*1+2 = 5

EXEMPLE INTERUPT TC2, CHAN 1 => #7

const int led_pin = 13; int state = false; void setup() { pinMode(led_pin, OUTPUT); pmc_set_writeprotect(false); // power management control (pmc) pmc_enable_periph_clk(ID_TC7); // Allumer le périphérique qui sera utilisé // Config le timer TC2, channel 1, TIMER_CLOCK4 == /128 TC_Configure(TC2,1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); TC_SetRC(TC2, 1, 131200); // On compte jusqu’à 131200 TC_Start(TC2, 1); // Partir le timer // Faire en sorte que la fonction d’interruption est appelée TC2->TC_CHANNEL[1].TC_IER=TC_IER_CPCS; // IER = interrupt enable register TC2->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS; // IDR = interrupt disable register NVIC_EnableIRQ(TC7_IRQn); }

EXEMPLE INTERUPT: FONCTION DE GESTION

¢  84MHz/128/131200 = 5 Hz (0.2 seconde) �  TIMER_CLOCK1 == /2 , �  …, �  TIMER_CLOCK4 == /128

void loop() { // Il ne se passe rien dans la boucle !!! } void TC7_Handler() { TC_GetStatus(TC2, 1); // Efface le status et permet un nouvel appel de l’interrupt state = !state; digitalWrite(led_pin, state); // On fait juste clignoter une LED 5 fois par sec }

INTERRUPTIONS: PARFAIT POUR LE DAC

¢ Générer la forme d’onde qui va contrôler le moteur

¢ DDS: Direct digital synthesis �  Configurer un interrupt pour avoir le taux

d’échantillonage voulu. �  Définir un tableau (array)

¢  Ex: un cycle d’une onde triangulaire

�  Jouer le tableau en boucle ¢  un échantillon à chaque passage dans la fonction de gestion

Ne pas utiliser: “analogWrite”

Utiliser: “dacc_write_conversion_data” Plus rapide

INTERUPTION ET ADC

¢ Acquérir le signal du photodétecteur

¢ On pourrait procéder de la même manière pour l’ADC �  Lire un échantillon à chaque interuption

¢ On aurait le problème de gérer l’interface série à chaque interuption, pour transmettre un point

¢ Et/ou d’écrire du code pour regrouper les données

¢ On peut faire mieux avec le DMA. �  DMA == Direct memory access.

DMA & ADC

¢ On peut configurer l’ADC pour échantillonner tout le temps �  C’est un périphérique indépendant du processeur �  Les échantillons vont juste aller nulle part.

¢ On peut dire à l’ADC d’envoyer les échantillons directement dans la RAM �  Adresse du premier échantillon �  Taille du tableau.

¢ Quand le tableau est plein, les échantillons se perdent à nouveau

¢ Le processeur peut lire la RAM en temps opportun �  Dans la boucle principale

STATÉGIE: ADC

¢ Dans setup() �  Configurer l’ADC pour qu’il échantillonne au taux voulu

¢ Lorsqu’on est prêt �  Passer l’adresse et la taille du bloc via le PDC

¢ Dans la boucle loop() �  Gérer le contrôleur série et transmettre les données du

bloc lorsque l’ordinateur le demande.

�  c.f. exemple dans les références ‘nicecircuits.com’

SYNCHRONISATION DU DAC ET DE L’ADC

¢ On veut partir l’acquisition quand le balayage commence: �  Configurer le DMA avec le PDC dans l’interrupt

utilisé pour le DAC ¢  À chaque fois qu’on passe à un endroit précis de la forme

d’onde Forme d’onde générée par le DDS

Passer le tableau au DMA lorsqu’on est à cet endroit dans le cycle

NOTES

¢ La programmation avec interuptions n’est pas séquentielle �  Comme le DMA est configuré dans l’interrupt

¢  Le tableau peut commencer à se remplir n’importe quand ¢  Peut importe où on est rendu dans la boucle loop()

¢ Bonnes pratiques �  Sémaphores �  Double buffer

Pas si facile à gérer correctement!

EXEMPLE: MON CODE ARDUINO EN EXÉCUTION

¢ Code non fourni !

RÉFÉRENCES: INTERUPT TIMERS, DDS

¢ http://rcarduino.blogspot.ca/2012/12/arduino-due-dds-part-1-sinewaves-and.html

¢ http://coolarduino.blogspot.ca/2015/07/fast-sampling-with-arduino-due.html

¢ http://arduino-er.blogspot.ca/2013/04/implement-timer-interrupt-for-arduino.html

¢ http://2manyprojects.net/timer-interrupts

RÉFÉRENCES: ADC

¢ http://asf.atmel.com/docs/3.21.0/sam3s/html/sam_adc_quickstart.html

¢ http://asf.atmel.com/docs/3.21.0/sam3s/html/index.html

¢ http://www.atmel.com/Images/Atmel-42109-SAM-Analog-to-Digital-Converter-ADC-Driver_ApplicationNote_AT03243.pdf

¢ http://www.atmel.com/Images/Atmel-42298-SAM3-4S-4C-Analog-to-digital-Converter-ADC_ApplicationNote_AT06860.pdf

¢ http://asf.atmel.com/docs/3.0.1/sam.drivers.adc.adc_example.arduino_due_x/html/adc_8h_source.html

REFERENCES: ADC, ATMEL

¢ http://asf.atmel.com/docs/3.0.1/sam3x/html/group___s_a_m3_x_a___a_d_c.html

¢ http://www.atmel.com/Images/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf

¢ http://nicecircuits.com/playing-with-analog-to-digital-converter-on-arduino-due/