ATMega32 och massor med interuppt

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

ATMega32 och massor med interuppt

Inlägg av Virr3 »

Tjenare...

jag undrar lite över interuppt på en atmega32:a

det är nämligen så att jag använde just nu bara ett interuppt(eller hur man säjer) och det är genom en av pinsen på avr:en

jag blir tvungen att använda yttligare två interuppt snart,
då de bara finns två "interuppt-pinns" så förmodar jag att man kan simulera ett interuppt med mjukvara?eller går inte de? hur löser man det då?

aja, men iallafall, kommer de att störas ifall man kör fler än en?
så att den ena tror att det är den andras interuppt den ska köra på osv... eller hur man ska förklara...:humm:

det är lite svårt att förklara då jag inte är så jätte insatt i den, men jag håller på och försöker att lära mig...

hoppas att det är okej förklarat annars säj vad det är jag glömt att säja så berättar jag... :)
mrhedin
Inlägg: 114
Blev medlem: 3 maj 2005, 19:46:24
Ort: Trollhättan/Kiruna
Kontakt:

Inlägg av mrhedin »

Tjena Virr3.

Om du skall köra med det du kallar för mjukvaruinterrupt, så måste det finnas ett sådant i processorn.

T.ex. kan man säga att man vill ha ett interrupt varje gång en ADomvandling är färdig, eller att timern har räknat upp till max. Då flaggar processorn för detta och har du ställt in att du tillåter interrupt och tittar just efter dessa flaggor så kommer en speciell rutin att köras då.

Interrupten kommer inte att förväxlas med varandra i och med att du(i C) skriver en funktion som får ha namnet SIGNAL(SIG_ADC) { } exempelvis för AD-omvandlarens. På det här viset skiljer du interrupten åt vad som skall hända för respektive interrupt.
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

>> Virr3

Det är inte alls dumt tänk. Men det är inte helt rätt.
En fördel med AVR jämfört med de PIC jag kört är att AVR har en ISR-vektor (interrupt service routine) för varje typ av interrupt. PIC har bara en, och man måste därför i ISR kolla vad det är som egentligen hänt.

Hursomhelst. Det finns två olika externa interrupt. Du kan få ett via INT-pinnen och ett annat när en pinne ändras på portB.

Du kan ha många olika interruptkällor igång samtidigt. AVRen kommer köra en speciell (av dig definierad) ISR för varje typ av interrupt.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Okej, tack $tiff och mrhedin...

för att ta denna tråden ett steg frammåt så...

vad jag ska med interuppten till är ir faktiskt...

jag har kollat lite på avrfeaks efter lite om timer interuppt, men inte funnit något superbra, det har vart något som vart riktigt bra men då har kodexemplena vart i asm... det jag skulle vilja ha är i c...

aja, ska kolla lite i databladet för atmega32:an och lite i manualen för libc...

om ni har några "tips" eller kodexempel liggandes skulle det vara snällt ifall ni postade dom här :)
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Varje exempel är nästan unikt. Det hjälper ju att läsa på lite först, innan man börjar leka med timern.

Genrellt ska du först bestämma vilken timer du vill använda, det finns oftast timer1 med 16 bitars upplösning och timer0 och timer2 med 8 bitars upplösning.
De olika timerna har lite olika finesser att välja bland.
Välj prescaler, d.v.s. hur fort timern ska räkna jämfört med systemklockan (om man nu har den som referens).
Aktivera interrupten.
Skriv en ISR som tar hand om interrupten.
Kompilera, exekvera :D

Så här enkelt kan det se ut när man väl vet vad registerna gör:

Kod: Markera allt

	// Timer0 setup
	TCCR0A = 0;				// Normal mode, nothing else
	TCCR0B = 1;				// Tiner on, no prescaling
	TIMSK0 = (1<<TOIE0);	// Overflow interrupt enabled
	
Här aktiveras timer0 för att räkna med prescaler 1, d.v.s. fort! Det är till en mjukvaru-PWM i Tiny13. Lägg märke till att registerna ser lite annorlunda ut på olika µC.
mrhedin
Inlägg: 114
Blev medlem: 3 maj 2005, 19:46:24
Ort: Trollhättan/Kiruna
Kontakt:

Inlägg av mrhedin »

>Virr3

Kan ge lite tips för hur du skall få ett timer-interrupt då.

Först och främst för att processorn skall reagera på något interrupt överhuvudtaget, sätter du bit 7 i SREG till en 1:a. (sid8)

Som exempel nu kan vi ju använda timer1.
För att processorn skall veta att den skall interruptas när timer1 har fått overflow, alltså kommit upp till 65535 så sätter du bit 2 i TIMSK. (sid 110)

Då kommer processorn att avbrytas och köra respektive ISR-rutin som du skriver i koden. Typ SIGNAL(SIG_TMR1) { } (är inte säker på det innanför paranterserna där, tror det är fel)


Det här är ju bara som exempel då. Du kan ju generera massor av olika interrupts med timer1. Jag vet inte riktigt vad det var för ett timerinterrupt du sökte, men hursomhelst. Det kanske hjälpte lite iaf...


EDIT: jag var sist ut, blir lite kaka på kaka. Men låter det stå kvar iaf =)
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

kollade igenom ett lib och fick fram att dessa vektorer va de såkallade "interuppt vectors"

Kod: Markera allt


#define SIG_INTERRUPT0          _VECTOR(1)
#define SIG_INTERRUPT1          _VECTOR(2)
#define SIG_INTERRUPT2          _VECTOR(3)
#define SIG_OUTPUT_COMPARE2     _VECTOR(4)
#define SIG_OVERFLOW2           _VECTOR(5)
#define SIG_INPUT_CAPTURE1      _VECTOR(6)
#define SIG_OUTPUT_COMPARE1A    _VECTOR(7)
#define SIG_OUTPUT_COMPARE1B    _VECTOR(8)
#define SIG_OVERFLOW1           _VECTOR(9)
#define SIG_OUTPUT_COMPARE0     _VECTOR(10)
#define SIG_OVERFLOW0           _VECTOR(11)
#define SIG_SPI                 _VECTOR(12)
#define SIG_USART_RECV          _VECTOR(13)
#define SIG_UART_RECV           _VECTOR(13) /* For backwards compatibility */
#define SIG_USART_DATA          _VECTOR(14)
#define SIG_UART_DATA           _VECTOR(14) /* For backwards compatibility */
#define SIG_USART_TRANS         _VECTOR(15)
#define SIG_UART_TRANS          _VECTOR(15) /* For backwards compatibility */
#define SIG_ADC                 _VECTOR(16)
#define SIG_EEPROM_READY        _VECTOR(17)
#define SIG_COMPARATOR          _VECTOR(18)
#define SIG_2WIRE_SERIAL        _VECTOR(19)
#define SIG_SPM_READY           _VECTOR(20)
antar att det är en av de här som ska stå i parantesen?
men, vilken? #define SIG_OVERFLOW0 eller?

Edit: nejdå, ingen fara med kaka på kaka:) tvärt om faktiskt:) två kakor är bättre än en:D

ne, men stort tack till er båda:)

du, mrhedin du skrev
ör att processorn skall veta att den skall interruptas när timer1 har fått overflow, alltså kommit upp till 65535 så sätter du bit 2 i TIMSK. (sid 110)
det fattar ja som att när timern räknat upp till 65535 så kommer ett interuppt?

eller har jag fattat fel? hur gör jag då om jag vill ha ett interuppt tidigare?
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Grejen är den att du laddar räknaren med ett initialvärde. Om du vill att interruptet ska komma efter 1000 clockcykler (utan prescaler) så laddar du räknaren med 64535 innan du startar den. På detta vis kommer du kunna variera hur länge du vill att timern ska gå innan interruptet inträffar.

PS. interruptet genereras nog inte vid 65535, utan när den slår över till noll igen. Men detta har mindre betydelse vid programmering i C antar jag. DS
mrhedin
Inlägg: 114
Blev medlem: 3 maj 2005, 19:46:24
Ort: Trollhättan/Kiruna
Kontakt:

Inlägg av mrhedin »

>Virre

Det är precis som karlstedt säger där att om du vill få ett intrerrupt tidigare så får du ladda timern med ett värde innan du drar igång den. Kika lite på hur timer1 funkar och posta en fråga igen om du fastnar

Men du har fattat det helt rätt att det kommer ett interrupt när timern kommer upp till max och slår om.


Om du överst i din kod inkluderar filerna interrupt.h och signal.h får du med alla defines där och lite till på ett smidigare sätt.

Det är alltså SIGNAL(SIG_OVERFLOW1) som skall stå innanför parantesen i och med att det är timer1:s overflow.


Lite tips med timern där. Timern användes tillsammans med en prescaler. Prescalern har 3 bitar i ett kontrollregister som du kan ställa in för att dividera din internklocka med ett tal för att få den klockfrekvens som används för att räkna timern framåt. Ett steg för varje klocktick.

När du pillar på prescalerbitarna går timern automatiskt igång. Exempel:
setbit(TCCR1B, CS10); // Starta Timer1, Prescaler 1024. CLK=3906Hz
clearbit(TCCR1B, CS11);// Starta Timer1, Prescaler 1024. CLK=3906Hz
setbit(TCCR1B, CS12); // Starta Timer1, Prescaler 1024. CLK=3906Hz

Om du använder 4MHz interklocka kommer timern med denna prescaler 1024 stega framåt med 3906 steg i sekunden.

För att få en sekund innan ett interrupt laddar du timerns register med:
TCNT1=61630; // Laddar med värde för att få exakt en sekund.


Hoppas det här hjälper dig ytterligare på traven...
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

tänkte att jag skulle försöka att få ihop den där koden ida:)
så, kod kommer upp snart:)

men, jag förstår inte de där med prescalern... inte alls faktiskt...

Edit: efter att jag tänkt lite så undrar jag om hur jag skickar informationen...

om jag gör så att irdioden blinkar i 38khz för att motagaren överhuvetaget ska fatta att de ä info som kommer, sen så avbryter ja de å skickar informationen?

eller? har jag fattat helt fel? för det går väl inte skicka infon i 38khz? eller, för ifall det kommer två bitar som är låga så blir det ju en annan frekvens väl?
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

I den den enklaste formen av modulering så _är_ närvaron eller frånvaron av bärvåg din information. Typ att när du sänder data som är 1 så sänder du bärvåg med 38kHz och när du sänder 0 så är det tyst och ingen bärvåg sänds. Eller tvärtom beroende protokoll.

Denna moduleringsteknik kallas ASK, Amplitude Shift Keying, och är en av dom enklaste man kan göra. Egentligen blir det ett specialfall av Amplitudmodulering där moduleringssignalen bara kan anta två tillstånd istället för ett analogt värde.

Sedan går det att lägga till extra kodning ovanpå detta i form olika långa "pulser" av bärvåg eller inte bärvåg. Allt är beroende på vad det är för IR-protokoll du skall köra med.
Senast redigerad av vfr 23 oktober 2005, 19:09:41, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Vad är det för IR mottagare ?
Vad säger databladet ?
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

jag vet inte riktigt vad databladet säjer, jag hittar inget om de i databladet:(


det är den "vanliga" everlight på elfa... (http://www.elfa.se/elfa-bin/dyndok.pl?dok=2021467.htm)
http://www.elfa.se/pdf/75/07530389.pdf
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Jo den som du har länkat till är bara själva mottagaren. Den demodulerar 38kHZ-signalen så att du får ut själva datasignalen. Vad du får ut från mottagaren är alltså beroende på vad du sänder ut från fjärrkontrollen i andra änden. Det är det protokollet du måste ha tag i och avkoda i processorn.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> jag vet inte riktigt vad databladet säjer, jag hittar inget om de i databladet:(

Här är jag osäker på vad "de" syftar på.

> det är den "vanliga" everlight på elfa... (http://www.elfa.se/elfa-bin/dyndok.pl?dok=2021467.htm)
> http://www.elfa.se/pdf/75/07530389.pdf

Jamen ! Där har vi ju databladet !
Pulserna skall alltså vara mellan 400 och 800 us (Th och Tl).
Sen får du själv bestämma (d.v.s förutsatt att du själv har full kontroll över sändare och mottagare) hur lång en "etta" och en "nolla" skall vara. Dock bör de alltså båda ligga inom intervallet ovan för att uppfylla kraven från puls-detektorn i IR mottagaren.

Dessa mottagare fungerar normalt inte där man helt enkelt switchar bärvågen av/på för 1/0, eftersom puls-detektorn vill ha en kontinuerlig ström av pulser och en ström av ettor (eller nollor) skulle förhindra detta).

Pulsernas längd kan dock variera (inom intervallet i databladet) så att man kan koda ettor och nollor (och eventuellt start och stop bitar beroende på hur du kör). Man kan, om man vill "finlira", justera längden på både pulsen *med* bärvåg och pulsen *utan* bärvåg, för att öka hastigheten (bitar/sek), men det kanske blir onödigt komplext.

Om man inte håller pulserna inom spec, så får man begränsningar i räckvid p.g.a av den automatiska förstärkningsjusteringen och integreringssteget inte fungerar optimalt.
Skriv svar