Hallo,

Ik zou graag mbv ImageCraft AVR (iccarv) een delay loop maken van bijvoorbeeld 200ms in C.
Weet iemand hoe ik dit kan doen zonder gebruik te maken van een timer(interrupt), maar bijvoorbleed mbv meerdere for-loops. Misschien kan aan de hand van een formule uitgerekend worden hoeveel for-loops nodig zijn.

Ik maak gebruik van een ATTiny2313 op 8 MHZ.

Groet,

Martijn

Heeft ImageCraft daar geen library functies voor dan? Het gratis AVR-GCC heeft die wel.

AVR's zijn (bijna) volledig Risc. Dus 1 instructie per clock cyclus. Tel uit je winst op 8 Mhz!
Ik ken de imagecraft compiler niet maar kijk ff in de assembly hoeveel instructies voor de for loop gebruikt worden en tel uit hoeveel keer je moet NOP'en.

Tip: Start Programma's Accessoires , Rekenmachine :-)

dus elke instructie duurt 1/8 millioenste seconde zal wel 125 nSec zijn zeker zo uit t hoofd :P

Op 3 december 2005 00:38:20 schreef lucy:
dus elke instructie duurt 1/8 millioenste seconde zal wel 125 nSec zijn zeker zo uit t hoofd :P

Branch instructies duren meer dan 1 klokpuls i.v.m. het flushen van de pipe line.
Daarnaast is het geen specifieke eigenschap van een RISC processor om met elke klokpuls 1 instructie af te handelen.
Het is eerder dat de meeste instructies ongeveer dezelfde executie tijd hebben.

In AVR-studio maakt de disassembler dit daarvan


5:          for(i = 0; i < 0xC000; i++);
+00000030:   8219        STD     Y+1,R1           Store indirect with displacement
+00000031:   821A        STD     Y+2,R1           Store indirect with displacement
+00000032:   8189        LDD     R24,Y+1          Load indirect with displacement
+00000033:   819A        LDD     R25,Y+2          Load indirect with displacement
+00000034:   EC20        LDI     R18,0xC0         Load immediate
+00000035:   3080        CPI     R24,0x00         Compare with immediate
+00000036:   0792        CPC     R25,R18          Compare with carry
+00000037:   F430        BRCC    PC+0x07          Branch if carry cleared
+00000038:   8189        LDD     R24,Y+1          Load indirect with displacement
+00000039:   819A        LDD     R25,Y+2          Load indirect with displacement
+0000003A:   9601        ADIW    R24,0x01         Add immediate to word
+0000003B:   8389        STD     Y+1,R24          Store indirect with displacement
+0000003C:   839A        STD     Y+2,R25          Store indirect with displacement
+0000003D:   CFF4        RJMP    PC-0x000B        Relative jump

Denk je nu nog steeds dat het zo makkelijk is?
Het is niet voor niets dat er library functies voor bestaan.

Ja,wat is er zo moeilijk aan optellen ??
(er stond trouwens bijna risc :-" )

7 for (a=0;a<10;a++)
\ 00000000 E000 LDI R16,LOW(0)
\ ?0001:
\ 00000002 300A CPI R16,LOW(10)
\ 00000004 F418 BRCC ?0000
8 {
9 _NOP();
\ 00000006 0000 NOP
\ 00000008 9503 INC R16
10 }
11 }
\ 0000000A CFFB RJMP ?0001
\ ?0000:
\ 0000000C 9508 RET
\ END

[Bericht gewijzigd door lucy op ]

Mijn reactie was direct gericht op Andy, die zonder verder commentaar hier een for loopje dumpt. Maar als je ziet hoe dat for loopje (met in dit geval AVRGCC) wordt omgezet naar machinecode. Dan is het duidelijk (door te tellen inderdaad) dat elke loop 12 instructies kost. De gehele loop neemt dus 49152 (=0xC000) * 12 = 598824 instructies. Op 8MHz is dat 74ms. Bij lange na dus niet de gewenste 200ms.

Maar dit is een hele omslachtige methode. Je schrijft eerst de C code en dan kijk je hoeveel instructies die in beslag neemt en vervolgens pas je je loop daarop aan. Dat doe je toch niet als je weet dat daar library functies voor bestaan. Waarvan of het aantal cycly bekend is of zelfs door de pre-compiler uitgerekend word.

Marcel,dat klopt niet echt. Ik heb de simulatie gedaan met AVR Studio 4 en kwam zelfs ietsje meer dan 200ms uit.
De reden waarom er zoveel code gebruikt wordt door de compiler is omdat ik i als int had gedeclareerd. Als je kortere code wil dan kun je 2 lussen nesten, maar dat was de oorspronkelijke vraag niet dacht ik en ook werd er niet meegegeven hoeveel lijnen assemblercode het maximaal mochten zijn. Daarbij komt nog dat meedere instructies 2 clockcycli nodig hebben (STD, LDD, LDI, BRCC (1/2), ADIW,...) doe je berekening nog maar eens of laat het is in AVR Studio 4 lopen en bekijk het resultaat maar eens.

Yup , er zijn programmeurs die weten waar ze het over hebben, Andy, en er zijn van die high level vertalers/tolken die libs moeten hebben om simpele dingen te doen. Zullen we t daarbij houden ?
Ik ga zwijgen over die met instructies die 2 clockcycli in beslag nemen maar toch bijna even lang duren als die van 1 clock cyclus :P (of heeft die een variabele clock op zijn AVR, speciale hardware revisie of zo? ) hihihi ze duren bijna even lang , maar je mag daar niet op rekenen als je timing routines uitrekent want sommige duren dan wel even lang maar nemen meer dan 1 clock cyclus in beslag. das wel heel erg 'fuzzy' logic :-)

Zoals Andy t zegt is netjes opgelost.
for loopjes met unsigned chars (8 bit controller mijnheer)
, je maakt een loopje van 1ms (als je wil - 3 instructies)
en roept dat 200 keer aan. Simpel efficient klein reproduceerbaar en voorspelbaar , geen scoop nodig om die 1 mSec te maken.....

Andy's voorbeeld in AVR studio geeft dit resultaat http://expand.xs4all.nl/uploadarchief/download.do?file=for_loop_timing… Anders dan mijn berekende waarde, maar zeker geen 200ms.

Zo blijk maar weer dat een op deze manier opgebouwde delay absoluut niet overdraagbaar is. Zoals al vermeld gebruikte ik hiervoor AVRGCC. Ik ben nu wel benieuwd welke compiler Andy gebruikt. Overigens is niet alleen het soort compiler van invloed. Ook kunnen er grote verschillen zijn tussen verschillende versies en configuratie instellingen van dezelfde compiler. Reden om een dergelijk oplossing zeker niet te willen gebruiken in een bedrijfsomgeving of waar dan ook, waar het mogelijk is dat verschillende personen met verschillende compilers (qua type, versie of config) werken. Kom ik weer terug op de library routine waarvan de werking gegarandeerd is. Natuurlijk kan je ook zelf een stukje inline assembler maken, maar was het nou juist niet de reden van het programmeren in C dat je zo min mogelijk met assembler bezig houd.

Nu kan lucy me wel gaan uitmaken voor een programmeur die niet weet waarover hij het heeft. Wat een bijzondere lage manier van discussieren is. Ik had bij het tellen van cycly inderdaad geen rekening gehouden met feit dat bepaalde instructies meerdere cycly kosten. Ik was namelijk in de veronderstelling dat AVR studio dat netjes zou aangeven.

Marcel, ik heb de zoals de steller aangegeven ImageCraft complier gebruikt met de standaardinstellingen en zonder optimalisatie. Dit kan idd. de verwerkingstijd wel beinvloeden. Ik heb enkele het principe willen aangeven hoe zulk een timing in C kon gemaakt worden en heb nooit een absolute waarde willen aangeven voor deze tijdslus. Met wat finetuning, moet ge tot een vrij benaderend resultaat kunnen komen.

Mijn resultaat met ICAVR = 202755,125 microsec. Toch aardig in de buurt.