ATMega32 och massor med interuppt

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Det hela beror på hur man vill att hela applikationan skall fungera.

Och om det är OK att processorn gör "en sak i taget". D.v.s t.ex under tiden som ett "kommando" sänds, så gör man inget annat. Det beror också på om man tror att det kommer att finnas delar i konstruktionen som man tidsmässigt inte har full kontroll över, t.ex om man vill kompletterar med ett seriellt gränssnitt för att kunna sända texter från en PC (skulle inte förvåna mig om man ganska snart vill komplettera med det, även om det inte finns med i först versionen), så underlätter det betydligt om man redan från början har byggt det hela runt en arkitektur som gör att USART rutiner kan "pluggas in" utan att störa den befintliga koden allt för mycket.

Normalt betyder detta en interruptstyrd grund med korta/snabba ISR's för de olika delarna, och en pollande main loop där man sedan tar hand om den icke tidskritiska bearbetningen. T.ex så används USART-receive ISR'en bara till att hämta inkommen byte till en buffert och sätta en flagga som signalerar att ny data finns i bufferten. Main loopen pollar denna flagga (tillsammans med andra flaggor från andra ISRs), och tar sedan ta hand om den bearbetningen som behövs. På så sätt är det ganska enkelt att plugga in nya funktionallitet, lägg till en ISR, fixa en ny flagga, komplettera main loopen med en poll på flaggan och ett CALL till bearbetningen.

En annan sak är att aldrig används programvara om det finns härdvara i processorn som gör samma sak bättre och enklare. T.ex att använda PWM modulen för att generera 38 Khz bärvågen istället för timade loopar.

När det gäller att interrupt kan "störa" övrig bearbetning, så är det ju det som är hela finessen med interrupt ! :-) Om det sedan finns (korta!) kodsegment som absolut inte får avbrytas, så är det ju bara att tillfälligt stänga av interrupten. Inget speciellt konstigt med det.

PIC18 har interrupt i två prio-nivåer, men de flesta använder det inte. Om man ser till att ingen ISR exekverar längre en den längsta accepterade fördröjningen för *något* av interrupten, så är det inget problem i alla fall. Det är bara att låta interrupten köras efter varandra även om två eller flera interrupt skulle råka inträffa "samtidigt".

Nåväl, det hela handlar i grunden om att hitta en applikationsarkitektur som man tror kommer att fungera både för behoven i "Rev 1A", och som även kommer att fungera när man lägger till ytterligare funktioner.

Det är väldigt enkelt att skriva en enkel loop som generar en 38 Khz signal, och om detta är det *enda* som processorn skall göra, så är det väll OK... :-)
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Visst ligger det mycket i det du säger Sodjan, men jag tycker det beror lite på vilken nivå man ligger som programmerare/utvecklare också. Du märker ju ungefär vilken nivå virr3 ligger på. (absolut inget illa menat, alla har vi varit nybörjare och velat lära oss) Men som sagt så kan den enkla approachen vara den rätta i vissa lägen. Märker du senare att du vill uppgradera funktionerna på din pryl men mjukvaran inte tillåter detta, ja, då har du lärt dig det och kommer förmodligen ha detta i åtanke nästa gång du kör igång ett projekt.

jag tror inte att dina första uC-projekt var helt interruptdrivna ;)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> jag tror inte att dina första uC-projekt var helt interruptdrivna

Men kanske borde ha varit det. :-) :-)
Men visst, du har naturligtsvis en poäng.
Jag ville väll mest bara sätta det hela i lite perspektiv...
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

okej.. tack allahopa :)

det ska komma i denna ordningen:

först skriver man in vad man nu vill få upp på ledsnurran på tangentbordet, detta ska komma upp så snart som möjligt(häls precis sammtidigt som man skriver) sen när man skrivit vad man nu tycker är lämpligt och sen tryckt på enter så ska hela faderullan över till andra µC:n och överföra koden till leldsnurran...

jag vet inte riktigt vad som är lämpligast att göra, att lära sig timern nu så att man kan de till senare projekt eller om man ska vänta lite...

jag tycker att den pwm koden som frejo skickade verkade helt okej faktiskt, det enda jag inte fatta 100 i den va vad dutycycle betyder men...
det borde ju inte va speciellt svårt att ta reda på tycker man...
har läst nått om de i databladet så...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

"Duty cycle" är förhållandet mellan "on" och "off" (eller hög/låg) i PWM signalen. Mäts normalt i 0-100% där 50% är en symetrisk fyrkantssignal.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

det måste betyda att dutycykel:n har en beroende roll av vilken frekvens det blir?
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

okej, nu har ja kopplat upp allt och skrivit en liten kodsnutt..

men, det funkar inte (trött man blir :cry:)

aja, får la fråga här igen...

jag tror de ä koden det är fel på för hela avr:en beter sig helkonstigt...

så här har jag kopplat(AVR:ATMega32):

PD7 sitter som strömförsörjning till ir-lysdioden(har ett motstånd mellan med) (bärvåg på 38khz)...
PC0 sitter som strömförsörjning till ir-mottagaren
PC2 sitter som strömförsörjning till en lysdiod
PA7 sitter utgången från motagaren till

när jag mätte fick jag:
PD7: 0,97v
PC0: 0v
PC2: 0,45v
PA7: 0v

antar att man igentligen inte ska använda utgångarna som strömförsörjning utan ha de till en transistor som sen är kopplad till strömförsörjning men ville göra det snabbt för mig såhär på kvällen, bara för att testa...
koden jag använt ser ut såhär:

Kod: Markera allt

#include <avr/io.h>
#include <avr/delay.h>

void ask(uint16_t antal_perioder);

int main(void)
{      
   DDRD = _BV(PD7) || _BV(PC0);
   
   
   while(1)
   {
   PORTC |=  _BV(PD7);
   PORTC |=  _BV(PC0);
   if (PINA & _BV(PA2)) 
        {
            PORTC |=  _BV(PC2);
        } 
		
    ask(65000);
	
   }
}


void ask(uint16_t antal_perioder)
{
   for(int i=0; i<antal_perioder; i++)
   {
      PORTD |= (7<<PD7);
      _delay_us(13);
      PORTD &= ~(7<<PD7);
      _delay_us(13);
   }
} 
skulle bli mycket glad ifall någon skulle villja hjälpa mig än en gång :oops:
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Jag ser 1 fel på en gång nämligen
DDRD = _BV(PD7) || _BV(PC0);

Det borde vara:
DDRD = _BV(PD7);
DDRC = _BV(PC0);

En lite bild på hur du ha koplat, skulle kunna hjälpa om vi ska hjälpa dej att fel söka :)

Edit: Du bör se över hur du sätter pinnarna på AVR och gå och sov, det brukar hjälpa mot det mästa :)
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

ändrade, ingen silnad :(
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Virr3> det måste betyda att dutycykel:n har en beroende roll av vilken frekvens det blir?

Jag är inte helt säker på vad du frågar, men duty cycle är enbart det rellativa förhållandet mellan hög och låg i PWM signalen. Det har ingenting med frekvens att göra.

Sen så tror jag att du måste bli bättre på att beskriva vad du gör och vad som faktiskt händer. Ett exempel :

> "hela avr:en beter sig helkonstigt..."
Hur då ? Hopper runt på bordet och lägger sig på rygg och spelar död ?
Beskriv helt enkelt exakt vad som händer ! Inga tolkningar eller omskrivningar, det blir bara fel och underlättar knappast för alla andra att förstå vad som faktiskt händer.

Vad sitter på PA2 ?
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Tjenare sodjan, vad jag menade med att den var helt konstig va de värdena som jag skrev i koppling till koden i slutet på inlägget...

lite dåligt beskrivit ja, det kanske jag kan erskänna... ska tänka på de...

ang. duty cyklen så tänkte jag kanske fel...

jag tänker såhär, en hz är en svängning från 0 till 1 under en sekund eller hur 1khz måste då vara 0 till 1 på en ms? om man då mixtrar lite och säjer till att det är längre til när den är etta så får jag det till att det ska vara en lägre frekvens så här på kvällskvisten...

men, nu när jag tänker på de så minskar man ju tiden på 0 så, det är väl som du säjer :/

aja, sånt är livet... ha en bra helg allahopa...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

1 Hz med 50% duty cycle är = 0.50 sek 1 och 0.50 sek 0.

1 Hz med 25% duty cycle är = 0.25 sek 1 och 0.75 sek 0.

1 Hz med 80% duty cycle är = 0.80 sek 1 och 0.20 sek 0.

Frekvens och duty cycle är alltså två *olika* egenskapar hos en fyrkantsvåg.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

okej, tack sodjan...

jag tror att jag har listat ut vad som är fel på koden nu..

det är att allt som är i while-satsen får en frekvens av 38khz...

men, jag vet inte hur jag ska lösa de:( ändrat lite i koden nu så att det stämmer bättre... såg i morse att koden va helt galen, men förhoppningsvis är den bättre nu :)

Kod: Markera allt

 #include <avr/io.h>
 #include <avr/delay.h>


void ask(uint16_t antal_perioder);

int main(void)
{      
	DDRC =    _BV(PC2) | _BV(PC1) | _BV(PC2) ;
        
        PORTC |=  _BV(PC2);
	PORTC |=  _BV(PC0);
	PORTC |=  _BV(PC1);
	

	while(1)
	{
	ask(65000);
	if (PINA & _BV(PC2)) 
		{
			PORTC |=  _BV(PC2);
		} 
	}
}


void ask(uint16_t antal_perioder)
{
   for(int i=0; i<antal_perioder; i++)
   {
      PORTC |= (7<<PC0);
      _delay_us(13);
      PORTC &= ~(7<<PC0);
      _delay_us(13);
   }
} 
när jag ändå skriver ett inlägg kan jag lika gjärna fråga: om jag ska ha en ifsats som här, hur skirver jag för att då för att få följande resultat?

om pa1 är lika med pc3 gör detta.. och hur gör jag för : om pa1 är hög gör detta?
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Några classic fel:
-Pinnarna PC2 till PC5 fungerar inte, Det beror på att den är Jtag interfacet sitter där och är på default (fuse bit)
-Delayen är för lång eller för kort mot du har angivit,
1 CPU frekvensen måste anges för kompilatorn (jag har förmej att gcc klagar).
2 Den interna RC kretsen är på som default men du hade tänkt använda extern kristall.
- Pull-up motståndet för ir-motagaren saknas vilket gör att signalen förblir låg...

Sedan en multimeter med frevens mätning är ett bra verktyg för att se om frekvensen stämmer, för ir motagare har hyfsat brant bandpass filter.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

mja..
jag vet inte riktigt..

när jag tarbort den där loopen verkar allt vara normalt, spänningarna kommer upp i 5v istället för 2,5 som de va å lura vid förut med loopen...

jag vet inte hur jag ska göra för att få det att funka!

åh, jag vill få konakt med while loopen utan att allt annat ska va där inne...

eller, vet inte riktigt hur man ska förklara...

just nu är allt innom while loopen 38khz känns det som... och de vill jag vill jag inte;)

jag har tänkt på de hela dan, men kommer inte på något bra
Skriv svar