Programmation embarquée : Différence entre versions
(→désynchronisation) |
(→désynchronisation) |
||
Ligne 285 : | Ligne 285 : | ||
l'horloge tourne à 20mhz mais est divisée par 256, donc elle fait 20000000/256=78125 cycles/sec | l'horloge tourne à 20mhz mais est divisée par 256, donc elle fait 20000000/256=78125 cycles/sec | ||
− | donc un cycle dure = 1/78125=0,0000128 sec | + | donc un cycle dure = 1/78125 = 0,0000128 sec = 12,8 microsecondes |
[[Catégorie:FabAcademy]] | [[Catégorie:FabAcademy]] |
Version du 21 mars 2014 à 14:09
Sommaire
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
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?
désynchronisation
J'ai enfin réussi à faire clignoter la led, mais depuis, j'ai perdu mon tiny !
si j'essaye de le reprogrammer, j'ai :
make -f hello.ftdi.44.blink.asm.make program-avrisp2
avrdude -p t44 -P usb -c avrisp2 -U flash:w:hello.ftdi.44.blink.hex
avrdude: stk500v2_command(): command failed avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Unknown status 0x00 avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override this check.
avrdude done. Thank you.
make: *** [program-avrisp2] Erreur 1
Sur les conseils de Neil, j'essaye d'utiliser l'option "-i" de avrdude , qui spécifie la délai en microsecondes entre chaque changement de bit.
-i delay For bitbang-type programmers, delay for approximately delay microseconds between each bit state change. If the host system is very fast, or the target runs off a slow clock (like a 32 kHz crystal, or the 128 kHz internal RC oscilla‐ tor), this can become necessary to satisfy the requirement that the ISP clock frequency must not be higher than 1/4 of the CPU clock frequency.
Si je continue mes mauvais calculs :
l'horloge tourne à 20mhz mais est divisée par 256, donc elle fait 20000000/256=78125 cycles/sec
donc un cycle dure = 1/78125 = 0,0000128 sec = 12,8 microsecondes