Programmation embarquée

De fablabo
Révision de 21 mars 2014 à 14:01 par Cedric (discussion | contributions) (des histoires d'horloge)

Aller à : navigation, rechercher

résumé

le TP de la semaine de la fabacademy consiste à se familiariser avec la programmation de microcontroleurs et processeurs.

je vais commencer par programmer les deux circuits que j'ai réalisé : le FabISP et le helloWorld


premiers pas

La première étape est de finir mon travail en retard sur le fabISP : comme j'attendais l'arrivée des composants, je n'ai pas eu le temps de programmer le circuit à temps. De plus je ne comprenais pas bien la logique d'alimentation du circuit : je croyais que le programmateur alimentait la puce cible alors qu'il fallait qu'elle le soit séparément...

cette fois ça marche en suivant le protocole du tutoriel

make -f hello.ftdi.44.echo.c.make avr-objcopy -O ihex hello.ftdi.44.echo.out hello.ftdi.44.echo.c.hex;\ avr-size --mcu=attiny44 --format=avr hello.ftdi.44.echo.out AVR Memory Usage


Device: attiny44

Program: 776 bytes (18.9% Full) (.text + .data + .bootloader)

Data: 64 bytes (25.0% Full) (.data + .bss + .noinit)


cedric@cedric-Inspiron-5520 ~/fabacademy/electronicDesign/programming $ make -f hello.ftdi.44.echo.c.make program-avrisp2-fuses avr-objcopy -O ihex hello.ftdi.44.echo.out hello.ftdi.44.echo.c.hex;\ avr-size --mcu=attiny44 --format=avr hello.ftdi.44.echo.out AVR Memory Usage


Device: attiny44

Program: 776 bytes (18.9% Full) (.text + .data + .bootloader)

Data: 64 bytes (25.0% Full) (.data + .bss + .noinit)


avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x5E:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9207 avrdude: reading input file "0x5E" avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written avrdude: verifying lfuse memory against 0x5E: avrdude: load data lfuse data from input file 0x5E: avrdude: input file 0x5E contains 1 bytes avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ... avrdude: 1 bytes of lfuse verified

avrdude: safemode: Fuses OK

avrdude done. Thank you.

$ make -f hello.ftdi.44.echo.c.make program-avrisp2 avr-objcopy -O ihex hello.ftdi.44.echo.out hello.ftdi.44.echo.c.hex;\ avr-size --mcu=attiny44 --format=avr hello.ftdi.44.echo.out AVR Memory Usage


Device: attiny44

Program: 776 bytes (18.9% Full) (.text + .data + .bootloader)

Data: 64 bytes (25.0% Full) (.data + .bss + .noinit)


avrdude -p t44 -P usb -c avrisp2 -U flash:w:hello.ftdi.44.echo.c.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9207 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

        To disable this feature, specify the -D option.

avrdude: erasing chip avrdude: reading input file "hello.ftdi.44.echo.c.hex" avrdude: input file hello.ftdi.44.echo.c.hex auto detected as Intel Hex avrdude: writing flash (776 bytes):

Writing | ################################################## | 100% 0.27s

avrdude: 776 bytes of flash written avrdude: verifying flash memory against hello.ftdi.44.echo.c.hex: avrdude: load data flash data from input file hello.ftdi.44.echo.c.hex: avrdude: input file hello.ftdi.44.echo.c.hex auto detected as Intel Hex avrdude: input file hello.ftdi.44.echo.c.hex contains 776 bytes avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.23s

avrdude: verifying ... avrdude: 776 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done. Thank you.



Par contre, le programme ne répond pas par le port série.

en explorant les différents codes, j'ai trouvé dans http://academy.cba.mit.edu/classes/embedded_programming/hello.ftdi.44.echo.interrupt.c

un commentaire de neil : "set lfuse to 0x7E for 20 MHz xtal"

or dans la makefile que j'ai utilisé, le fuse est seté à 0x5E

j'essaye de comprendre le datasheet pour résoudre ce probleme...

Dans le datasheet, il est question de la calibration de l'oscilateur: "...OSCCAL = 0x7F gives a higher frequency than OSCCAL = 0x80..."


je n'ai pas réussi à décoder exactement le code pour comprendre à quoi correspond ce setting mais je vois qu'il est question de selectionner l'external clock et le multiple de l'horloge.

En tous cas, le circuit fonctionne : je peux commencer à essayer de la programmer

il suffit de modifier le makefile en remplaçant :


program-avrisp2-fuses: $(PROJECT).hex avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x5E:m


par


program-avrisp2-fuses: $(PROJECT).hex avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x7F:m



en assembleur

j'ai choisi la facilité : au lieu d'écrire en hexadécimal, je vais utiliser l'assembleur...

En partant de l'exemple de Neil, je vais essayer de faire un clignoter ma led.

je commence à lire le programme et je trouve :

ldi temp, (1 << CLKPCE) ldi temp1, (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0)

en lisant le datasheet, je comprends que :

'ldi = load immediate


(p30) CLKPCE=1 : Clock Prescaler Change Enable

(0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0) : Clock prescaler select : Clock division factor = 1

donc logiquement, le systeme doit fonctionner à la fréquence du quarts (qui est l'orloge externe : 20mhz)

compilation

il faut avoir téléchargé le compilateur gavrasm


j'arrive à compiler mon code, mais la led ne clignote pas...

quelques pistes sur l'assembleur

http://www.unixgarden.com/index.php/gnu-linux-magazine/coder-pour-atmel-attiny


le guide assembleur AVR


des histoires d'horloge

voici ma boucle de délai :

delai:

  ;ldi temp, 255; max
  ;clr temp
  delay_loop:
     dec temp 
     clr temp1  
     delay_loop2:
       dec temp1
       clr temp2

delay_loop3:

         dec temp2
         brne delay_loop3 
       brne delay_loop2 
     brne delay_loop
  ret


malgré une boucle de délai conséquente (255^3), je ne voyais pas la led clignoter.

pourtant 255*255*255=16581375 cycles

et l'horloge tourne à 20Mhz, soit un cycle toutes les 1/20000000=0,00000005 sec

donc logiquement ma boucle devrai faire :

16581375*0,00000005=0,8s

or je ne vois pas le clignotement.

Par contre en changeant le diviseur de l'horloge à 256

ldi temp, (1 << CLKPCE) ldi temp1, (1 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);/256 out CLKPR, temp out CLKPR, temp1

le clignotement est apparent et dure à peu près la durée prévue. J'ai donc fait des erreurs de calcul?