Min C kod fungerar inte (AVR)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Min C kod fungerar inte (AVR)

Inlägg av johano »

BTW, det verkar vara ett trevligt kort det där, finns det några kvar till försäljning?

johan
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Re: Min C kod fungerar inte (AVR)

Inlägg av thepirateboy »

Ja, jag har två till och får troligen in fler under nästa vecka.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Min C kod fungerar inte (AVR)

Inlägg av johano »

Du har pm

/johan
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Min C kod fungerar inte (AVR)

Inlägg av sodjan »

> För att jag har ändrat till portd.

Ja, *nu* ja !
Min kommentar avsåg naturligstvis den kod du hade postat och
som fanns tillgänglig när jag gjorde kommentaren.

Och även då du skrev "Den gör väl portd till utgång?" så fanns det ingen
annan kod än den där det stog "DDRC = 0xff; //Sätter portb till utgång".

Slutligen, min kommentar har inte ett smack med viss port att göra igentligen, det hela
handlade om att du satte DDR *C* i instruktionen men nämner PORT *B* i kommentaren !

Att det var just C och B är ointressant, att det var *olika* var det viktiga och slarviga.
Det verkar du fortfarande ha kollosalt svårt att förstå...
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Min C kod fungerar inte (AVR)

Inlägg av jesse »

sodjan skrev:> _delay_ms(2000) brukar ge en fördröjning på 2 sekunder, inte 0.2 sekunder.

Det jag har hittat om _delay_ms() är att om man överskrider maxvärdet
för parametern så kommer den att börja räkna parametern som 1/10 ms.
Alltså 0.2 sek med 2000 som parameter.
The maximal possible delay is 262.14 ms / F_CPU in MHz.

When the user request delay which exceed the maximum possible one, _delay_ms() provides
a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of
1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency).
The user will not be informed about decreased resolution.
Men det kanske är en annan _delay_ms() som jag har hittat...

Å andra sidan så lär det inte hjälpa om lysdioden sitter på fel pinne i alla fall...
Det är fortfarande något här som jag inte fattar? Eller, jo... nej :(

Jag simulerade delay_ms(200), delay_ms(300) och delay_ms(2000) för F_CPU=1 MHz.
Vid 200 fick jag en fördröjning på exakt 200 ms. Vid 300 fick jag 312 ms och (2000) gav 2080 ms fördröjning. Det verkar vara fel när de säger " with a resolution of 1/10 ms"??? Hur uppnår jag det? Den där maxgränsen begriper jag inte. Jag får samma resultat om jag sätter F_CPU till 20 MHz
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Re: Min C kod fungerar inte (AVR)

Inlägg av thepirateboy »

Blir det någon förändring om du ändrar optimeringen (-Os, -O2 osv)?
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Min C kod fungerar inte (AVR)

Inlägg av jesse »

Det ska man inte göra - för då blir det fel, enligt lib-instruktionerna.
Det ska alltid vara -Os
-02 ger dock samma resultat, utan optimering blir det lite bara fel: 203.42 ms...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Min C kod fungerar inte (AVR)

Inlägg av sodjan »

Nej, jag fattar inte heller hur man korrekt ska tolka beskrivningen av _delay_ms()...

Men å andra sidan så finns/fanns det större problem med koden så den kanske
inte spelar så stor roll... :-)
Muppis
Inlägg: 275
Blev medlem: 15 februari 2007, 10:26:28
Ort: Halmstad

Re: Min C kod fungerar inte (AVR)

Inlägg av Muppis »

Värt att tänka på är att Windows har en upplösning på 10ms i sina timers.
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Min C kod fungerar inte (AVR)

Inlägg av SvenW »

För er som inte har koden hemma:
(Flyttalsoperationerna sker i kompilatorn och tar inga
resurser i AVR-processorn)

Kod: Markera allt

/**
   \ingroup util_delay

   Perform a delay of \c __ms milliseconds, using _delay_loop_2().

   The macro F_CPU is supposed to be defined to a
   constant defining the CPU clock frequency (in Hertz).

   The maximal possible delay is 262.14 ms / F_CPU in MHz.

   When the user request delay which exceed the maximum possible one,
   _delay_ms() provides a decreased resolution functionality. In this
   mode _delay_ms() will work with a resolution of 1/10 ms, providing
   delays up to 6.5535 seconds (independent from CPU frequency).  The
   user will not be informed about decreased resolution.
 */
void
_delay_ms(double __ms)
{
	uint16_t __ticks;
	double __tmp = ((F_CPU) / 4e3) * __ms;
	if (__tmp < 1.0)
		__ticks = 1;
	else if (__tmp > 65535)
	{
		//	__ticks = requested delay in 1/10 ms
		__ticks = (uint16_t) (__ms * 10.0);
		while(__ticks)
		{
			// wait 1/10 ms
			_delay_loop_2(((F_CPU) / 4e3) / 10);
			__ticks --;
		}
		return;
	}
	else
		__ticks = (uint16_t)__tmp;
	_delay_loop_2(__ticks);
}

#endif /* _UTIL_DELAY_H_ */

Kod: Markera allt

/** \ingroup util_delay_basic

    Delay loop using a 16-bit counter \c __count, so up to 65536
    iterations are possible.  (The value 65536 would have to be
    passed as 0.)  The loop executes four CPU cycles per iteration,
    not including the overhead the compiler requires to setup the
    counter register pair.

    Thus, at a CPU speed of 1 MHz, delays of up to about 262.1
    milliseconds can be achieved.
 */
void
_delay_loop_2(uint16_t __count)
{
	__asm__ volatile (
		"1: sbiw %0,1" "\n\t"
		"brne 1b"
		: "=w" (__count)
		: "0" (__count)
	);
}

#endif /* _UTIL_DELAY_BASIC_H_ */

monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Min C kod fungerar inte (AVR)

Inlägg av monstrum »

Varför hålla på att försöka få fruktansvärt exakta delay-funktioner? För mig känns det helt orelevant ifall delay(1000) ger fördröjning 1,0 s eller 1,1 s.
Ska man ha en exakt fördröjning så använder man en hårdvaru-timer alternativt en mjukvarubaserad dito som utgår från en kontinuerlig interrupt-timer.
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Min C kod fungerar inte (AVR)

Inlägg av Icecap »

Jag kan bara hålla med, visst behövs delay lite då och då men att ha dessa problem med dessa funktioner fattar jag helt enkelt inte.

Jag startar alltid en timer-interrupt som fungerar till det jag behöver, det har hänt i enstaka fall att jag har stoppat ett program en viss tid (t.ex. visande en sign-on på ett display efter initiering) men jag har aldrig använd delay() till sånt.

I vissa fall där man ska testa en viss enkel funktion kan det vara vettigt att använda sånt men aldrig i en skarp version!
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Min C kod fungerar inte (AVR)

Inlägg av jesse »

För mig känns det helt orelevant ifall delay(1000) ger fördröjning 1,0 s eller 1,1 s.
Nu var väl problemet att _delay_ms(2000) kunde ge en fördröjning på 200ms istället för 2000 enligt vissa inlägg här? Det är ju en viss skillnad. Dessutom så finns det ju ingen som helst anledning varför _delay_ms(1000) skulle ge en fördröjning på 1100 ms. Så värdelösa är faktiskt inte dessa fördröjningsrutiner. Noggrannheten är givetvis 1 ms och inget annat. Så visst ska man kunna använda sig av dessa och kunna lita på dem.
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: Min C kod fungerar inte (AVR)

Inlägg av stekern »

I vissa fall kan dessa _delay rutiner dessutom bli nogrannare än att köra med timer interrupt, i och med bortsparning på stacken.
(detta går givetvis att rundgå genom att skriva timer isren i asm, men då ska man kunna hålla tungan rätt i mun).
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Min C kod fungerar inte (AVR)

Inlägg av Icecap »

Jag har aldrig varit i en situation där det är viktigt att ett 2 sek delay är exakt 2 sek, när man når den storlek är det alltid på ett ungefär och ska det vara exakt går det att skriva ISR'n så att latensen är ganska liten.

Min erfarenhet är att användandet av _delay() nästan uteslutande sker hos oerfarna programmerare, inget ont i det men när de mer vana går ifrån det är det kanske an anledning...

Själva delay-funktionen använder man ju lite varstans, lekar man t.ex. med 1-Wire är delay ju totalt oumbärligt men även där kan man leka lite. Jag gjorde t.ex. en avläsning av temperatur som körde i min 10Hz timer-ISR.

För att sända en '1' ska man ju dra datalinjen '0' kortvarigt och sedan '1', ska man sända '0' ska man hålla datalinjen '0' i längre tid.
Jag löste det vid att göra en sekvensstyring som startade med att lägga '0' ut.

Sedan gjorde jag lite annat som gick snabbt och kollade sedan om det skulle vara en '1' eller '0', skulle det vara en '1' höjde jag datalinjen. sedan gjorde jag färdigt i ISR'n och slutade med att lägga en '1' ut på datalinjen.

På detta vis gjorde jag annat under tiden som 1-Wire funktionen kördes och det kostade väldigt lite ISR-tid - och fungerade perfekt.

Visst tog det en del interrupts (= tid) men temperaturen ändras inte speciellt snabbt så det var knappast ett större problem, jag hade knappast extra overhead och det kör fortfarande efter vad jag vet. Används i 2 textskyltar, ett i Svappavaara och ett i Abisko/Björkliden.
Skriv svar