AVR/atmega8 pinnen constant hoog & code optimalisatie vraag

Hallo allemaal,
Het leek me leuk een nixie klok te gaan bouwen met het DCF77 atoomklok radiosignaal voor de klok. Ik had op een site gezien dat een Atmega8 daar goed voor te gebruiken is. Ik ben echter helemaal nieuw wbt AVR en dergelijke dus er zijn een aantal dingen die ik niet helemaal begrijp (programmeren kan ik al wel op beginnersniveau maar heb het nog nooit op hardware toegepast).

Ik heb een simpele breadboard opstelling met een ledje dat moet knipperen als ik 5 volt op PD1 zet. Hiervoor heb ik een programmatje met WinAVR geschreven en het met ponyprog op de Atmega8 gezet. init() Zet PB1 als uitgang en blinking() maakt de poort afwisselend hoog en laag zodat de aangekoppelde led gaat knipperen. Hier de code:

int main(void)
{
   init();
   while(1)
   {
	if(bit_is_set(PIND,1))
	{
	   blinking(3);
	}
    }

}

Tot zover gaat alles goed, en in de simulatie van AVR Studio werk het ook zoals ik bedacht had.

Het eerste probleem is dat om de een of andere reden mijn pinnen altijd hoog lijken te zijn. Ik hoef de reset ook niet met een pull up te verbinden, hij doet het gewoon. Zodra ik de reset met de 0 volt verbind reset hij zich pas daadwerkelijk.
Pin B1 is ook steeds hoog, dus het ledje knippert constant en gaat pas uit als ik hem op de 0 volt zet.
Als ik hem door wil meten met mijn multimeter gaat het ledje ook uit en geeft de multimeter ook zoals werwacht 0 volt aan.
Ik heb nog even getest met de interne pull up aanzetten (PORTD = 0xFF), dan staat er inderdaad +5V op de pinnen als ik het meet en werkt hij verder nog hetzelfde.

De vraag dus: is dit een gevolg zijn van het monteren op een simpel breadboard of kan er iets anders aan de hand zijn?

Dan nog een andere programmeer vraag. Ik ben zelf Java gewend en weet dus niet of dit 'typisch C gedrag' is.
De blinking() method is als volgt

void blinking(int times)
{
	int i = 0;	
	int msec = 500;
	while(i<times)
	{
                
                /* set output to 5V, LED on */
                PORTB|= _BV(PB1);
                _delay_ms(msec);
				
				/* led off, pin=0 */
                PORTB&= ~_BV(PB1);
                _delay_ms(msec);
		i++;
    }
	
}

Times is het aantal keer dat de led moet knipperen als de method opgeroepen wordt. msec is het aantal miliseconden dat de led aan moet zijn 'per knipper'.
Ik weet trouwens dat int gebruik niet zo efficient is hier wegens kleine getallen maar da's gewoon gemakshalve, en de for loop deed niet gelijk wat ik wilde dus handmatig met de i teller.

Maak ik daar nou van

void blinking(int times, int msec)
(...)
//int msec = 500;
(...)

Dus msec aangeven in de method call en weg gecomment in de code, dan neemt mijn code ineens van 158 bytes (1,9% full) naar 3592 (43,8%) in grootte toe. Dit is vergelijkbaar met de grootte van mijn eerste code als ik de optimization op -O0 zet ipv -O1. Er gaat denk ik dus iets mis met de optimalisatie, maar ik heb geen idee wat dat kan zijn of hoe ik het moet oplossen.

Bedankt voor jullie tijd en eventuele hulp :)

De reset heeft intern een zwakke pull-up, zonder deze aan te sluiten zal die dus altijd hoog zijn.

De overige poorten laat je blijkbaar zweven. De toestand van een zwevende poort is onvoorspelbaar. Daarom hebben AVRs op alle poorten configureerbare pull-ups. Met de pull-ups aan weet je zeker dat je poort in een stabiele toestand blijft, ook als er niets is aangesloten. Sluit je nu een schakelaar aan, schakel de poort dan naar massa. De logica is dan wel net andersom. Schakelaar uit geeft een 1 en schakelaar aan geeft een 0. In de software kan je dat makkelijk omdraaien door bit_is_clear(..) te gebruiken.

Wat betreft code optimalisatie gebruik ik altijd -Os (optimize for size)

Dankje Marcel. Ik ben van het computer programmeren gewoon dat waarden absoluut zijn dus ik dacht ik dat de poorten laag zouden zijn tenzij ik anders programmeerde, zweven kende ik nog niet.
Hij doet het nu inderdaad zoals het moet in 'in het echt', de AVR Studio simultator doet juist het verkeerde.

De Os switch maakt helaas geen verschil. Ik heb nog wat verder getest ook, in de init method kan ik zoveel ints toevoegen als ik maar wil, de code word niet groter. Bij de knipper method gebeurt het sowieso, ook als ik de naam van de method en de variabelen verander.

Ik ga nog even kijken wat hij doet met wat extra methods erbij.

Ik optimaliseer --net als Marcel-- ook steeds met -Os. Iets als -O1 valt misschien te overwegen als je een relatief klein programma hebt, dat zo snel mogelijk moet lopen. Denk ik.
Let ook op met floating-point stuff. 1 enkele floating-point bewerking blaast je code immens op.
Er was ook iets met _delay_ms(). Dat vergt in principe een float als argument, maar als je voor "size" optimaliseert, voert avr-gcc wat magie uit zodat er in werkelijkheid met int's gewerkt wordt. Als je niet voor "size" optimaliseert, zit de kans er in dat er met floats gewerkt wordt. Andermaal: denk ik. :-)

Ben ook bezig nixebuizen via een Atmega8 op een DCF77-module te laten werekn.
Heb de nixies nu multiplexen en uren/minuten deel van DCF77 binnen.
Hoever ben jij?
Is uitwisseling programmadelen mogelijk?
Succes verder

Op 4 oktober 2007 13:31:31 schreef grantoptions:
Ben ook bezig nixebuizen via een Atmega8 op een DCF77-module te laten werekn.
Heb de nixies nu multiplexen en uren/minuten deel van DCF77 binnen.
Hoever ben jij?
Is uitwisseling programmadelen mogelijk?
Succes verder

Hey, Ik heb het belachelijk druk met verslagen schrijven sinds dat het studiejaar begonnen is, ben al blij als ik even 2 uurtjes niets te doen heb. Dus heb geen tijd gehad om uberhaupt iets te doen, moet zelfs de nixie's nog bestellen. Over 3 weken heb ik weer wat tijd, dan wilde ik gaan beginnen.
Groetjes

OK. Heb gelijke problemen. Laten we er later weer contact over hebben.
Grt.